Re: [Mesa-dev] [PATCH 06/12] nir: Add a structure splitting pass

2018-07-26 Thread Thomas Helland
2018-07-26 18:00 GMT+02:00 Jason Ekstrand :
> ---
>  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
>
> diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
> index cc147218c4e..144ba94a8c6 100644
> --- a/src/compiler/Makefile.sources
> +++ b/src/compiler/Makefile.sources
> @@ -300,6 +300,7 @@ NIR_FILES = \
> nir/nir_serialize.h \
> nir/nir_split_per_member_structs.c \
> nir/nir_split_var_copies.c \
> +   nir/nir_split_vars.c \
> nir/nir_sweep.c \
> nir/nir_to_lcssa.c \
> nir/nir_validate.c \
> diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build
> index a1bb19356ce..3fd5535ba52 100644
> --- a/src/compiler/nir/meson.build
> +++ b/src/compiler/nir/meson.build
> @@ -184,6 +184,7 @@ files_libnir = files(
>'nir_serialize.h',
>'nir_split_per_member_structs.c',
>'nir_split_var_copies.c',
> +  'nir_split_vars.c',
>'nir_sweep.c',
>'nir_to_lcssa.c',
>'nir_validate.c',
> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> index 3bfe7d7f7bf..4af7166f25b 100644
> --- a/src/compiler/nir/nir.h
> +++ b/src/compiler/nir/nir.h
> @@ -2609,6 +2609,7 @@ int nir_gs_count_vertices(const nir_shader *shader);
>
>  bool nir_split_var_copies(nir_shader *shader);
>  bool nir_split_per_member_structs(nir_shader *shader);
> +bool nir_split_struct_vars(nir_shader *shader, nir_variable_mode modes);
>
>  bool nir_lower_returns_impl(nir_function_impl *impl);
>  bool nir_lower_returns(nir_shader *shader);
> diff --git a/src/compiler/nir/nir_split_vars.c 
> b/src/compiler/nir/nir_split_vars.c
> new file mode 100644
> index 000..1f59ac2f5e7
> --- /dev/null
> +++ b/src/compiler/nir/nir_split_vars.c
> @@ -0,0 +1,271 @@
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
> DEALINGS
> + * IN THE SOFTWARE.
> + */
> +
> +#include "nir.h"
> +#include "nir_builder.h"
> +#include "nir_deref.h"
> +
> +struct split_var_state {
> +   void *mem_ctx;
> +
> +   nir_shader *shader;
> +   nir_function_impl *impl;
> +
> +   nir_variable *base_var;
> +};
> +
> +struct field {
> +   struct field *parent;
> +
> +   const struct glsl_type *type;
> +
> +   unsigned num_fields;
> +   struct field *fields;
> +
> +   nir_variable *var;
> +};
> +
> +static const struct glsl_type *
> +wrap_type_in_array(const struct glsl_type *type,
> +   const struct glsl_type *array_type)
> +{
> +   if (!glsl_type_is_array(array_type))
> +  return type;
> +
> +   const struct glsl_type *elem_type =
> +  wrap_type_in_array(type, glsl_get_array_element(array_type));
> +   return glsl_array_type(elem_type, glsl_get_length(array_type));
> +}
> +
> +static void
> +init_field_for_type(struct field *field, struct field *parent,
> +const struct glsl_type *type,
> +const char *name,
> +struct split_var_state *state)
> +{
> +   *field = (struct field) {
> +  .parent = parent,
> +  .type = type,
> +   };
> +
> +   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),

Should be semicolon at the end here?

> +  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));
> + }

Re: [Mesa-dev] [PATCH 06/12] nir: Add a structure splitting pass

2018-07-26 Thread Caio Marcelo de Oliveira Filho
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(, 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(, 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 = _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
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev