From 73d2c6cdce8c12e87e387bc958c720f9d8f6b9b4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 23 Jul 2020 12:29:02 -0700 Subject: [PATCH] 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 Part-of: --- 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 -- 2.30.2