}
}
-static void
-rewrite_deref_instr(nir_builder *b, nir_deref_instr *deref,
- struct hash_table *var_to_member_map)
+static bool
+rewrite_deref_instr(nir_builder *b, nir_instr *instr, void *cb_data)
{
+ if (instr->type != nir_instr_type_deref)
+ return false;
+
+ nir_deref_instr *deref = nir_instr_as_deref(instr);
+ struct hash_table *var_to_member_map = cb_data;
+
/* We must be a struct deref */
if (deref->deref_type != nir_deref_type_struct)
- return;
+ return false;
nir_deref_instr *base;
for (base = nir_deref_instr_parent(deref);
/* If this struct is nested inside another, bail */
if (base->deref_type == nir_deref_type_struct)
- return;
+ return false;
}
/* We must be on a variable with members */
if (!base || base->var->num_members == 0)
- return;
+ return false;
nir_variable *member = find_var_member(base->var, deref->strct.index,
var_to_member_map);
/* The referenced variable is no longer valid, clean up the deref */
nir_deref_instr_remove_if_unused(deref);
+
+ return true;
}
bool
return false;
}
- nir_foreach_function(function, shader) {
- if (!function->impl)
- continue;
-
- nir_builder b;
- nir_builder_init(&b, function->impl);
- nir_foreach_block(block, function->impl) {
- nir_foreach_instr_safe(instr, block) {
- if (instr->type == nir_instr_type_deref) {
- rewrite_deref_instr(&b, nir_instr_as_deref(instr),
- var_to_member_map);
- }
- }
- }
-
- nir_metadata_preserve(function->impl,
- nir_metadata_block_index |
- nir_metadata_dominance);
- }
+ nir_shader_instructions_pass(shader, rewrite_deref_instr,
+ nir_metadata_block_index |
+ nir_metadata_dominance,
+ var_to_member_map);
ralloc_free(dead_ctx);