nv50/ir: optimize neg(and(set, 1)) to set
authorKarol Herbst <nouveau@karolherbst.de>
Sat, 23 Jan 2016 23:16:05 +0000 (00:16 +0100)
committerIlia Mirkin <imirkin@alum.mit.edu>
Tue, 16 Feb 2016 23:20:10 +0000 (18:20 -0500)
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 <nouveau@karolherbst.de>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp

index 05b8db4a3d8dcc23e1e10f70af79b83025e33280..35b1fa7795e230eda6aa38279bf810fde7c3e205 100644 (file)
@@ -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;
       }