Re: [Mesa-dev] [PATCH 02/10] nir: Add a loop analysis pass

2016-09-19 Thread Timothy Arceri
On Fri, 2016-09-16 at 15:25 -0700, Jason Ekstrand wrote:
> > On Thu, Sep 15, 2016 at 12:03 AM, Timothy Arceri  wrote:
> > > > From: Thomas Helland 
> > 
> > 
> > This pass detects induction variables and calculates the
> > 
> > trip count of loops to be used for loop unrolling.
> > 
> > 
> > 
> > I've removed support for float induction values for now, for the
> > 
> > simple reason that they don't appear in my shader-db collection,
> > 
> > and so I don't see it as common enough that we want to pollute the
> > 
> > pass with this in the initial version.
> > 
> > 
> > 
> > V2: Rebase, adapt to removal of function overloads
> > 
> > 
> > 
> > V3: (Timothy Arceri)
> > 
> > > >  - don't try to find trip count if loop terminator conditional is a
phi
> > 
> >  - fix trip count for do-while loops
> > 
> >  - replace conditional type != alu assert with return
> > 
> >  - disable unrolling of loops with continues
> > 
> > > >  - multiple fixes to memory allocation, stop leaking and don't
destroy
> > 
> >    structs we want to use for unrolling.
> > 
> > > >  - fix iteration count bugs when induction var not on RHS of
condition
> > 
> >  - add FIXME for && conditions
> > 
> >  - calculate trip count for unsigned induction/limit vars
> > 
> > 
> > 
> > V4:
> > 
> > - count instructions in a loop
> > 
> > > > - set the limiting_terminator even if we can't find the trip count
for
> > 
> > > >  all terminators. This is needed for complex unrolling where we
handle
> > 
> >  2 terminators and the trip count is unknown for one of them.
> > 
> > - restruct structs so we don't keep information not required after
> > 
> >  analysis and remove dead fields.
> > 
> > > > - force unrolling in some cases as per the rules in the GLSL IR
pass
> > 
> > ---
> > 
> >  src/compiler/Makefile.sources       |    2 +
> > 
> >  src/compiler/nir/nir.h              |   36 +-
> > 
> > > >  src/compiler/nir/nir_loop_analyze.c | 1012
+++
> > 
> >  src/compiler/nir/nir_metadata.c     |    8 +-
> > 
> >  4 files changed, 1056 insertions(+), 2 deletions(-)
> > 
> >  create mode 100644 src/compiler/nir/nir_loop_analyze.c
> > 
> > 
> > 
> > > > diff --git a/src/compiler/Makefile.sources
b/src/compiler/Makefile.sources
> > 
> > index f5b4f9c..7ed26a9 100644
> > 
> > --- a/src/compiler/Makefile.sources
> > 
> > +++ b/src/compiler/Makefile.sources
> > 
> > @@ -190,6 +190,8 @@ NIR_FILES = \
> > 
> >         nir/nir_intrinsics.c \
> > 
> >         nir/nir_intrinsics.h \
> > 
> >         nir/nir_liveness.c \
> > 
> > +       nir/nir_loop_analyze.c \
> > 
> > +       nir/nir_loop_analyze.h \
> > 
> >         nir/nir_lower_alu_to_scalar.c \
> > 
> >         nir/nir_lower_atomics.c \
> > 
> >         nir/nir_lower_bitmap.c \
> > 
> > diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> > 
> > index ff7c422..49e8cd8 100644
> > 
> > --- a/src/compiler/nir/nir.h
> > 
> > +++ b/src/compiler/nir/nir.h
> > 
> > @@ -1549,9 +1549,36 @@ nir_if_last_else_node(nir_if *if_stmt)
> > 
> >  }
> > 
> > 
> > 
> >  typedef struct {
> > 
> > +   nir_if *nif;
> > 
> > +
> > 
> > +   nir_instr *conditional_instr;
> > 
> > +
> > 
> > +   struct list_head loop_terminator_link;
> > 
> > +} nir_loop_terminator;
> > 
> > +
> > 
> > +typedef struct {
> > 
> > +   /* Number of instructions in the loop */
> > 
> > +   unsigned num_instructions;
> > 
> > +
> > 
> > +   /* How many times the loop is run (if known) */
> > 
> > +   unsigned trip_count;
> > 
> > +   bool is_trip_count_known;
> > We could use 0 or -1 to indicate "I don't know trip count" instead of
an extra boolean.  Not sure that it matters much.
>  
> > +
> > 
> > +   /* Unroll the loop regardless of its size */
> > 
> > +   bool force_unroll;
> > It seems a bit odd to have this decide to force-unroll.  This is an
analysis pass, not a "make decisions" pass.
> 
> 
> 
>  
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > 

Re: [Mesa-dev] [PATCH 02/10] nir: Add a loop analysis pass

2016-09-19 Thread Timothy Arceri
I sent this reply on Saturday however is seems something went wrong and
it didn't make it out so here it is again.

On Fri, 2016-09-16 at 15:25 -0700, Jason Ekstrand wrote:
> On Thu, Sep 15, 2016 at 12:03 AM, Timothy Arceri  abora.com> wrote:
> > From: Thomas Helland 
> > 
> > This pass detects induction variables and calculates the
> > trip count of loops to be used for loop unrolling.
> > 
> > I've removed support for float induction values for now, for the
> > simple reason that they don't appear in my shader-db collection,
> > and so I don't see it as common enough that we want to pollute the
> > pass with this in the initial version.
> > 
> > V2: Rebase, adapt to removal of function overloads
> > 
> > V3: (Timothy Arceri)
> >  - don't try to find trip count if loop terminator conditional is a
> > phi
> >  - fix trip count for do-while loops
> >  - replace conditional type != alu assert with return
> >  - disable unrolling of loops with continues
> >  - multiple fixes to memory allocation, stop leaking and don't
> > destroy
> >    structs we want to use for unrolling.
> >  - fix iteration count bugs when induction var not on RHS of
> > condition
> >  - add FIXME for && conditions
> >  - calculate trip count for unsigned induction/limit vars
> > 
> > V4:
> > - count instructions in a loop
> > - set the limiting_terminator even if we can't find the trip count
> > for
> >  all terminators. This is needed for complex unrolling where we
> > handle
> >  2 terminators and the trip count is unknown for one of them.
> > - restruct structs so we don't keep information not required after
> >  analysis and remove dead fields.
> > - force unrolling in some cases as per the rules in the GLSL IR
> > pass
> > ---
> >  src/compiler/Makefile.sources       |    2 +
> >  src/compiler/nir/nir.h              |   36 +-
> >  src/compiler/nir/nir_loop_analyze.c | 1012
> > +++
> >  src/compiler/nir/nir_metadata.c     |    8 +-
> >  4 files changed, 1056 insertions(+), 2 deletions(-)
> >  create mode 100644 src/compiler/nir/nir_loop_analyze.c
> > 
> > diff --git a/src/compiler/Makefile.sources
> > b/src/compiler/Makefile.sources
> > index f5b4f9c..7ed26a9 100644
> > --- a/src/compiler/Makefile.sources
> > +++ b/src/compiler/Makefile.sources
> > @@ -190,6 +190,8 @@ NIR_FILES = \
> >         nir/nir_intrinsics.c \
> >         nir/nir_intrinsics.h \
> >         nir/nir_liveness.c \
> > +       nir/nir_loop_analyze.c \
> > +       nir/nir_loop_analyze.h \
> >         nir/nir_lower_alu_to_scalar.c \
> >         nir/nir_lower_atomics.c \
> >         nir/nir_lower_bitmap.c \
> > diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> > index ff7c422..49e8cd8 100644
> > --- a/src/compiler/nir/nir.h
> > +++ b/src/compiler/nir/nir.h
> > @@ -1549,9 +1549,36 @@ nir_if_last_else_node(nir_if *if_stmt)
> >  }
> > 
> >  typedef struct {
> > +   nir_if *nif;
> > +
> > +   nir_instr *conditional_instr;
> > +
> > +   struct list_head loop_terminator_link;
> > +} nir_loop_terminator;
> > +
> > +typedef struct {
> > +   /* Number of instructions in the loop */
> > +   unsigned num_instructions;
> > +
> > +   /* How many times the loop is run (if known) */
> > +   unsigned trip_count;
> > +   bool is_trip_count_known;
> 
> We could use 0 or -1 to indicate "I don't know trip count" instead of
> an extra boolean.  Not sure that it matters much.
>  
> > +
> > +   /* Unroll the loop regardless of its size */
> > +   bool force_unroll;
> 
> It seems a bit odd to have this decide to force-unroll.  This is an
> analysis pass, not a "make decisions" pass.
>  
> > +
> > +   nir_loop_terminator *limiting_terminator;
> > +
> > +   /* A list of loop_terminators terminating this loop. */
> > +   struct list_head loop_terminator_list;
> > +} nir_loop_info;
> > +
> > +typedef struct {
> >     nir_cf_node cf_node;
> > 
> >     struct exec_list body; /** < list of nir_cf_node */
> > +
> > +   nir_loop_info *info;
> >  } nir_loop;
> > 
> >  static inline nir_cf_node *
> > @@ -1576,6 +1603,7 @@ typedef enum {
> >     nir_metadata_dominance = 0x2,
> >     nir_metadata_live_ssa_defs = 0x4,
> >     nir_metadata_not_properly_reset = 0x8,
> > +   nir_metadata_loop_analysis = 0x16,
> >  } nir_metadata;
> > 
> >  typedef struct {
> > @@ -1758,6 +1786,8 @@ typedef struct nir_shader_compiler_options {
> >      * information must be inferred from the list of input
> > nir_variables.
> >      */
> >     bool use_interpolated_input_intrinsics;
> > +
> > +   unsigned max_unroll_iterations;
> >  } nir_shader_compiler_options;
> > 
> >  typedef struct nir_shader_info {
> > @@ -1962,7 +1992,7 @@ nir_loop *nir_loop_create(nir_shader
> > *shader);
> >  nir_function_impl *nir_cf_node_get_function(nir_cf_node *node);
> > 
> >  /** requests that the given pieces of metadata be generated */
> > -void nir_metadata_require(nir_function_impl *impl, nir_metadata
> > required);
> > +void nir_metadata_require(nir_function_impl *impl, nir_metadata
> > require

Re: [Mesa-dev] [PATCH 02/10] nir: Add a loop analysis pass

2016-09-16 Thread Jason Ekstrand
On Fri, Sep 16, 2016 at 5:36 PM, Connor Abbott  wrote:

> On Fri, Sep 16, 2016 at 6:25 PM, Jason Ekstrand 
> wrote:
> > On Thu, Sep 15, 2016 at 12:03 AM, Timothy Arceri
> >  wrote:
> >>
> >> From: Thomas Helland 
> >>
> >> This pass detects induction variables and calculates the
> >> trip count of loops to be used for loop unrolling.
> >>
> >> I've removed support for float induction values for now, for the
> >> simple reason that they don't appear in my shader-db collection,
> >> and so I don't see it as common enough that we want to pollute the
> >> pass with this in the initial version.
> >>
> >> V2: Rebase, adapt to removal of function overloads
> >>
> >> V3: (Timothy Arceri)
> >>  - don't try to find trip count if loop terminator conditional is a phi
> >>  - fix trip count for do-while loops
> >>  - replace conditional type != alu assert with return
> >>  - disable unrolling of loops with continues
> >>  - multiple fixes to memory allocation, stop leaking and don't destroy
> >>structs we want to use for unrolling.
> >>  - fix iteration count bugs when induction var not on RHS of condition
> >>  - add FIXME for && conditions
> >>  - calculate trip count for unsigned induction/limit vars
> >>
> >> V4:
> >> - count instructions in a loop
> >> - set the limiting_terminator even if we can't find the trip count for
> >>  all terminators. This is needed for complex unrolling where we handle
> >>  2 terminators and the trip count is unknown for one of them.
> >> - restruct structs so we don't keep information not required after
> >>  analysis and remove dead fields.
> >> - force unrolling in some cases as per the rules in the GLSL IR pass
> >> ---
> >>  src/compiler/Makefile.sources   |2 +
> >>  src/compiler/nir/nir.h  |   36 +-
> >>  src/compiler/nir/nir_loop_analyze.c | 1012
> >> +++
> >>  src/compiler/nir/nir_metadata.c |8 +-
> >>  4 files changed, 1056 insertions(+), 2 deletions(-)
> >>  create mode 100644 src/compiler/nir/nir_loop_analyze.c
> >>
> >> diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.
> sources
> >> index f5b4f9c..7ed26a9 100644
> >> --- a/src/compiler/Makefile.sources
> >> +++ b/src/compiler/Makefile.sources
> >> @@ -190,6 +190,8 @@ NIR_FILES = \
> >> nir/nir_intrinsics.c \
> >> nir/nir_intrinsics.h \
> >> nir/nir_liveness.c \
> >> +   nir/nir_loop_analyze.c \
> >> +   nir/nir_loop_analyze.h \
> >> nir/nir_lower_alu_to_scalar.c \
> >> nir/nir_lower_atomics.c \
> >> nir/nir_lower_bitmap.c \
> >> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> >> index ff7c422..49e8cd8 100644
> >> --- a/src/compiler/nir/nir.h
> >> +++ b/src/compiler/nir/nir.h
> >> @@ -1549,9 +1549,36 @@ nir_if_last_else_node(nir_if *if_stmt)
> >>  }
> >>
> >>  typedef struct {
> >> +   nir_if *nif;
> >> +
> >> +   nir_instr *conditional_instr;
> >> +
> >> +   struct list_head loop_terminator_link;
> >> +} nir_loop_terminator;
> >> +
> >> +typedef struct {
> >> +   /* Number of instructions in the loop */
> >> +   unsigned num_instructions;
> >> +
> >> +   /* How many times the loop is run (if known) */
> >> +   unsigned trip_count;
> >> +   bool is_trip_count_known;
> >
> >
> > We could use 0 or -1 to indicate "I don't know trip count" instead of an
> > extra boolean.  Not sure that it matters much.
> >
> >>
> >> +
> >> +   /* Unroll the loop regardless of its size */
> >> +   bool force_unroll;
> >
> >
> > It seems a bit odd to have this decide to force-unroll.  This is an
> analysis
> > pass, not a "make decisions" pass.
> >
> >>
> >> +
> >> +   nir_loop_terminator *limiting_terminator;
> >> +
> >> +   /* A list of loop_terminators terminating this loop. */
> >> +   struct list_head loop_terminator_list;
> >> +} nir_loop_info;
> >> +
> >> +typedef struct {
> >> nir_cf_node cf_node;
> >>
> >> struct exec_list body; /** < list of nir_cf_node */
> >> +
> >> +   nir_loop_info *info;
> >>  } nir_loop;
> >>
> >>  static inline nir_cf_node *
> >> @@ -1576,6 +1603,7 @@ typedef enum {
> >> nir_metadata_dominance = 0x2,
> >> nir_metadata_live_ssa_defs = 0x4,
> >> nir_metadata_not_properly_reset = 0x8,
> >> +   nir_metadata_loop_analysis = 0x16,
> >>  } nir_metadata;
> >>
> >>  typedef struct {
> >> @@ -1758,6 +1786,8 @@ typedef struct nir_shader_compiler_options {
> >>  * information must be inferred from the list of input
> nir_variables.
> >>  */
> >> bool use_interpolated_input_intrinsics;
> >> +
> >> +   unsigned max_unroll_iterations;
> >>  } nir_shader_compiler_options;
> >>
> >>  typedef struct nir_shader_info {
> >> @@ -1962,7 +1992,7 @@ nir_loop *nir_loop_create(nir_shader *shader);
> >>  nir_function_impl *nir_cf_node_get_function(nir_cf_node *node);
> >>
> >>  /** requests that the given pieces of metadata be generated */
> >> -void nir_metadata_require(nir_function_impl *impl, nir_metadata
> >> required);
> >> +void nir_metadata_require(n

Re: [Mesa-dev] [PATCH 02/10] nir: Add a loop analysis pass

2016-09-16 Thread Connor Abbott
On Fri, Sep 16, 2016 at 6:25 PM, Jason Ekstrand  wrote:
> On Thu, Sep 15, 2016 at 12:03 AM, Timothy Arceri
>  wrote:
>>
>> From: Thomas Helland 
>>
>> This pass detects induction variables and calculates the
>> trip count of loops to be used for loop unrolling.
>>
>> I've removed support for float induction values for now, for the
>> simple reason that they don't appear in my shader-db collection,
>> and so I don't see it as common enough that we want to pollute the
>> pass with this in the initial version.
>>
>> V2: Rebase, adapt to removal of function overloads
>>
>> V3: (Timothy Arceri)
>>  - don't try to find trip count if loop terminator conditional is a phi
>>  - fix trip count for do-while loops
>>  - replace conditional type != alu assert with return
>>  - disable unrolling of loops with continues
>>  - multiple fixes to memory allocation, stop leaking and don't destroy
>>structs we want to use for unrolling.
>>  - fix iteration count bugs when induction var not on RHS of condition
>>  - add FIXME for && conditions
>>  - calculate trip count for unsigned induction/limit vars
>>
>> V4:
>> - count instructions in a loop
>> - set the limiting_terminator even if we can't find the trip count for
>>  all terminators. This is needed for complex unrolling where we handle
>>  2 terminators and the trip count is unknown for one of them.
>> - restruct structs so we don't keep information not required after
>>  analysis and remove dead fields.
>> - force unrolling in some cases as per the rules in the GLSL IR pass
>> ---
>>  src/compiler/Makefile.sources   |2 +
>>  src/compiler/nir/nir.h  |   36 +-
>>  src/compiler/nir/nir_loop_analyze.c | 1012
>> +++
>>  src/compiler/nir/nir_metadata.c |8 +-
>>  4 files changed, 1056 insertions(+), 2 deletions(-)
>>  create mode 100644 src/compiler/nir/nir_loop_analyze.c
>>
>> diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
>> index f5b4f9c..7ed26a9 100644
>> --- a/src/compiler/Makefile.sources
>> +++ b/src/compiler/Makefile.sources
>> @@ -190,6 +190,8 @@ NIR_FILES = \
>> nir/nir_intrinsics.c \
>> nir/nir_intrinsics.h \
>> nir/nir_liveness.c \
>> +   nir/nir_loop_analyze.c \
>> +   nir/nir_loop_analyze.h \
>> nir/nir_lower_alu_to_scalar.c \
>> nir/nir_lower_atomics.c \
>> nir/nir_lower_bitmap.c \
>> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
>> index ff7c422..49e8cd8 100644
>> --- a/src/compiler/nir/nir.h
>> +++ b/src/compiler/nir/nir.h
>> @@ -1549,9 +1549,36 @@ nir_if_last_else_node(nir_if *if_stmt)
>>  }
>>
>>  typedef struct {
>> +   nir_if *nif;
>> +
>> +   nir_instr *conditional_instr;
>> +
>> +   struct list_head loop_terminator_link;
>> +} nir_loop_terminator;
>> +
>> +typedef struct {
>> +   /* Number of instructions in the loop */
>> +   unsigned num_instructions;
>> +
>> +   /* How many times the loop is run (if known) */
>> +   unsigned trip_count;
>> +   bool is_trip_count_known;
>
>
> We could use 0 or -1 to indicate "I don't know trip count" instead of an
> extra boolean.  Not sure that it matters much.
>
>>
>> +
>> +   /* Unroll the loop regardless of its size */
>> +   bool force_unroll;
>
>
> It seems a bit odd to have this decide to force-unroll.  This is an analysis
> pass, not a "make decisions" pass.
>
>>
>> +
>> +   nir_loop_terminator *limiting_terminator;
>> +
>> +   /* A list of loop_terminators terminating this loop. */
>> +   struct list_head loop_terminator_list;
>> +} nir_loop_info;
>> +
>> +typedef struct {
>> nir_cf_node cf_node;
>>
>> struct exec_list body; /** < list of nir_cf_node */
>> +
>> +   nir_loop_info *info;
>>  } nir_loop;
>>
>>  static inline nir_cf_node *
>> @@ -1576,6 +1603,7 @@ typedef enum {
>> nir_metadata_dominance = 0x2,
>> nir_metadata_live_ssa_defs = 0x4,
>> nir_metadata_not_properly_reset = 0x8,
>> +   nir_metadata_loop_analysis = 0x16,
>>  } nir_metadata;
>>
>>  typedef struct {
>> @@ -1758,6 +1786,8 @@ typedef struct nir_shader_compiler_options {
>>  * information must be inferred from the list of input nir_variables.
>>  */
>> bool use_interpolated_input_intrinsics;
>> +
>> +   unsigned max_unroll_iterations;
>>  } nir_shader_compiler_options;
>>
>>  typedef struct nir_shader_info {
>> @@ -1962,7 +1992,7 @@ nir_loop *nir_loop_create(nir_shader *shader);
>>  nir_function_impl *nir_cf_node_get_function(nir_cf_node *node);
>>
>>  /** requests that the given pieces of metadata be generated */
>> -void nir_metadata_require(nir_function_impl *impl, nir_metadata
>> required);
>> +void nir_metadata_require(nir_function_impl *impl, nir_metadata required,
>> ...);
>>  /** dirties all but the preserved metadata */
>>  void nir_metadata_preserve(nir_function_impl *impl, nir_metadata
>> preserved);
>>
>> @@ -2559,6 +2589,10 @@ void nir_lower_double_pack(nir_shader *shader);
>>  bool nir_normalize_cubemap_coords(nir_shader *shader);
>>
>>  

Re: [Mesa-dev] [PATCH 02/10] nir: Add a loop analysis pass

2016-09-16 Thread Timothy Arceri
On Sat, 2016-09-17 at 09:40 +1000, Timothy Arceri wrote:
> On Fri, 2016-09-16 at 15:25 -0700, Jason Ekstrand wrote:
> > > > On Thu, Sep 15, 2016 at 12:03 AM, Timothy Arceri  wrote:
> > > > > > From: Thomas Helland 
> > 
> > 

snip

> 
> >  
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > 
+      return -1;

+

+   /* do-while loops can increment the starting value before the condition is

+    * checked. e.g.

+    *

+    *    do {

+    *        ndx++;

+    *     } while (ndx < 3);

+    *

+    * Here we check if the induction variable is used directly by the loop

+    * condition and if so we assume we need to step the initial value.

+    */

+   bool increment_before = false;

+   if (cond_alu->src[0].src.ssa == alu_def->def ||

+       cond_alu->src[1].src.ssa == alu_def->def) {

+      increment_before = true;
> > 
> > Is there a reason why this can't be handled as "trip_count + 1"?  This 
> > seems way overcomplicated.
> 
> Yes there is. We don't know that we will increment by 1 it could be by 10, 
> also if we support more opts we may have to do a mul etc.
> We could set the initial value here but I decided to keep it all in 
> get_iteration() I guess I could move this logic there also.
> 
Ingonre that I see what you are getting at but it would be trip_count -
1. That should be ok if sub is lowered as you say.
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 02/10] nir: Add a loop analysis pass

2016-09-16 Thread Timothy Arceri
On Fri, 2016-09-16 at 17:01 +0200, Erik Faye-Lund wrote:
> On Thu, Sep 15, 2016 at 9:03 AM, Timothy Arceri
>  wrote:
> > 
> > +   const int bias[] = { -1, 1, 1 };
> > +
> > +   for (unsigned i = 0; i < ARRAY_SIZE(bias); i++) {
> > +  iter_int = iter_int + bias[i];
> > +
> > +  switch (cond_op) {
> > +  case nir_op_ige:
> > +  case nir_op_ilt:
> > +  case nir_op_ieq:
> > +  case nir_op_ine:
> > + if (itest_interations(iter_int, step, limit, cond_op,
> > initial_val,
> > +   limit_rhs)) {
> > +return iter_int;
> > + }
> > + break;
> > +  case nir_op_uge:
> > +  case nir_op_ult:
> > + if (utest_interations(iter_int, step, limit, cond_op,
> > +   (uint32_t) initial_val, limit_rhs))
> > {
> > +return iter_int;
> > + }
> > + break;
> > +  default:
> > + return -1;
> > +  }
> > +   }
> 
> Can't this be easier written as:

Probably. I believe Thomas just copied this code from the GLSL IR pass.

> 
> for (int i = iter_int - 1; i <= iter_int + 1; ++i)
> {
> switch (cond_op) {
> [...]
> if (itest_interations(i, step, limit, cond_op, initial_val,
> limit_rhs))
>  return i;
> [...]
> ?
> ___
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 02/10] nir: Add a loop analysis pass

2016-09-16 Thread Jason Ekstrand
On Thu, Sep 15, 2016 at 12:03 AM, Timothy Arceri <
timothy.arc...@collabora.com> wrote:

> From: Thomas Helland 
>
> This pass detects induction variables and calculates the
> trip count of loops to be used for loop unrolling.
>
> I've removed support for float induction values for now, for the
> simple reason that they don't appear in my shader-db collection,
> and so I don't see it as common enough that we want to pollute the
> pass with this in the initial version.
>
> V2: Rebase, adapt to removal of function overloads
>
> V3: (Timothy Arceri)
>  - don't try to find trip count if loop terminator conditional is a phi
>  - fix trip count for do-while loops
>  - replace conditional type != alu assert with return
>  - disable unrolling of loops with continues
>  - multiple fixes to memory allocation, stop leaking and don't destroy
>structs we want to use for unrolling.
>  - fix iteration count bugs when induction var not on RHS of condition
>  - add FIXME for && conditions
>  - calculate trip count for unsigned induction/limit vars
>
> V4:
> - count instructions in a loop
> - set the limiting_terminator even if we can't find the trip count for
>  all terminators. This is needed for complex unrolling where we handle
>  2 terminators and the trip count is unknown for one of them.
> - restruct structs so we don't keep information not required after
>  analysis and remove dead fields.
> - force unrolling in some cases as per the rules in the GLSL IR pass
> ---
>  src/compiler/Makefile.sources   |2 +
>  src/compiler/nir/nir.h  |   36 +-
>  src/compiler/nir/nir_loop_analyze.c | 1012 ++
> +
>  src/compiler/nir/nir_metadata.c |8 +-
>  4 files changed, 1056 insertions(+), 2 deletions(-)
>  create mode 100644 src/compiler/nir/nir_loop_analyze.c
>
> diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
> index f5b4f9c..7ed26a9 100644
> --- a/src/compiler/Makefile.sources
> +++ b/src/compiler/Makefile.sources
> @@ -190,6 +190,8 @@ NIR_FILES = \
> nir/nir_intrinsics.c \
> nir/nir_intrinsics.h \
> nir/nir_liveness.c \
> +   nir/nir_loop_analyze.c \
> +   nir/nir_loop_analyze.h \
> nir/nir_lower_alu_to_scalar.c \
> nir/nir_lower_atomics.c \
> nir/nir_lower_bitmap.c \
> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> index ff7c422..49e8cd8 100644
> --- a/src/compiler/nir/nir.h
> +++ b/src/compiler/nir/nir.h
> @@ -1549,9 +1549,36 @@ nir_if_last_else_node(nir_if *if_stmt)
>  }
>
>  typedef struct {
> +   nir_if *nif;
> +
> +   nir_instr *conditional_instr;
> +
> +   struct list_head loop_terminator_link;
> +} nir_loop_terminator;
> +
> +typedef struct {
> +   /* Number of instructions in the loop */
> +   unsigned num_instructions;
> +
> +   /* How many times the loop is run (if known) */
> +   unsigned trip_count;
> +   bool is_trip_count_known;
>

We could use 0 or -1 to indicate "I don't know trip count" instead of an
extra boolean.  Not sure that it matters much.


> +
> +   /* Unroll the loop regardless of its size */
> +   bool force_unroll;
>

It seems a bit odd to have this decide to force-unroll.  This is an
analysis pass, not a "make decisions" pass.


> +
> +   nir_loop_terminator *limiting_terminator;
> +
> +   /* A list of loop_terminators terminating this loop. */
> +   struct list_head loop_terminator_list;
> +} nir_loop_info;
> +
> +typedef struct {
> nir_cf_node cf_node;
>
> struct exec_list body; /** < list of nir_cf_node */
> +
> +   nir_loop_info *info;
>  } nir_loop;
>
>  static inline nir_cf_node *
> @@ -1576,6 +1603,7 @@ typedef enum {
> nir_metadata_dominance = 0x2,
> nir_metadata_live_ssa_defs = 0x4,
> nir_metadata_not_properly_reset = 0x8,
> +   nir_metadata_loop_analysis = 0x16,
>  } nir_metadata;
>
>  typedef struct {
> @@ -1758,6 +1786,8 @@ typedef struct nir_shader_compiler_options {
>  * information must be inferred from the list of input nir_variables.
>  */
> bool use_interpolated_input_intrinsics;
> +
> +   unsigned max_unroll_iterations;
>  } nir_shader_compiler_options;
>
>  typedef struct nir_shader_info {
> @@ -1962,7 +1992,7 @@ nir_loop *nir_loop_create(nir_shader *shader);
>  nir_function_impl *nir_cf_node_get_function(nir_cf_node *node);
>
>  /** requests that the given pieces of metadata be generated */
> -void nir_metadata_require(nir_function_impl *impl, nir_metadata
> required);
> +void nir_metadata_require(nir_function_impl *impl, nir_metadata
> required, ...);
>  /** dirties all but the preserved metadata */
>  void nir_metadata_preserve(nir_function_impl *impl, nir_metadata
> preserved);
>
> @@ -2559,6 +2589,10 @@ void nir_lower_double_pack(nir_shader *shader);
>  bool nir_normalize_cubemap_coords(nir_shader *shader);
>
>  void nir_live_ssa_defs_impl(nir_function_impl *impl);
> +
> +void nir_loop_analyze_impl(nir_function_impl *impl,
> +   nir_variable_mode indirect_mas

Re: [Mesa-dev] [PATCH 02/10] nir: Add a loop analysis pass

2016-09-16 Thread Erik Faye-Lund
On Thu, Sep 15, 2016 at 9:03 AM, Timothy Arceri
 wrote:
> +   const int bias[] = { -1, 1, 1 };
> +
> +   for (unsigned i = 0; i < ARRAY_SIZE(bias); i++) {
> +  iter_int = iter_int + bias[i];
> +
> +  switch (cond_op) {
> +  case nir_op_ige:
> +  case nir_op_ilt:
> +  case nir_op_ieq:
> +  case nir_op_ine:
> + if (itest_interations(iter_int, step, limit, cond_op, initial_val,
> +   limit_rhs)) {
> +return iter_int;
> + }
> + break;
> +  case nir_op_uge:
> +  case nir_op_ult:
> + if (utest_interations(iter_int, step, limit, cond_op,
> +   (uint32_t) initial_val, limit_rhs)) {
> +return iter_int;
> + }
> + break;
> +  default:
> + return -1;
> +  }
> +   }

Can't this be easier written as:

for (int i = iter_int - 1; i <= iter_int + 1; ++i)
{
switch (cond_op) {
[...]
if (itest_interations(i, step, limit, cond_op, initial_val, limit_rhs))
 return i;
[...]
?
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev