Module: Mesa Branch: master Commit: 2f5d18403a4d51a2cd927c141884361850bad41d URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=2f5d18403a4d51a2cd927c141884361850bad41d
Author: Eric Anholt <[email protected]> Date: Tue Sep 29 15:44:57 2020 -0700 nir: Replace nir_ssa_def->live_index with nir_instr->index. live_index had two things going on: 0 meant the instr was an undef and always dead, and otherwise ssa defs had increasing numbers by instruction order. We already have a field in the instruction for storing instruction order, and ssa defs don't need that number to be contiguous (if you want a compact per-ssa-def number, use ssa->index after reindexing). We don't use ssa->index for this, because reindexing those would change nir_print, and that would be rude to people trying to track what's happening in optimization passes. This openend up a hole in nir_ssa_def, so we move nir_ssa_def->index toward the end to shrink the struct from 64 bytes to 56. Reviewed-by: Jason Ekstrand <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3395> --- src/compiler/nir/nir.c | 1 - src/compiler/nir/nir.h | 10 +++------- src/compiler/nir/nir_from_ssa.c | 29 +++++++++++++++++++++++------ src/compiler/nir/nir_liveness.c | 32 +++++++------------------------- 4 files changed, 33 insertions(+), 39 deletions(-) diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 032dbcb3be5..b3a5384f663 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -1555,7 +1555,6 @@ nir_ssa_def_init(nir_instr *instr, nir_ssa_def *def, unsigned bit_size, const char *name) { def->name = ralloc_strdup(instr, name); - def->live_index = UINT_MAX; /* Something clearly OOB */ def->parent_instr = instr; list_inithead(&def->uses); list_inithead(&def->if_uses); diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index b480e691008..70eed7948ea 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -786,12 +786,6 @@ typedef struct nir_ssa_def { /** for debugging only, can be NULL */ const char* name; - /** generic SSA definition index. */ - unsigned index; - - /** Ordered SSA definition index used by nir_liveness. */ - unsigned live_index; - /** Instruction which produces this SSA value. */ nir_instr *parent_instr; @@ -801,6 +795,9 @@ typedef struct nir_ssa_def { /** set of nir_ifs where this register is used as a condition */ struct list_head if_uses; + /** generic SSA definition index. */ + unsigned index; + uint8_t num_components; /* The bit-size of each channel; must be one of 8, 16, 32, or 64 */ @@ -2841,7 +2838,6 @@ typedef enum { * * This includes: * - * - nir_ssa_def::live_index * - nir_block::live_in * - nir_block::live_out * diff --git a/src/compiler/nir/nir_from_ssa.c b/src/compiler/nir/nir_from_ssa.c index 52c3a2cb33b..fcaf156d218 100644 --- a/src/compiler/nir/nir_from_ssa.c +++ b/src/compiler/nir/nir_from_ssa.c @@ -44,17 +44,33 @@ struct from_ssa_state { bool progress; }; +/* Returns if def @a comes after def @b. + * + * We treat SSA undefs as always coming before other instruction types. + */ +static bool +def_after(nir_ssa_def *a, nir_ssa_def *b) +{ + if (a->parent_instr->type == nir_instr_type_ssa_undef) + return false; + + if (b->parent_instr->type == nir_instr_type_ssa_undef) + return true; + + return a->parent_instr->index > b->parent_instr->index; +} + /* Returns true if a dominates b */ static bool ssa_def_dominates(nir_ssa_def *a, nir_ssa_def *b) { - if (a->live_index == 0) { + if (a->parent_instr->type == nir_instr_type_ssa_undef) { /* SSA undefs always dominate */ return true; - } else if (b->live_index < a->live_index) { + } if (def_after(a, b)) { return false; } else if (a->parent_instr->block == b->parent_instr->block) { - return a->live_index <= b->live_index; + return def_after(b, a); } else { return nir_block_dominates(a->parent_instr->block, b->parent_instr->block); @@ -157,7 +173,7 @@ merge_merge_sets(merge_set *a, merge_set *b) merge_node *b_node = exec_node_data(merge_node, bn, node); if (exec_node_is_tail_sentinel(an) || - a_node->def->live_index > b_node->def->live_index) { + def_after(a_node->def, b_node->def)) { struct exec_node *next = bn->next; exec_node_remove(bn); exec_node_insert_node_before(an, bn); @@ -202,7 +218,7 @@ merge_sets_interfere(merge_set *a, merge_set *b) merge_node *a_node = exec_node_data(merge_node, an, node); merge_node *b_node = exec_node_data(merge_node, bn, node); - if (a_node->def->live_index <= b_node->def->live_index) { + if (def_after(b_node->def, a_node->def)) { current = a_node; an = an->next; } else { @@ -785,7 +801,8 @@ nir_convert_from_ssa_impl(nir_function_impl *impl, bool phi_webs_only) nir_metadata_preserve(impl, nir_metadata_block_index | nir_metadata_dominance); - nir_metadata_require(impl, nir_metadata_live_ssa_defs | + nir_metadata_require(impl, nir_metadata_instr_index | + nir_metadata_live_ssa_defs | nir_metadata_dominance); nir_foreach_block(block, impl) { diff --git a/src/compiler/nir/nir_liveness.c b/src/compiler/nir/nir_liveness.c index 9b9df10e66d..accb418e6e4 100644 --- a/src/compiler/nir/nir_liveness.c +++ b/src/compiler/nir/nir_liveness.c @@ -43,7 +43,6 @@ */ struct live_ssa_defs_state { - unsigned num_ssa_defs; unsigned bitset_words; /* Used in propagate_across_edge() */ @@ -52,19 +51,6 @@ struct live_ssa_defs_state { nir_block_worklist worklist; }; -static bool -index_ssa_def(nir_ssa_def *def, void *void_state) -{ - struct live_ssa_defs_state *state = void_state; - - if (def->parent_instr->type == nir_instr_type_ssa_undef) - def->live_index = 0; - else - def->live_index = state->num_ssa_defs++; - - return true; -} - /* Initialize the liveness data to zero and add the given block to the * worklist. */ @@ -93,7 +79,7 @@ set_src_live(nir_src *src, void *void_live) if (!src->is_ssa) return true; - if (src->ssa->live_index == 0) + if (src->ssa->parent_instr->type == nir_instr_type_ssa_undef) return true; /* undefined variables are never live */ BITSET_SET(live, src->ssa->index); @@ -165,15 +151,10 @@ nir_live_ssa_defs_impl(nir_function_impl *impl) }; 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 - * can be compacted into a single bit. + /* Number the instructions so we can do cheap interference tests using the + * instruction index. */ - state.num_ssa_defs = 1; - nir_foreach_block(block, impl) { - nir_foreach_instr(instr, block) - nir_foreach_ssa_def(instr, index_ssa_def, &state); - } + nir_metadata_require(impl, nir_metadata_instr_index); nir_block_worklist_init(&state.worklist, impl->num_blocks, NULL); @@ -295,10 +276,11 @@ nir_ssa_defs_interfere(nir_ssa_def *a, nir_ssa_def *b) * least one isn't dead. */ return true; - } else if (a->live_index == 0 || b->live_index == 0) { + } else if (a->parent_instr->type == nir_instr_type_ssa_undef || + b->parent_instr->type == nir_instr_type_ssa_undef) { /* If either variable is an ssa_undef, then there's no interference */ return false; - } else if (a->live_index < b->live_index) { + } else if (a->parent_instr->index < b->parent_instr->index) { return nir_ssa_def_is_live_at(a, b->parent_instr); } else { return nir_ssa_def_is_live_at(b, a->parent_instr); _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
