nv50/ir: optimize multiplication by 16-bit immediates into two xmads
authorRhys Perry <pendingchaos02@gmail.com>
Sat, 18 Aug 2018 14:06:50 +0000 (15:06 +0100)
committerRhys Perry <pendingchaos02@gmail.com>
Mon, 27 Aug 2018 12:57:11 +0000 (13:57 +0100)
Rather than the usual three that would be created.

total instructions in shared programs : 5796385 -> 5786560 (-0.17%)
total gprs used in shared programs    : 670103 -> 669968 (-0.02%)
total shared used in shared programs  : 548832 -> 548832 (0.00%)
total local used in shared programs   : 21164 -> 21068 (-0.45%)

                local     shared        gpr       inst      bytes
    helped           1           0          64        1040        1040
      hurt           0           0          27           0           0

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Karol Herbst <kherbst@redhat.com>
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp

index 1ab743705a7ce6b15b58c5fed8197f35cbd2aed3..ecb4bae2a83651af98db0912bb48098362c4315c 100644 (file)
@@ -997,6 +997,16 @@ ConstantFolding::createMul(DataType ty, Value *def, Value *a, int64_t b, Value *
       return true;
    }
 
+   if (typeSizeof(ty) == 4 && b >= 0 && b <= 0xffff &&
+       target->isOpSupported(OP_XMAD, TYPE_U32)) {
+      Value *tmp = bld.mkOp3v(OP_XMAD, TYPE_U32, bld.getSSA(),
+                              a, bld.mkImm((uint32_t)b), c ? c : bld.mkImm(0));
+      bld.mkOp3(OP_XMAD, TYPE_U32, def, a, bld.mkImm((uint32_t)b), tmp)->subOp =
+         NV50_IR_SUBOP_XMAD_PSL | NV50_IR_SUBOP_XMAD_H1(0);
+
+      return true;
+   }
+
    return false;
 }