[Mesa-dev] [PATCHv3 1/3] i965/fs: improve liveness analysis for partial writes

Chia-I Wu olvaffe at gmail.com
Wed Oct 16 08:58:09 CEST 2013


From: Chia-I Wu <olv at lunarg.com>

When two partial writes write the first and second halves of a variable
respectively before the variable is used, the variable can be added to the def
bitset.

v2: no change
v3: no longer rely on hints from by the visitor

Signed-off-by: Chia-I Wu <olv at lunarg.com>
---
 .../drivers/dri/i965/brw_fs_live_variables.cpp     | 26 +++++++++++++++++-----
 src/mesa/drivers/dri/i965/brw_fs_live_variables.h  |  5 +++--
 2 files changed, 24 insertions(+), 7 deletions(-)

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 b3026c2..cceff42 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
@@ -97,7 +97,8 @@ fs_live_variables::setup_one_read(bblock_t *block, fs_inst *inst,
     * channel) without having completely defined that variable within the
     * block.
     */
-   if (!BITSET_TEST(bd[block->block_num].def, var))
+   if (!BITSET_TEST(bd[block->block_num].def, var) &&
+       !BITSET_TEST(bd[block->block_num].def_sechalf, var))
       BITSET_SET(bd[block->block_num].use, var);
 }
 
@@ -113,9 +114,22 @@ fs_live_variables::setup_one_write(bblock_t *block, fs_inst *inst,
    /* The def[] bitset marks when an initialization in a block completely
     * screens off previous updates of that variable (VGRF channel).
     */
-   if (inst->dst.file == GRF && !inst->is_partial_write()) {
-      if (!BITSET_TEST(bd[block->block_num].use, var))
-         BITSET_SET(bd[block->block_num].def, var);
+   if (inst->dst.file == GRF) {
+      /* We do not want to call inst->is_partial_write() here as we track the
+       * two halves separately.
+       */
+      bool predicated = (inst->predicate && inst->opcode != BRW_OPCODE_SEL);
+
+      if (!predicated && !BITSET_TEST(bd[block->block_num].use, var)) {
+         if (inst->force_sechalf) {
+            BITSET_SET(bd[block->block_num].def_sechalf, var);
+         } else {
+            BITSET_SET(bd[block->block_num].def, var);
+
+            if (!inst->force_uncompressed)
+               BITSET_SET(bd[block->block_num].def_sechalf, var);
+         }
+      }
    }
 }
 
@@ -188,8 +202,9 @@ fs_live_variables::compute_live_variables()
       for (int b = 0; b < cfg->num_blocks; b++) {
 	 /* Update livein */
 	 for (int i = 0; i < bitset_words; i++) {
+            BITSET_WORD def = (bd[b].def[i] & bd[b].def_sechalf[i]);
             BITSET_WORD new_livein = (bd[b].use[i] |
-                                      (bd[b].liveout[i] & ~bd[b].def[i]));
+                                      (bd[b].liveout[i] & ~def));
 	    if (new_livein & ~bd[b].livein[i]) {
                bd[b].livein[i] |= new_livein;
                cont = true;
@@ -275,6 +290,7 @@ fs_live_variables::fs_live_variables(fs_visitor *v, cfg_t *cfg)
    bitset_words = BITSET_WORDS(num_vars);
    for (int i = 0; i < cfg->num_blocks; i++) {
       bd[i].def = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
+      bd[i].def_sechalf = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
       bd[i].use = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
       bd[i].livein = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
       bd[i].liveout = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.h b/src/mesa/drivers/dri/i965/brw_fs_live_variables.h
index 82575d8..d7f0bba 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.h
+++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.h
@@ -37,9 +37,10 @@ struct block_data {
     * Which variables are defined before being used in the block.
     *
     * Note that for our purposes, "defined" means unconditionally, completely
-    * defined.
+    * defined.  As an instruction may write to only the first or the second
+    * half of a variable, we need two bitsets.
     */
-   BITSET_WORD *def;
+   BITSET_WORD *def, *def_sechalf;
 
    /**
     * Which variables are used before being defined in the block.
-- 
1.8.3.1



More information about the mesa-dev mailing list