Mesa (master): i965/vec4: Eliminate dead writes to the flag register.

Matt Turner mattst88 at kemper.freedesktop.org
Mon Mar 24 18:09:09 UTC 2014


Module: Mesa
Branch: master
Commit: 764e25d79dad3096274ab2df04f5aa3ffb232119
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=764e25d79dad3096274ab2df04f5aa3ffb232119

Author: Matt Turner <mattst88 at gmail.com>
Date:   Tue Mar 18 19:19:02 2014 -0700

i965/vec4: Eliminate dead writes to the flag register.

For each write, search previous instructions for unread writes to the
flag register and remove them. Note that this will not eliminate the
last unread write.

total instructions in shared programs: 788074 -> 788004 (-0.01%)
instructions in affected programs:     4930 -> 4860 (-1.42%)

Reviewed-by: Eric Anholt <eric at anholt.net>

---

 src/mesa/drivers/dri/i965/brw_vec4.cpp |   66 +++++++++++++++++++++++---------
 1 file changed, 48 insertions(+), 18 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index e9219a9..4ae6020 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -381,35 +381,53 @@ vec4_visitor::dead_code_eliminate()
 
       seen_control_flow = inst->is_control_flow() || seen_control_flow;
 
-      if (inst->dst.file != GRF || inst->has_side_effects())
+      if (inst->has_side_effects())
          continue;
 
-      int write_mask = inst->dst.writemask;
+      bool inst_writes_flag = false;
+      if (inst->dst.file != GRF) {
+         if (inst->dst.is_null() && inst->writes_flag()) {
+            inst_writes_flag = true;
+         } else {
+            continue;
+         }
+      }
 
-      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 (inst->dst.file == GRF) {
+         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);
+               }
             }
          }
-      }
 
-      progress = try_eliminate_instruction(inst, write_mask) || progress;
+         progress = try_eliminate_instruction(inst, write_mask) || progress;
+      }
 
       if (seen_control_flow || inst->predicate || inst->prev == NULL)
          continue;
 
-      int dead_channels = inst->dst.writemask;
+      int dead_channels;
+      if (inst_writes_flag) {
+/* Arbitrarily chosen, other than not being an xyzw writemask. */
+#define FLAG_WRITEMASK (1 << 5)
+         dead_channels = inst->reads_flag() ? 0 : FLAG_WRITEMASK;
+      } else {
+         dead_channels = inst->dst.writemask;
 
-      for (int i = 0; i < 3; i++) {
-         if (inst->src[i].file != GRF ||
-             inst->src[i].reg != inst->dst.reg)
-               continue;
+         for (int i = 0; i < 3; i++) {
+            if (inst->src[i].file != GRF ||
+                inst->src[i].reg != inst->dst.reg)
+                  continue;
 
-         for (int j = 0; j < 4; j++) {
-            int swiz = BRW_GET_SWZ(inst->src[i].swizzle, j);
-            dead_channels &= ~(1 << swiz);
+            for (int j = 0; j < 4; j++) {
+               int swiz = BRW_GET_SWZ(inst->src[i].swizzle, j);
+               dead_channels &= ~(1 << swiz);
+            }
          }
       }
 
@@ -418,9 +436,21 @@ vec4_visitor::dead_code_eliminate()
            node = prev, prev = prev->prev) {
          vec4_instruction *scan_inst = (vec4_instruction  *)node;
 
-         if (scan_inst->dst.file != GRF || scan_inst->has_side_effects())
+         if (scan_inst->has_side_effects())
             continue;
 
+         if (inst_writes_flag) {
+            if (scan_inst->dst.is_null() && scan_inst->writes_flag()) {
+               scan_inst->remove();
+               progress = true;
+            } else if (scan_inst->reads_flag()) {
+               dead_channels = 0;
+            }
+            continue;
+         } else if (scan_inst->dst.file != GRF) {
+            continue;
+         }
+
          if (inst->dst.reg == scan_inst->dst.reg) {
             int new_writemask = scan_inst->dst.writemask & ~dead_channels;
 




More information about the mesa-commit mailing list