nir: Add nir_rematerialize_deref_in_use_blocks

nir_rematerialize_deref_in_use_blocks can be used in passes that don't
run on the whole function.

Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23712>
This commit is contained in:
Konstantin Seurer 2023-07-28 17:07:49 +02:00 committed by Marge Bot
parent ba809dccb8
commit 29dc1b193a
2 changed files with 30 additions and 0 deletions

View file

@ -5955,6 +5955,8 @@ bool nir_convert_from_ssa(nir_shader *shader,
bool nir_lower_phis_to_regs_block(nir_block *block);
bool nir_lower_ssa_defs_to_regs_block(nir_block *block);
bool nir_rematerialize_deref_in_use_blocks(nir_deref_instr *instr);
bool nir_rematerialize_derefs_in_use_blocks_impl(nir_function_impl *impl);
bool nir_lower_samplers(nir_shader *shader);

View file

@ -823,6 +823,34 @@ rematerialize_deref_src(nir_src *src, void *_state)
return true;
}
bool
nir_rematerialize_deref_in_use_blocks(nir_deref_instr *instr)
{
if (nir_deref_instr_remove_if_unused(instr))
return true;
struct rematerialize_deref_state state = {
.builder = nir_builder_create(nir_cf_node_get_function(&instr->instr.block->cf_node)),
};
nir_foreach_use_safe(use, &instr->def) {
if (use->parent_instr->block == instr->instr.block)
continue;
/* If a deref is used in a phi, we can't rematerialize it, as the new
* derefs would appear before the phi, which is not valid.
*/
if (use->parent_instr->type == nir_instr_type_phi)
continue;
state.block = use->parent_instr->block;
state.builder.cursor = nir_before_instr(use->parent_instr);
rematerialize_deref_src(use, &state);
}
return state.progress;
}
/** Re-materialize derefs in every block
*
* This pass re-materializes deref instructions in every block in which it is