Mesa (master): nir: Switch the indexing of block->live_in/out arrays.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Aug 31 18:45:24 UTC 2020


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

Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jul 23 12:29:02 2020 -0700

nir: Switch the indexing of block->live_in/out arrays.

In nir-to-tgsi, I want to free temps storing SSA values when they go dead,
and NIR liveness has most of the information I need.  Hoever, when I reach
the end of a block, I need to free whatever temps were in liveout which
are dead at that point.  If liveout is indexed by live_index, then I don't
know the maximum live_index for iterating the live_out bitset, and I also
don't have a way to map that index back to the def->index that my temps
are stored under.

We can use the more typical def->index for these bitsets, which resolves
both of those problems.  The only cost is that ssa_undefs don't get merged
into a single bit in the bitfield, but there are generally 1-4 of them in
a shader and we don't track liveness for those anyway so splitting them
apart is fine.

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6408>

---

 src/compiler/nir/nir.c          |  2 ++
 src/compiler/nir/nir.h          |  6 ++++--
 src/compiler/nir/nir_liveness.c | 20 ++++++++++----------
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index 24515f05cb8..2ef15300b65 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -1847,6 +1847,8 @@ nir_index_ssa_defs(nir_function_impl *impl)
 {
    unsigned index = 0;
 
+   impl->valid_metadata &= ~nir_metadata_live_ssa_defs;
+
    nir_foreach_block_unstructured(block, impl) {
       nir_foreach_instr(instr, block)
          nir_foreach_ssa_def(instr, index_ssa_def_cb, &index);
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 2cfef211b67..73a08344197 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -768,7 +768,7 @@ typedef struct nir_ssa_def {
    /** generic SSA definition index. */
    unsigned index;
 
-   /** Index into the live_in and live_out bitfields */
+   /** Ordered SSA definition index used by nir_liveness. */
    unsigned live_index;
 
    /** Instruction which produces this SSA value. */
@@ -2603,7 +2603,9 @@ typedef struct nir_block {
     */
    int16_t dom_pre_index, dom_post_index;
 
-   /* live in and out for this block; used for liveness analysis */
+   /* SSA def live in and out for this block; used for liveness analysis.
+    * Indexed by ssa_def->index
+    */
    BITSET_WORD *live_in;
    BITSET_WORD *live_out;
 } nir_block;
diff --git a/src/compiler/nir/nir_liveness.c b/src/compiler/nir/nir_liveness.c
index 16dbeb4a223..d8f33c2d0ea 100644
--- a/src/compiler/nir/nir_liveness.c
+++ b/src/compiler/nir/nir_liveness.c
@@ -96,7 +96,7 @@ set_src_live(nir_src *src, void *void_live)
    if (src->ssa->live_index == 0)
       return true;   /* undefined variables are never live */
 
-   BITSET_SET(live, src->ssa->live_index);
+   BITSET_SET(live, src->ssa->index);
 
    return true;
 }
@@ -106,7 +106,7 @@ set_ssa_def_dead(nir_ssa_def *def, void *void_live)
 {
    BITSET_WORD *live = void_live;
 
-   BITSET_CLEAR(live, def->live_index);
+   BITSET_CLEAR(live, def->index);
 
    return true;
 }
@@ -160,7 +160,10 @@ propagate_across_edge(nir_block *pred, nir_block *succ,
 void
 nir_live_ssa_defs_impl(nir_function_impl *impl)
 {
-   struct live_ssa_defs_state state;
+   struct live_ssa_defs_state state = {
+      .bitset_words = BITSET_WORDS(impl->ssa_alloc),
+   };
+   state.tmp_live = rzalloc_array(impl, BITSET_WORD, state.bitset_words),
 
    /* We start at 1 because we reserve the index value of 0 for ssa_undef
     * instructions.  Those are never live, so their liveness information
@@ -174,12 +177,9 @@ nir_live_ssa_defs_impl(nir_function_impl *impl)
 
    nir_block_worklist_init(&state.worklist, impl->num_blocks, NULL);
 
-   /* We now know how many unique ssa definitions we have and we can go
-    * ahead and allocate live_in and live_out sets and add all of the
-    * blocks to the worklist.
+   /* Allocate live_in and live_out sets and add all of the blocks to the
+    * worklist.
     */
-   state.bitset_words = BITSET_WORDS(state.num_ssa_defs);
-   state.tmp_live = rzalloc_array(impl, BITSET_WORD, state.bitset_words);
    nir_foreach_block(block, impl) {
       init_liveness_block(block, &state);
    }
@@ -259,13 +259,13 @@ search_for_use_after_instr(nir_instr *start, nir_ssa_def *def)
 static bool
 nir_ssa_def_is_live_at(nir_ssa_def *def, nir_instr *instr)
 {
-   if (BITSET_TEST(instr->block->live_out, def->live_index)) {
+   if (BITSET_TEST(instr->block->live_out, def->index)) {
       /* Since def dominates instr, if def is in the liveout of the block,
        * it's live at instr
        */
       return true;
    } else {
-      if (BITSET_TEST(instr->block->live_in, def->live_index) ||
+      if (BITSET_TEST(instr->block->live_in, def->index) ||
           def->parent_instr->block == instr->block) {
          /* In this case it is either live coming into instr's block or it
           * is defined in the same block.  In this case, we simply need to



More information about the mesa-commit mailing list