mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 06:30:11 +01:00
nir: Add a call to get a struct describing SSA liveness per instruction.
nir-to-tgsi will use this to release release temporaries for SSA storage back to ureg's linear register allocation once they're dead. Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3395>
This commit is contained in:
parent
a206b58157
commit
c730feacc0
2 changed files with 95 additions and 0 deletions
|
|
@ -3477,6 +3477,26 @@ nir_shader_get_entrypoint(nir_shader *shader)
|
|||
return func->impl;
|
||||
}
|
||||
|
||||
typedef struct nir_liveness_bounds {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
} nir_liveness_bounds;
|
||||
|
||||
typedef struct nir_instr_liveness {
|
||||
/**
|
||||
* nir_instr->index for the start and end of a single live interval for SSA
|
||||
* defs. ssa values last used by a nir_if condition will have an interval
|
||||
* ending at the first instruction after the last one before the if
|
||||
* condition.
|
||||
*
|
||||
* Indexed by def->index (impl->ssa_alloc elements).
|
||||
*/
|
||||
struct nir_liveness_bounds *defs;
|
||||
} nir_instr_liveness;
|
||||
|
||||
nir_instr_liveness *
|
||||
nir_live_ssa_defs_per_instr(nir_function_impl *impl);
|
||||
|
||||
nir_shader *nir_shader_create(void *mem_ctx,
|
||||
gl_shader_stage stage,
|
||||
const nir_shader_compiler_options *options,
|
||||
|
|
|
|||
|
|
@ -286,3 +286,78 @@ nir_ssa_defs_interfere(nir_ssa_def *a, nir_ssa_def *b)
|
|||
return nir_ssa_def_is_live_at(b, a->parent_instr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Takes an SSA def's defs and uses and expands the live interval to cover
|
||||
* that range. Control flow effects are handled separately.
|
||||
*/
|
||||
static bool def_cb(nir_ssa_def *def, void *state)
|
||||
{
|
||||
nir_instr_liveness *liveness = state;
|
||||
nir_instr *instr = def->parent_instr;
|
||||
int index = def->index;
|
||||
|
||||
liveness->defs[index].start = MIN2(liveness->defs[index].start, instr->index);
|
||||
|
||||
nir_foreach_use(src, def) {
|
||||
liveness->defs[index].end = MAX2(liveness->defs[index].end,
|
||||
src->parent_instr->index);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nir_instr_liveness *
|
||||
nir_live_ssa_defs_per_instr(nir_function_impl *impl)
|
||||
{
|
||||
/* We'll use block-level live_ssa_defs to expand our per-instr ranges for
|
||||
* control flow.
|
||||
*/
|
||||
nir_metadata_require(impl,
|
||||
nir_metadata_block_index |
|
||||
nir_metadata_instr_index |
|
||||
nir_metadata_live_ssa_defs);
|
||||
|
||||
/* Make our struct. */
|
||||
nir_instr_liveness *liveness = ralloc(NULL, nir_instr_liveness);
|
||||
liveness->defs = rzalloc_array(liveness, nir_liveness_bounds,
|
||||
impl->ssa_alloc);
|
||||
|
||||
/* Set our starts so we can use MIN2() as we accumulate bounds. */
|
||||
for (int i = 0; i < impl->ssa_alloc; i++)
|
||||
liveness->defs->start = ~0;
|
||||
|
||||
unsigned last_instr = 0;
|
||||
nir_foreach_block(block, impl) {
|
||||
unsigned index;
|
||||
BITSET_FOREACH_SET(index, block->live_in, impl->ssa_alloc) {
|
||||
liveness->defs[index].start = MIN2(liveness->defs[index].start,
|
||||
last_instr);
|
||||
}
|
||||
|
||||
nir_foreach_instr(instr, block) {
|
||||
nir_foreach_ssa_def(instr, def_cb, liveness);
|
||||
|
||||
last_instr = instr->index;
|
||||
};
|
||||
|
||||
/* track an if src's use. We need to make sure that our value is live
|
||||
* across the if reference, where we don't have an instr->index
|
||||
* representing the use. Mark it as live through the next real
|
||||
* instruction.
|
||||
*/
|
||||
nir_if *nif = nir_block_get_following_if(block);
|
||||
if (nif) {
|
||||
if (nif->condition.is_ssa) {
|
||||
liveness->defs[nif->condition.ssa->index].end = MAX2(
|
||||
liveness->defs[nif->condition.ssa->index].end,
|
||||
last_instr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
BITSET_FOREACH_SET(index, block->live_out, impl->ssa_alloc) {
|
||||
liveness->defs[index].end = MAX2(liveness->defs[index].end, last_instr);
|
||||
}
|
||||
}
|
||||
|
||||
return liveness;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue