[Mesa-dev] [PATCH 02/24] i965/fs: Track flag register liveness with byte granularity.

Francisco Jerez currojerez at riseup.net
Fri May 27 03:46:07 UTC 2016


This is required for correctness in presence of multiple 8-wide flag
writes (e.g. 8-wide instructions with a conditional mod set) which
update a different portion of the same 16-bit flag subregister.  Right
now we keep track of flag dataflow with 16-bit granularity and
consider flag writes to have killed any previous definition of the
same subregister even if the write was less than 16 channels wide,
which can cause live flag register updates to be dead code-eliminated
incorrectly.

Additionally this makes sure that we handle 32-wide flag writes and
reads which may span multiple flag subregisters so the current
approach of just setting/testing a single bit from the live set
wouldn't have worked.
---
 .../dri/i965/brw_fs_dead_code_eliminate.cpp        | 11 ++++-------
 .../drivers/dri/i965/brw_fs_live_variables.cpp     | 23 +++++-----------------
 2 files changed, 9 insertions(+), 25 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp b/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp
index bd57e09..a1d07ff 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp
@@ -77,7 +77,7 @@ fs_visitor::dead_code_eliminate()
          }
 
          if (inst->dst.is_null() && inst->writes_flag()) {
-            if (!BITSET_TEST(flag_live, inst->flag_subreg)) {
+            if (!(flag_live[0] & inst->flags_written())) {
                inst->opcode = BRW_OPCODE_NOP;
                progress = true;
             }
@@ -102,9 +102,8 @@ fs_visitor::dead_code_eliminate()
             }
          }
 
-         if (inst->writes_flag() && !inst->predicate) {
-            BITSET_CLEAR(flag_live, inst->flag_subreg);
-         }
+         if (!inst->predicate && inst->exec_size >= 8)
+            flag_live[0] &= ~inst->flags_written();
 
          if (inst->opcode == BRW_OPCODE_NOP) {
             inst->remove(block);
@@ -121,9 +120,7 @@ fs_visitor::dead_code_eliminate()
             }
          }
 
-         if (inst->reads_flag()) {
-            BITSET_SET(flag_live, inst->flag_subreg);
-         }
+         flag_live[0] |= inst->flags_read(devinfo);
       }
    }
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
index 66b70a9..8bd4229 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
@@ -123,19 +123,8 @@ fs_live_variables::setup_def_use()
                reg.reg_offset++;
             }
 	 }
-         if (inst->reads_flag()) {
-            /* The vertical combination predicates read f0.0 and f0.1. */
-            if (inst->predicate == BRW_PREDICATE_ALIGN1_ANYV ||
-                inst->predicate == BRW_PREDICATE_ALIGN1_ALLV) {
-               assert(inst->flag_subreg == 0);
-               if (!BITSET_TEST(bd->flag_def, 1)) {
-                  BITSET_SET(bd->flag_use, 1);
-               }
-            }
-            if (!BITSET_TEST(bd->flag_def, inst->flag_subreg)) {
-               BITSET_SET(bd->flag_use, inst->flag_subreg);
-            }
-         }
+
+         bd->flag_use[0] |= inst->flags_read(v->devinfo) & ~bd->flag_def[0];
 
          /* Set def[] for this instruction */
          if (inst->dst.file == VGRF) {
@@ -145,11 +134,9 @@ fs_live_variables::setup_def_use()
                reg.reg_offset++;
             }
 	 }
-         if (inst->writes_flag()) {
-            if (!BITSET_TEST(bd->flag_use, inst->flag_subreg)) {
-               BITSET_SET(bd->flag_def, inst->flag_subreg);
-            }
-         }
+
+         if (!inst->predicate && inst->exec_size >= 8)
+            bd->flag_def[0] |= inst->flags_written() & ~bd->flag_use[0];
 
 	 ip++;
       }
-- 
2.7.3



More information about the mesa-dev mailing list