i965/vec4: Let dead code eliminate trim dead channels.
authorMatt Turner <mattst88@gmail.com>
Tue, 11 Mar 2014 20:14:08 +0000 (13:14 -0700)
committerMatt Turner <mattst88@gmail.com>
Mon, 24 Mar 2014 18:06:26 +0000 (11:06 -0700)
That is, modify

   mad dst, a, b, c

to be

   mad dst.xyz, a, b, c

if dst.w is never read.

total instructions in shared programs: 811869 -> 805582 (-0.77%)
instructions in affected programs:     168287 -> 162000 (-3.74%)

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_vec4.cpp

index 135cc42..673086d 100644 (file)
@@ -343,8 +343,20 @@ vec4_visitor::dead_code_eliminate()
       if (inst->dst.file != GRF || inst->has_side_effects())
          continue;
 
-      assert(this->virtual_grf_end[inst->dst.reg] >= pc);
-      if (this->virtual_grf_end[inst->dst.reg] == pc) {
+      int write_mask = inst->dst.writemask;
+
+      for (int c = 0; c < 4; c++) {
+         if (write_mask & (1 << c)) {
+            assert(this->virtual_grf_end[inst->dst.reg * 4 + c] >= pc);
+            if (this->virtual_grf_end[inst->dst.reg * 4 + c] == pc) {
+               write_mask &= ~(1 << c);
+            }
+         }
+      }
+
+      if (write_mask == 0) {
+         progress = true;
+
          /* Don't dead code eliminate instructions that write to the
           * accumulator as a side-effect. Instead just set the destination
           * to the null register to free it.
@@ -363,7 +375,18 @@ vec4_visitor::dead_code_eliminate()
             }
             break;
          }
-         progress = true;
+      } else if (inst->dst.writemask != write_mask) {
+         switch (inst->opcode) {
+         case SHADER_OPCODE_TXF_CMS:
+         case SHADER_OPCODE_GEN4_SCRATCH_READ:
+         case VS_OPCODE_PULL_CONSTANT_LOAD:
+         case VS_OPCODE_PULL_CONSTANT_LOAD_GEN7:
+            break;
+         default:
+            progress = true;
+            inst->dst.writemask = write_mask;
+            break;
+         }
       }
    }