About Social Code
aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/nir/nir_liveness.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/nir/nir_liveness.c')
-rw-r--r--src/compiler/nir/nir_liveness.c69
1 files changed, 29 insertions, 40 deletions
diff --git a/src/compiler/nir/nir_liveness.c b/src/compiler/nir/nir_liveness.c
index 27b6481ad7b..b25ca7c13d5 100644
--- a/src/compiler/nir/nir_liveness.c
+++ b/src/compiler/nir/nir_liveness.c
@@ -40,10 +40,11 @@
*/
struct live_defs_state {
- unsigned bitset_words;
+ unsigned num_bits;
+ void *mem_ctx;
/* Used in propagate_across_edge() */
- BITSET_WORD *tmp_live;
+ struct u_sparse_bitset tmp_live;
nir_block_worklist worklist;
};
@@ -55,26 +56,20 @@ static void
init_liveness_block(nir_block *block,
struct live_defs_state *state)
{
- block->live_in = reralloc(block, block->live_in, BITSET_WORD,
- state->bitset_words);
- memset(block->live_in, 0, state->bitset_words * sizeof(BITSET_WORD));
-
- block->live_out = reralloc(block, block->live_out, BITSET_WORD,
- state->bitset_words);
- memset(block->live_out, 0, state->bitset_words * sizeof(BITSET_WORD));
-
+ u_sparse_bitset_init(&block->live_in, state->num_bits, state->mem_ctx);
+ u_sparse_bitset_init(&block->live_out, state->num_bits, state->mem_ctx);
nir_block_worklist_push_head(&state->worklist, block);
}
static bool
set_src_live(nir_src *src, void *void_live)
{
- BITSET_WORD *live = void_live;
+ struct u_sparse_bitset *live = void_live;
if (nir_src_is_undef(*src))
return true; /* undefined variables are never live */
- BITSET_SET(live, src->ssa->index);
+ u_sparse_bitset_set(live, src->ssa->index);
return true;
}
@@ -82,9 +77,9 @@ set_src_live(nir_src *src, void *void_live)
static bool
set_ssa_def_dead(nir_def *def, void *void_live)
{
- BITSET_WORD *live = void_live;
+ struct u_sparse_bitset *live = void_live;
- BITSET_CLEAR(live, def->index);
+ u_sparse_bitset_clear(live, def->index);
return true;
}
@@ -102,8 +97,8 @@ static bool
propagate_across_edge(nir_block *pred, nir_block *succ,
struct live_defs_state *state)
{
- BITSET_WORD *live = state->tmp_live;
- memcpy(live, succ->live_in, state->bitset_words * sizeof *live);
+ struct u_sparse_bitset *live = &state->tmp_live;
+ u_sparse_bitset_dup(live, &succ->live_in);
nir_foreach_phi(phi, succ) {
set_ssa_def_dead(&phi->def, live);
@@ -118,21 +113,18 @@ propagate_across_edge(nir_block *pred, nir_block *succ,
}
}
- BITSET_WORD progress = 0;
- for (unsigned i = 0; i < state->bitset_words; ++i) {
- progress |= live[i] & ~pred->live_out[i];
- pred->live_out[i] |= live[i];
- }
- return progress != 0;
+ bool progress = u_sparse_bitset_merge(&pred->live_out, live);
+ u_sparse_bitset_free(live);
+ return progress;
}
void
nir_live_defs_impl(nir_function_impl *impl)
{
struct live_defs_state state = {
- .bitset_words = BITSET_WORDS(impl->ssa_alloc),
+ .num_bits = impl->ssa_alloc,
+ .mem_ctx = impl,
};
- state.tmp_live = rzalloc_array(impl, BITSET_WORD, state.bitset_words),
nir_block_worklist_init(&state.worklist, impl->num_blocks, NULL);
@@ -156,12 +148,11 @@ nir_live_defs_impl(nir_function_impl *impl)
*/
nir_block *block = nir_block_worklist_pop_head(&state.worklist);
- memcpy(block->live_in, block->live_out,
- state.bitset_words * sizeof(BITSET_WORD));
+ u_sparse_bitset_dup(&block->live_in, &block->live_out);
nir_if *following_if = nir_block_get_following_if(block);
if (following_if)
- set_src_live(&following_if->condition, block->live_in);
+ set_src_live(&following_if->condition, &block->live_in);
nir_foreach_instr_reverse(instr, block) {
/* Phi nodes are handled seperately so we want to skip them. Since
@@ -171,8 +162,8 @@ nir_live_defs_impl(nir_function_impl *impl)
if (instr->type == nir_instr_type_phi)
break;
- nir_foreach_def(instr, set_ssa_def_dead, block->live_in);
- nir_foreach_src(instr, set_src_live, block->live_in);
+ nir_foreach_def(instr, set_ssa_def_dead, &block->live_in);
+ nir_foreach_src(instr, set_src_live, &block->live_in);
}
/* Walk over all of the predecessors of the current block updating
@@ -187,7 +178,6 @@ nir_live_defs_impl(nir_function_impl *impl)
}
}
- ralloc_free(state.tmp_live);
nir_block_worklist_fini(&state.worklist);
}
@@ -197,7 +187,7 @@ nir_live_defs_impl(nir_function_impl *impl)
* which the instruction lives. Do not ralloc_free() it directly;
* instead, provide a mem_ctx and free that.
*/
-const BITSET_WORD *
+struct u_sparse_bitset *
nir_get_live_defs(nir_cursor cursor, void *mem_ctx)
{
nir_block *block = nir_cursor_current_block(cursor);
@@ -206,26 +196,25 @@ nir_get_live_defs(nir_cursor cursor, void *mem_ctx)
switch (cursor.option) {
case nir_cursor_before_block:
- return cursor.block->live_in;
+ return &cursor.block->live_in;
case nir_cursor_after_block:
- return cursor.block->live_out;
+ return &cursor.block->live_out;
case nir_cursor_before_instr:
if (cursor.instr == nir_block_first_instr(cursor.instr->block))
- return cursor.instr->block->live_in;
+ return &cursor.instr->block->live_in;
break;
case nir_cursor_after_instr:
if (cursor.instr == nir_block_last_instr(cursor.instr->block))
- return cursor.instr->block->live_out;
+ return &cursor.instr->block->live_out;
break;
}
/* If we got here, we're an instruction cursor mid-block */
- const unsigned bitset_words = BITSET_WORDS(impl->ssa_alloc);
- BITSET_WORD *live = ralloc_array(mem_ctx, BITSET_WORD, bitset_words);
- memcpy(live, block->live_out, bitset_words * sizeof(BITSET_WORD));
+ struct u_sparse_bitset *live = rzalloc_size(mem_ctx, sizeof(struct u_sparse_bitset));
+ u_sparse_bitset_dup_with_ctx(live, &block->live_out, mem_ctx);
nir_foreach_instr_reverse(instr, block) {
if (cursor.option == nir_cursor_after_instr && instr == cursor.instr)
@@ -283,13 +272,13 @@ search_for_use_after_instr(nir_instr *start, nir_def *def)
static bool
nir_def_is_live_at(nir_def *def, nir_instr *instr)
{
- if (BITSET_TEST(instr->block->live_out, def->index)) {
+ if (u_sparse_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->index) ||
+ if (u_sparse_bitset_test(&instr->block->live_in, def->index) ||
nir_def_block(def) == 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