[Mesa-dev] [PATCH 06/12] nir: Add a structure splitting pass
Caio Marcelo de Oliveira Filho
caio.oliveira at intel.com
Thu Jul 26 17:59:15 UTC 2018
On Thu, Jul 26, 2018 at 09:00:02AM -0700, Jason Ekstrand wrote:
> ---
> src/compiler/Makefile.sources | 1 +
> src/compiler/nir/meson.build | 1 +
> src/compiler/nir/nir.h | 1 +
> src/compiler/nir/nir_split_vars.c | 271 ++++++++++++++++++++++++++++++
> 4 files changed, 274 insertions(+)
> create mode 100644 src/compiler/nir/nir_split_vars.c
(...)
> + const struct glsl_type *struct_type = glsl_without_array(type);
> + if (glsl_type_is_struct(struct_type)) {
> + field->num_fields = glsl_get_length(struct_type),
> + field->fields = ralloc_array(state->mem_ctx, struct field,
> + field->num_fields);
> + for (unsigned i = 0; i < field->num_fields; i++) {
> + char *field_name = NULL;
> + if (name) {
> + ralloc_asprintf(state->mem_ctx, "%s_%s", name,
> + glsl_get_struct_elem_name(struct_type, i));
> + }
Maybe if no name for the parent is available, use something in this
place ("unnamed", or whatever). That way the rest of the hierarchy
doesn't lose the meaning completely.
> +static void
> +split_struct_derefs_impl(nir_function_impl *impl,
> + struct hash_table *var_field_map,
> + nir_variable_mode modes,
> + void *mem_ctx)
> +{
> + nir_builder b;
> + nir_builder_init(&b, impl);
> +
> + nir_foreach_block(block, impl) {
> + nir_foreach_instr_safe(instr, block) {
> + if (instr->type != nir_instr_type_deref)
> + continue;
> +
> + nir_deref_instr *deref = nir_instr_as_deref(instr);
> + if (!(deref->mode & modes))
> + continue;
> +
> + /* Clean up any dead derefs we find lying around. They may refer to
> + * variables we're planning to split.
> + */
> + if (nir_deref_instr_remove_if_unused(deref))
> + continue;
> +
> + if (!glsl_type_is_vector_or_scalar(deref->type))
> + continue;
> +
> + nir_variable *base_var = nir_deref_instr_get_variable(deref);
> + struct hash_entry *entry =
> + _mesa_hash_table_search(var_field_map, base_var);
> + if (!entry)
> + continue;
> +
> + struct field *root_field = entry->data;
> +
> + nir_deref_path path;
> + nir_deref_path_init(&path, deref, mem_ctx);
> +
> + struct field *tail_field = root_field;
> + for (unsigned i = 0; path.path[i]; i++) {
> + if (path.path[i]->deref_type != nir_deref_type_struct)
> + continue;
> +
> + assert(i > 0);
> + assert(glsl_type_is_struct(path.path[i - 1]->type));
> + assert(path.path[i - 1]->type ==
> + glsl_without_array(tail_field->type));
> +
> + tail_field = &tail_field->fields[path.path[i]->strct.index];
> + }
Would make sense to assert here that tail_field is "leaf" in the
fields tree, i.e. tail_field->num_fields == 0?
Thanks,
Caio
More information about the mesa-dev
mailing list