nv50/ir: optimize shl + and
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 13 Jan 2017 05:41:11 +0000 (00:41 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Tue, 17 Jan 2017 02:13:09 +0000 (21:13 -0500)
Address loading can often end up as shl + shr + shl combinations. The
latter two are equal shifts, which get converted into an and mask.
However if the previous shl is more than the mask is trying to remove
(in terms of low bits), we can just remove the and entirely. This
reduces some large shaders by as many as 3% of instructions (out of 2K).

total instructions in shared programs : 6495509 -> 6491076 (-0.07%)
total gprs used in shared programs    : 954621 -> 954623 (0.00%)

                local        gpr       inst      bytes
    helped           0           0        1014        1014
      hurt           0           2           0           0

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp

index 28b59857e63de08bb4fb6a1afffca7d416fa710b..04b6af2471b5486daacfda2de8829252065b4588 100644 (file)
@@ -1260,6 +1260,17 @@ ConstantFolding::opnd(Instruction *i, ImmediateValue &imm0, int s)
          i->op = OP_EXTBF;
          i->setSrc(0, src->getSrc(0));
          i->setSrc(1, new_ImmediateValue(prog, ext));
+      } else if (src->op == OP_SHL &&
+                 src->src(1).getImmediate(imm1) &&
+                 i->src(t).mod == Modifier(0) &&
+                 util_is_power_of_two(~imm0.reg.data.u32 + 1) &&
+                 util_last_bit(~imm0.reg.data.u32) <= imm1.reg.data.u32) {
+         i->op = OP_MOV;
+         i->setSrc(s, NULL);
+         if (t) {
+            i->setSrc(0, i->getSrc(t));
+            i->setSrc(t, NULL);
+         }
       }
    }
       break;