mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 20:20:18 +01:00
ir3: rematerialize preamble defs in block dominated by sources
Preamble defs were rematerialized at the end of the preamble. However, when some of the sources were defined inside control flow, this would lead to these sources not dominating their use. Fix this by finding the block that is dominated by all sources and inserting the new instruction there. Also make sure we only de-duplicate instructions if the new instruction is dominated by the existing one. Fixes a NIR validation error in Devil may cry 5. Signed-off-by: Job Noorman <jnoorman@igalia.com> Fixes:fdfe86aa52("ir3: Expand preamble rematerialization") Fixes:6a744ddebc("ir3: Initial support for pushing globals with ldg.k") Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33270>
This commit is contained in:
parent
5f3cad0026
commit
e7ac1094f6
1 changed files with 64 additions and 5 deletions
|
|
@ -367,6 +367,53 @@ ir3_def_is_rematerializable_for_preamble(nir_def *def,
|
|||
}
|
||||
}
|
||||
|
||||
struct find_insert_block_state {
|
||||
nir_block *insert_block;
|
||||
};
|
||||
|
||||
static bool
|
||||
find_dominated_src(nir_src *src, void *data)
|
||||
{
|
||||
struct find_insert_block_state *state = data;
|
||||
nir_block *src_block = src->ssa->parent_instr->block;
|
||||
|
||||
if (!state->insert_block) {
|
||||
state->insert_block = src_block;
|
||||
return true;
|
||||
} else if (nir_block_dominates(state->insert_block, src_block)) {
|
||||
state->insert_block = src_block;
|
||||
return true;
|
||||
} else if (nir_block_dominates(src_block, state->insert_block)) {
|
||||
return true;
|
||||
} else {
|
||||
state->insert_block = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the block where instr can be inserted. This is the block that is
|
||||
* dominated by all its sources. If instr doesn't have any sources, return dflt.
|
||||
*/
|
||||
static nir_block *
|
||||
find_insert_block(nir_instr *instr, nir_block *dflt)
|
||||
{
|
||||
struct find_insert_block_state state = {
|
||||
.insert_block = NULL,
|
||||
};
|
||||
|
||||
if (nir_foreach_src(instr, find_dominated_src, &state)) {
|
||||
return state.insert_block ? state.insert_block : dflt;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
dominates(const nir_instr *old_instr, const nir_instr *new_instr)
|
||||
{
|
||||
return nir_block_dominates(old_instr->block, new_instr->block);
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
_rematerialize_def(nir_builder *b, struct hash_table *remap_ht,
|
||||
struct set *instr_set, nir_def **preamble_defs,
|
||||
|
|
@ -405,17 +452,29 @@ _rematerialize_def(nir_builder *b, struct hash_table *remap_ht,
|
|||
|
||||
nir_instr *instr = nir_instr_clone_deep(b->shader, def->parent_instr,
|
||||
remap_ht);
|
||||
|
||||
/* Find a legal place to insert the new instruction. We cannot simply put it
|
||||
* at the end of the preamble since the original instruction and its sources
|
||||
* may be defined inside control flow.
|
||||
*/
|
||||
nir_metadata_require(b->impl, nir_metadata_dominance);
|
||||
nir_block *insert_block =
|
||||
find_insert_block(instr, nir_cursor_current_block(b->cursor));
|
||||
|
||||
/* Since the preamble control flow was reconstructed from the original one,
|
||||
* we must be able to find a legal place to insert the instruction.
|
||||
*/
|
||||
assert(insert_block);
|
||||
b->cursor = nir_after_block(insert_block);
|
||||
nir_builder_instr_insert(b, instr);
|
||||
|
||||
if (instr_set) {
|
||||
nir_instr *other_instr =
|
||||
nir_instr_set_add_or_rewrite(instr_set, instr, NULL);
|
||||
nir_instr_set_add_or_rewrite(instr_set, instr, dominates);
|
||||
if (other_instr) {
|
||||
instr = other_instr;
|
||||
_mesa_hash_table_insert(remap_ht, def, nir_instr_def(other_instr));
|
||||
} else {
|
||||
nir_builder_instr_insert(b, instr);
|
||||
}
|
||||
} else {
|
||||
nir_builder_instr_insert(b, instr);
|
||||
}
|
||||
|
||||
return nir_instr_def(instr);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue