nv50/ir: constant fold OP_SPLIT
authorTobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
Fri, 30 Sep 2016 21:50:15 +0000 (23:50 +0200)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sat, 15 Oct 2016 03:23:57 +0000 (23:23 -0400)
Split the source immediate value into new values and move them into the
original defs set by the split. Since we can only have up to 64-bit
immediates, this is largely beneficial for F64 (and, in the future, U64)
operations.

Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
[imirkin: always use U32, set newi for foldCount tracking]
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp

index 737bda3ee3398a171c571f2a782ae30f8d35f3f6..0fb1a7803bd08a4f933819eac943e95b95b94e7e 100644 (file)
@@ -932,6 +932,24 @@ ConstantFolding::opnd(Instruction *i, ImmediateValue &imm0, int s)
    Instruction *newi = i;
 
    switch (i->op) {
+   case OP_SPLIT: {
+      bld.setPosition(i, false);
+
+      uint8_t size = i->getDef(0)->reg.size;
+      uint32_t mask = (1ULL << size) - 1;
+      assert(size <= 32);
+
+      uint64_t val = imm0.reg.data.u64;
+      for (int8_t d = 0; i->defExists(d); ++d) {
+         Value *def = i->getDef(d);
+         assert(def->reg.size == size);
+
+         newi = bld.mkMov(def, bld.mkImm((uint32_t)(val & mask)), TYPE_U32);
+         val >>= size;
+      }
+      delete_Instruction(prog, i);
+      break;
+   }
    case OP_MUL:
       if (i->dType == TYPE_F32)
          tryCollapseChainedMULs(i, s, imm0);