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)
 {

Reply via email to