[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