Re: [Mesa-dev] [PATCH v4 006/129] nir: Add helpers for working with deref instructions

2018-06-01 Thread Jason Ekstrand
On Fri, Jun 1, 2018 at 6:03 AM, Bas Nieuwenhuizen 
wrote:

> On Fri, Jun 1, 2018 at 7:01 AM, Jason Ekstrand 
> wrote:
> > This commit adds a pass for lowering deref instructions to deref chains
> > as well as some smaller helpers to ease the transition.
> >
> > Reviewed-by: Caio Marcelo de Oliveira Filho 
> > ---
> >  src/compiler/Makefile.sources  |   1 +
> >  src/compiler/nir/meson.build   |   1 +
> >  src/compiler/nir/nir.h |  33 +
> >  src/compiler/nir/nir_builder.h |  23 
> >  src/compiler/nir/nir_deref.c   | 301 ++
> +++
> >  5 files changed, 359 insertions(+)
> >  create mode 100644 src/compiler/nir/nir_deref.c
> >
> > diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.
> sources
> > index 3daa2c5..ee30046 100644
> > --- a/src/compiler/Makefile.sources
> > +++ b/src/compiler/Makefile.sources
> > @@ -201,6 +201,7 @@ NIR_FILES = \
> > nir/nir_control_flow.c \
> > nir/nir_control_flow.h \
> > nir/nir_control_flow_private.h \
> > +   nir/nir_deref.c \
> > nir/nir_dominance.c \
> > nir/nir_format_convert.h \
> > nir/nir_from_ssa.c \
> > diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build
> > index 3fec363..6c80c36 100644
> > --- a/src/compiler/nir/meson.build
> > +++ b/src/compiler/nir/meson.build
> > @@ -92,6 +92,7 @@ files_libnir = files(
> >'nir_control_flow.c',
> >'nir_control_flow.h',
> >'nir_control_flow_private.h',
> > +  'nir_deref.c',
> >'nir_dominance.c',
> >'nir_format_convert.h',
> >'nir_from_ssa.c',
> > diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> > index 4f359f1..8b826d8 100644
> > --- a/src/compiler/nir/nir.h
> > +++ b/src/compiler/nir/nir.h
> > @@ -1003,6 +1003,27 @@ nir_src_as_deref(nir_src src)
> > return nir_instr_as_deref(src.ssa->parent_instr);
> >  }
> >
> > +static inline nir_deref_instr *
> > +nir_deref_instr_parent(const nir_deref_instr *instr)
> > +{
> > +   if (instr->deref_type == nir_deref_type_var)
> > +  return NULL;
> > +   else
> > +  return nir_src_as_deref(instr->parent);
> > +}
> > +
> > +static inline nir_variable *
> > +nir_deref_instr_get_variable(const nir_deref_instr *instr)
> > +{
> > +   while (instr->deref_type != nir_deref_type_var)
> > +  instr = nir_deref_instr_parent(instr);
>
> I think we need to handle casts here, for which the type can be !=
> nir_deref_type_var, but the next iteration can have instr = NULL. Can
> be fixed with
>
>
>  static inline nir_variable *
>  nir_deref_instr_get_variable(const nir_deref_instr *instr)
>  {
> -   while (instr->deref_type != nir_deref_type_var)
> +   while (instr && instr->deref_type != nir_deref_type_var)
>instr = nir_deref_instr_parent(instr);
>
> -   return instr->var;
> +   return instr ? instr->var : NULL;
>  }
>
>
> (Unless we want it to not look past casts, then we need to add &&
> instr->deref_type != nir_deref_type_cast to the while condition)
>

I think we want to not handle casts here.  Anything that's calling this and
doesn't know about casts will almost certainly be wrong if we give it a
variable.  I'm going to send out a few FIXUP patches in a minute.


> > +
> > +   return instr->var;
> > +}
> > +
> > +nir_deref_var *
> > +nir_deref_instr_to_deref(nir_deref_instr *instr, void *mem_ctx);
> > +
> >  typedef struct {
> > nir_instr instr;
> >
> > @@ -2598,6 +2619,18 @@ bool nir_inline_functions(nir_shader *shader);
> >
> >  bool nir_propagate_invariant(nir_shader *shader);
> >
> > +enum nir_lower_deref_flags {
> > +   nir_lower_load_store_derefs =   (1 << 0),
> > +   nir_lower_texture_derefs =  (1 << 1),
> > +   nir_lower_interp_derefs =   (1 << 2),
> > +   nir_lower_atomic_counter_derefs =   (1 << 3),
> > +   nir_lower_atomic_derefs =   (1 << 4),
> > +   nir_lower_image_derefs =(1 << 5),
> > +};
> > +
> > +bool nir_lower_deref_instrs(nir_shader *shader,
> > +enum nir_lower_deref_flags flags);
> > +
> >  void nir_lower_var_copy_instr(nir_intrinsic_instr *copy, nir_shader
> *shader);
> >  bool nir_lower_var_copies(nir_shader *shader);
> >
> > diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_
> builder.h
> > index a667372..42fe285 100644
> > --- a/src/compiler/nir/nir_builder.h
> > +++ b/src/compiler/nir/nir_builder.h
> > @@ -644,6 +644,29 @@ nir_build_deref_cast(nir_builder *build,
> nir_ssa_def *parent,
> > return deref;
> >  }
> >
> > +static inline nir_deref_instr *
> > +nir_build_deref_for_chain(nir_builder *b, nir_deref_var *deref_var)
> > +{
> > +   nir_deref_instr *tail = nir_build_deref_var(b, deref_var->var);
> > +   for (nir_deref *d = deref_var->deref.child; d; d = d->child) {
> > +  if (d->deref_type == nir_deref_type_array) {
> > + nir_deref_array *a = nir_deref_as_array(d);
> > + assert(a->deref_array_type != nir_deref_array_type_wildcard);
> > +
> > + nir_ssa_def 

Re: [Mesa-dev] [PATCH v4 006/129] nir: Add helpers for working with deref instructions

2018-06-01 Thread Bas Nieuwenhuizen
On Fri, Jun 1, 2018 at 7:01 AM, Jason Ekstrand  wrote:
> This commit adds a pass for lowering deref instructions to deref chains
> as well as some smaller helpers to ease the transition.
>
> Reviewed-by: Caio Marcelo de Oliveira Filho 
> ---
>  src/compiler/Makefile.sources  |   1 +
>  src/compiler/nir/meson.build   |   1 +
>  src/compiler/nir/nir.h |  33 +
>  src/compiler/nir/nir_builder.h |  23 
>  src/compiler/nir/nir_deref.c   | 301 
> +
>  5 files changed, 359 insertions(+)
>  create mode 100644 src/compiler/nir/nir_deref.c
>
> diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
> index 3daa2c5..ee30046 100644
> --- a/src/compiler/Makefile.sources
> +++ b/src/compiler/Makefile.sources
> @@ -201,6 +201,7 @@ NIR_FILES = \
> nir/nir_control_flow.c \
> nir/nir_control_flow.h \
> nir/nir_control_flow_private.h \
> +   nir/nir_deref.c \
> nir/nir_dominance.c \
> nir/nir_format_convert.h \
> nir/nir_from_ssa.c \
> diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build
> index 3fec363..6c80c36 100644
> --- a/src/compiler/nir/meson.build
> +++ b/src/compiler/nir/meson.build
> @@ -92,6 +92,7 @@ files_libnir = files(
>'nir_control_flow.c',
>'nir_control_flow.h',
>'nir_control_flow_private.h',
> +  'nir_deref.c',
>'nir_dominance.c',
>'nir_format_convert.h',
>'nir_from_ssa.c',
> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> index 4f359f1..8b826d8 100644
> --- a/src/compiler/nir/nir.h
> +++ b/src/compiler/nir/nir.h
> @@ -1003,6 +1003,27 @@ nir_src_as_deref(nir_src src)
> return nir_instr_as_deref(src.ssa->parent_instr);
>  }
>
> +static inline nir_deref_instr *
> +nir_deref_instr_parent(const nir_deref_instr *instr)
> +{
> +   if (instr->deref_type == nir_deref_type_var)
> +  return NULL;
> +   else
> +  return nir_src_as_deref(instr->parent);
> +}
> +
> +static inline nir_variable *
> +nir_deref_instr_get_variable(const nir_deref_instr *instr)
> +{
> +   while (instr->deref_type != nir_deref_type_var)
> +  instr = nir_deref_instr_parent(instr);

I think we need to handle casts here, for which the type can be !=
nir_deref_type_var, but the next iteration can have instr = NULL. Can
be fixed with


 static inline nir_variable *
 nir_deref_instr_get_variable(const nir_deref_instr *instr)
 {
-   while (instr->deref_type != nir_deref_type_var)
+   while (instr && instr->deref_type != nir_deref_type_var)
   instr = nir_deref_instr_parent(instr);

-   return instr->var;
+   return instr ? instr->var : NULL;
 }


(Unless we want it to not look past casts, then we need to add &&
instr->deref_type != nir_deref_type_cast to the while condition)

> +
> +   return instr->var;
> +}
> +
> +nir_deref_var *
> +nir_deref_instr_to_deref(nir_deref_instr *instr, void *mem_ctx);
> +
>  typedef struct {
> nir_instr instr;
>
> @@ -2598,6 +2619,18 @@ bool nir_inline_functions(nir_shader *shader);
>
>  bool nir_propagate_invariant(nir_shader *shader);
>
> +enum nir_lower_deref_flags {
> +   nir_lower_load_store_derefs =   (1 << 0),
> +   nir_lower_texture_derefs =  (1 << 1),
> +   nir_lower_interp_derefs =   (1 << 2),
> +   nir_lower_atomic_counter_derefs =   (1 << 3),
> +   nir_lower_atomic_derefs =   (1 << 4),
> +   nir_lower_image_derefs =(1 << 5),
> +};
> +
> +bool nir_lower_deref_instrs(nir_shader *shader,
> +enum nir_lower_deref_flags flags);
> +
>  void nir_lower_var_copy_instr(nir_intrinsic_instr *copy, nir_shader *shader);
>  bool nir_lower_var_copies(nir_shader *shader);
>
> diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h
> index a667372..42fe285 100644
> --- a/src/compiler/nir/nir_builder.h
> +++ b/src/compiler/nir/nir_builder.h
> @@ -644,6 +644,29 @@ nir_build_deref_cast(nir_builder *build, nir_ssa_def 
> *parent,
> return deref;
>  }
>
> +static inline nir_deref_instr *
> +nir_build_deref_for_chain(nir_builder *b, nir_deref_var *deref_var)
> +{
> +   nir_deref_instr *tail = nir_build_deref_var(b, deref_var->var);
> +   for (nir_deref *d = deref_var->deref.child; d; d = d->child) {
> +  if (d->deref_type == nir_deref_type_array) {
> + nir_deref_array *a = nir_deref_as_array(d);
> + assert(a->deref_array_type != nir_deref_array_type_wildcard);
> +
> + nir_ssa_def *index = nir_imm_int(b, a->base_offset);
> + if (a->deref_array_type == nir_deref_array_type_indirect)
> +index = nir_iadd(b, index, nir_ssa_for_src(b, a->indirect, 1));
> +
> + tail = nir_build_deref_array(b, tail, index);
> +  } else {
> + nir_deref_struct *s = nir_deref_as_struct(d);
> + tail = nir_build_deref_struct(b, tail, s->index);
> +  }
> +   }
> +
> +   return tail;
> +}
> +
>  static inline nir_ssa_def *
>  nir_load_reg(nir_builder *build, nir_register *reg)
>  {
> diff 

[Mesa-dev] [PATCH v4 006/129] nir: Add helpers for working with deref instructions

2018-05-31 Thread Jason Ekstrand
This commit adds a pass for lowering deref instructions to deref chains
as well as some smaller helpers to ease the transition.

Reviewed-by: Caio Marcelo de Oliveira Filho 
---
 src/compiler/Makefile.sources  |   1 +
 src/compiler/nir/meson.build   |   1 +
 src/compiler/nir/nir.h |  33 +
 src/compiler/nir/nir_builder.h |  23 
 src/compiler/nir/nir_deref.c   | 301 +
 5 files changed, 359 insertions(+)
 create mode 100644 src/compiler/nir/nir_deref.c

diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
index 3daa2c5..ee30046 100644
--- a/src/compiler/Makefile.sources
+++ b/src/compiler/Makefile.sources
@@ -201,6 +201,7 @@ NIR_FILES = \
nir/nir_control_flow.c \
nir/nir_control_flow.h \
nir/nir_control_flow_private.h \
+   nir/nir_deref.c \
nir/nir_dominance.c \
nir/nir_format_convert.h \
nir/nir_from_ssa.c \
diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build
index 3fec363..6c80c36 100644
--- a/src/compiler/nir/meson.build
+++ b/src/compiler/nir/meson.build
@@ -92,6 +92,7 @@ files_libnir = files(
   'nir_control_flow.c',
   'nir_control_flow.h',
   'nir_control_flow_private.h',
+  'nir_deref.c',
   'nir_dominance.c',
   'nir_format_convert.h',
   'nir_from_ssa.c',
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 4f359f1..8b826d8 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1003,6 +1003,27 @@ nir_src_as_deref(nir_src src)
return nir_instr_as_deref(src.ssa->parent_instr);
 }
 
+static inline nir_deref_instr *
+nir_deref_instr_parent(const nir_deref_instr *instr)
+{
+   if (instr->deref_type == nir_deref_type_var)
+  return NULL;
+   else
+  return nir_src_as_deref(instr->parent);
+}
+
+static inline nir_variable *
+nir_deref_instr_get_variable(const nir_deref_instr *instr)
+{
+   while (instr->deref_type != nir_deref_type_var)
+  instr = nir_deref_instr_parent(instr);
+
+   return instr->var;
+}
+
+nir_deref_var *
+nir_deref_instr_to_deref(nir_deref_instr *instr, void *mem_ctx);
+
 typedef struct {
nir_instr instr;
 
@@ -2598,6 +2619,18 @@ bool nir_inline_functions(nir_shader *shader);
 
 bool nir_propagate_invariant(nir_shader *shader);
 
+enum nir_lower_deref_flags {
+   nir_lower_load_store_derefs =   (1 << 0),
+   nir_lower_texture_derefs =  (1 << 1),
+   nir_lower_interp_derefs =   (1 << 2),
+   nir_lower_atomic_counter_derefs =   (1 << 3),
+   nir_lower_atomic_derefs =   (1 << 4),
+   nir_lower_image_derefs =(1 << 5),
+};
+
+bool nir_lower_deref_instrs(nir_shader *shader,
+enum nir_lower_deref_flags flags);
+
 void nir_lower_var_copy_instr(nir_intrinsic_instr *copy, nir_shader *shader);
 bool nir_lower_var_copies(nir_shader *shader);
 
diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h
index a667372..42fe285 100644
--- a/src/compiler/nir/nir_builder.h
+++ b/src/compiler/nir/nir_builder.h
@@ -644,6 +644,29 @@ nir_build_deref_cast(nir_builder *build, nir_ssa_def 
*parent,
return deref;
 }
 
+static inline nir_deref_instr *
+nir_build_deref_for_chain(nir_builder *b, nir_deref_var *deref_var)
+{
+   nir_deref_instr *tail = nir_build_deref_var(b, deref_var->var);
+   for (nir_deref *d = deref_var->deref.child; d; d = d->child) {
+  if (d->deref_type == nir_deref_type_array) {
+ nir_deref_array *a = nir_deref_as_array(d);
+ assert(a->deref_array_type != nir_deref_array_type_wildcard);
+
+ nir_ssa_def *index = nir_imm_int(b, a->base_offset);
+ if (a->deref_array_type == nir_deref_array_type_indirect)
+index = nir_iadd(b, index, nir_ssa_for_src(b, a->indirect, 1));
+
+ tail = nir_build_deref_array(b, tail, index);
+  } else {
+ nir_deref_struct *s = nir_deref_as_struct(d);
+ tail = nir_build_deref_struct(b, tail, s->index);
+  }
+   }
+
+   return tail;
+}
+
 static inline nir_ssa_def *
 nir_load_reg(nir_builder *build, nir_register *reg)
 {
diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
new file mode 100644
index 000..87a8192
--- /dev/null
+++ b/src/compiler/nir/nir_deref.c
@@ -0,0 +1,301 @@
+/*
+ * 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