Module: Mesa Branch: main Commit: c468aa60591bf7de81ccc235fb1038f8262b9bbc URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=c468aa60591bf7de81ccc235fb1038f8262b9bbc
Author: Timothy Arceri <[email protected]> Date: Fri Nov 24 13:49:10 2023 +1100 nir: add nir_fixup_deref_types() This will be used to fix up types after arrays have been resized. Reviewed-by: Alejandro PiƱeiro <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26534> --- src/compiler/nir/nir.h | 1 + src/compiler/nir/nir_deref.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 1a5a820c7c4..f4f3a9e097c 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -5096,6 +5096,7 @@ bool nir_opt_memcpy(nir_shader *shader); bool nir_lower_memcpy(nir_shader *shader); void nir_fixup_deref_modes(nir_shader *shader); +void nir_fixup_deref_types(nir_shader *shader); bool nir_lower_global_vars_to_local(nir_shader *shader); diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c index 5ffbe72ccdb..2e2ea655a92 100644 --- a/src/compiler/nir/nir_deref.c +++ b/src/compiler/nir/nir_deref.c @@ -458,6 +458,50 @@ nir_fixup_deref_modes(nir_shader *shader) NULL); } +static bool +nir_fixup_deref_types_instr(UNUSED struct nir_builder *b, nir_instr *instr, UNUSED void *data) +{ + if (instr->type != nir_instr_type_deref) + return false; + + nir_deref_instr *deref = nir_instr_as_deref(instr); + const struct glsl_type *parent_derived_type; + if (deref->deref_type == nir_deref_type_var) { + parent_derived_type = deref->var->type; + } else if (deref->deref_type == nir_deref_type_array || + deref->deref_type == nir_deref_type_struct) { + nir_deref_instr *parent = nir_src_as_deref(deref->parent); + if (deref->deref_type == nir_deref_type_array) { + parent_derived_type = glsl_get_array_element(parent->type); + } else if (deref->deref_type == nir_deref_type_struct) { + parent_derived_type = + glsl_get_struct_field(parent->type, deref->strct.index); + } else { + unreachable("Unsupported deref type"); + } + } else { + unreachable("Unsupported deref type"); + } + + if (deref->type == parent_derived_type) + return false; + + deref->type = parent_derived_type; + return true; +} + +/* Update deref types when array sizes have changed. */ +void +nir_fixup_deref_types(nir_shader *shader) +{ + nir_shader_instructions_pass(shader, nir_fixup_deref_types_instr, + nir_metadata_block_index | + nir_metadata_dominance | + nir_metadata_live_defs | + nir_metadata_instr_index, + NULL); +} + static bool modes_may_alias(nir_variable_mode a, nir_variable_mode b) {
