[Mesa-dev] [PATCH 1/2] i965/vec4: Add a pass to reduce swizzles.

Matt Turner mattst88 at gmail.com
Mon Aug 18 12:24:14 PDT 2014


total instructions in shared programs: 4344280 -> 4288033 (-1.29%)
instructions in affected programs:     397468 -> 341221 (-14.15%)
---
Suggestions for a better name are welcome.

 src/mesa/drivers/dri/i965/brw_vec4.cpp | 98 ++++++++++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_vec4.h   |  1 +
 2 files changed, 99 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 5d4a92c..c1363ca 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -311,6 +311,103 @@ src_reg::equals(const src_reg &r) const
 		  sizeof(fixed_hw_reg)) == 0);
 }
 
+/* Replaces unused channels of a swizzle with channels that are used.
+ *
+ * For instance, this pass transforms
+ *
+ *    mov vgrf4.yz, vgrf5.wxzy
+ *
+ * into
+ *
+ *    mov vgrf4.yz, vgrf5.xxzx
+ *
+ * This eliminates false uses of some channels, letting dead code elimination
+ * remove the instructions that wrote them.
+ */
+bool
+vec4_visitor::opt_reduce_swizzle()
+{
+   bool progress = false;
+
+   foreach_in_list_safe(vec4_instruction, inst, &instructions) {
+      if (inst->dst.file == BAD_FILE || inst->dst.file == HW_REG)
+         continue;
+
+      int swizzle[4];
+
+      /* Determine which channels of the sources are read. */
+      switch (inst->opcode) {
+      case BRW_OPCODE_DP4:
+      case BRW_OPCODE_DPH: /* FINISHME: DPH reads only three channels of src0,
+                            *           but all four of src1.
+                            */
+         swizzle[0] = 0;
+         swizzle[1] = 1;
+         swizzle[2] = 2;
+         swizzle[3] = 3;
+         break;
+      case BRW_OPCODE_DP3:
+         swizzle[0] = 0;
+         swizzle[1] = 1;
+         swizzle[2] = 2;
+         swizzle[3] = -1;
+         break;
+      case BRW_OPCODE_DP2:
+         swizzle[0] = 0;
+         swizzle[1] = 1;
+         swizzle[2] = -1;
+         swizzle[3] = -1;
+         break;
+      default:
+         swizzle[0] = inst->dst.writemask & WRITEMASK_X ? 0 : -1;
+         swizzle[1] = inst->dst.writemask & WRITEMASK_Y ? 1 : -1;
+         swizzle[2] = inst->dst.writemask & WRITEMASK_Z ? 2 : -1;
+         swizzle[3] = inst->dst.writemask & WRITEMASK_W ? 3 : -1;
+         break;
+      }
+
+      /* Resolve unread channels (-1) by assigning them the swizzle of the
+       * first channel that is used.
+       */
+      int chosen = 0;
+      for (int i = 0; i < 4; i++) {
+         if (swizzle[i] != -1) {
+            chosen = swizzle[i];
+            break;
+         }
+      }
+      for (int i = 0; i < 4; i++) {
+         if (swizzle[i] == -1) {
+            swizzle[i] = chosen;
+         }
+      }
+
+      /* Update sources' swizzles. */
+      for (int i = 0; i < 3; i++) {
+         if (inst->src[i].file != GRF &&
+             inst->src[i].file != ATTR &&
+             inst->src[i].file != UNIFORM)
+            continue;
+
+         int swiz[4];
+         for (int j = 0; j < 4; j++) {
+            swiz[j] = BRW_GET_SWZ(inst->src[i].swizzle, swizzle[j]);
+         }
+
+         unsigned new_swizzle = BRW_SWIZZLE4(swiz[0], swiz[1], swiz[2], swiz[3]);
+         if (inst->src[i].swizzle != new_swizzle) {
+            inst->src[i].swizzle = new_swizzle;
+            progress = true;
+         }
+      }
+   }
+
+   if (progress)
+      invalidate_live_intervals();
+
+   return progress;
+}
+
 static bool
 try_eliminate_instruction(vec4_instruction *inst, int new_writemask,
                           const struct brw_context *brw)
@@ -1701,6 +1798,7 @@ vec4_visitor::run()
       iteration++;
       int pass_num = 0;
 
+      OPT(opt_reduce_swizzle);
       OPT(dead_code_eliminate);
       OPT(dead_control_flow_eliminate, this);
       OPT(opt_copy_propagation);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index c59d24f..f009dd2 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -380,6 +380,7 @@ public:
    void calculate_live_intervals();
    void invalidate_live_intervals();
    void split_virtual_grfs();
+   bool opt_reduce_swizzle();
    bool dead_code_eliminate();
    bool virtual_grf_interferes(int a, int b);
    bool opt_copy_propagation();
-- 
1.8.5.5



More information about the mesa-dev mailing list