diff options
author | Karol Herbst <[email protected]> | 2016-01-24 00:16:05 +0100 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2016-02-16 18:20:10 -0500 |
commit | 068e9848ba5937673d66c42a4b44067fd78becaf (patch) | |
tree | 23e03894acd9dab58ff32da31ad701d1d72104cd | |
parent | ca23c8081f1f9f709df7a63b9e6de379c0b8df44 (diff) |
nv50/ir: optimize neg(and(set, 1)) to set
helps shaders in saints row IV, bioshock infinite and shadow warrior
total instructions in shared programs : 1914931 -> 1903900 (-0.58%)
total gprs used in shared programs : 247920 -> 247785 (-0.05%)
total local used in shared programs : 5673 -> 5673 (0.00%)
total bytes used in shared programs : 17558272 -> 17457320 (-0.57%)
local gpr inst bytes
helped 0 137 719 719
hurt 0 12 0 0
v2: remove this opt for OP_SLCT and check against float for OP_SET
v3: simplified the code
Signed-off-by: Karol Herbst <[email protected]>
Reviewed-by: Ilia Mirkin <[email protected]>
-rw-r--r-- | src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp index 05b8db4a3d8..35b1fa7795e 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp @@ -1539,6 +1539,7 @@ private: void handleCVT_CVT(Instruction *); void handleCVT_EXTBF(Instruction *); void handleSUCLAMP(Instruction *); + void handleNEG(Instruction *); BuildUtil bld; }; @@ -2011,6 +2012,34 @@ AlgebraicOpt::handleSUCLAMP(Instruction *insn) insn->setSrc(0, add->getSrc(s)); } +// NEG(AND(SET, 1)) -> SET +void +AlgebraicOpt::handleNEG(Instruction *i) { + Instruction *src = i->getSrc(0)->getInsn(); + ImmediateValue imm; + int b; + + if (isFloatType(i->sType) || !src || src->op != OP_AND) + return; + + if (src->src(0).getImmediate(imm)) + b = 1; + else if (src->src(1).getImmediate(imm)) + b = 0; + else + return; + + if (!imm.isInteger(1)) + return; + + Instruction *set = src->getSrc(b)->getInsn(); + if ((set->op == OP_SET || set->op == OP_SET_AND || + set->op == OP_SET_OR || set->op == OP_SET_XOR) && + !isFloatType(set->dType)) { + i->def(0).replace(set->getDef(0), false); + } +} + bool AlgebraicOpt::visit(BasicBlock *bb) { @@ -2048,6 +2077,9 @@ AlgebraicOpt::visit(BasicBlock *bb) case OP_SUCLAMP: handleSUCLAMP(i); break; + case OP_NEG: + handleNEG(i); + break; default: break; } |