From 29dc1b193a0112dad270979682f2c94e87e144fc Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Fri, 28 Jul 2023 17:07:49 +0200 Subject: [PATCH] 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 Part-of: --- src/compiler/nir/nir.h | 2 ++ src/compiler/nir/nir_deref.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 3a7953e8624..2c367ab1d6e 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -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); diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c index 0513974780d..5dfb06edae3 100644 --- a/src/compiler/nir/nir_deref.c +++ b/src/compiler/nir/nir_deref.c @@ -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