[Mesa-dev] [PATCH 08/10] nir: add a loop unrolling pass

Timothy Arceri timothy.arceri at collabora.com
Thu Oct 6 03:19:19 UTC 2016


On Thu, 2016-10-06 at 13:25 +1100, Timothy Arceri wrote:

<snip>

> > > +
> > > +static void
> > > +update_remap_tables(bool is_first_iteration, struct hash_table
> > > *remap_table,
> > > +                    struct hash_table *phi_remap,
> > > +                    struct hash_table *src_before_loop,
> > > +                    struct hash_table *src_after_loop)
> > > +{
> > > +   struct hash_entry *phi_hte;
> > > +   hash_table_foreach(phi_remap, phi_hte) {
> > > +      struct hash_entry *remap_hte =
> > > +         _mesa_hash_table_search(remap_table, phi_hte->data);
> > > +
> > > +      nir_ssa_def *phi_def = (nir_ssa_def *) phi_hte->key;
> > > +      nir_ssa_def *phi_src = (nir_ssa_def *) phi_hte->data;
> > > +
> > > +      if (!remap_hte && is_first_iteration) {
> > > +         _mesa_hash_table_insert(remap_table, phi_hte->key,
> > > phi_hte->data);
> > > +         continue;
> > > +      }
> > > +
> > > +      if (is_phi_src_phi_from_loop_header(phi_def, phi_src)) {
> > > +          /* After copy propagation we can end up with phis
> > > inside
> > > loops
> > > +           * that look like this:
> > > +           *
> > > +           *    vec1 32 ssa_14 = phi block_0: ssa_9, block_4:
> > > ssa_13
> > > +           *    vec1 32 ssa_13 = phi block_0: ssa_8, block_4:
> > > ssa_12
> > > +           *    vec1 32 ssa_12 = phi block_0: ssa_7, block_4:
> > > ssa_11
> > > +           *    vec1 32 ssa_11 = phi block_0: ssa_6, block_4:
> > > ssa_14
> > > +           *
> > > +           * For each iteration of the loop we need to update
> > > the
> > > phi and
> > > +           * cloning remap tables so that we use the correct src
> > > for the
> > > +           * next iteration.
> > > +           */
> > > +          struct hash_entry *sbl_hte =
> > > +             _mesa_hash_table_search(src_before_loop, phi_hte-
> > > > 
> > > > data);
> > > +          _mesa_hash_table_insert(remap_table, phi_hte->key,
> > > sbl_hte->data);
> > > +
> > > +          struct hash_entry *sal_hte =
> > > +             _mesa_hash_table_search(src_after_loop, phi_hte-
> > > > 
> > > > data);
> > > +          phi_hte->data = sal_hte->data;
> > > +      } else if (remap_hte) {
> > > +          _mesa_hash_table_insert(remap_table, phi_hte->key,
> > > remap_hte->data);
> > > +      }
> > 
> > Hrm... I understand the problem but I would have thought we could
> > have done it with fewer remap tables... 
> >  My naeve idea would be to do
> > as follows:
> > 
> > In create_remap_tables, populate the remap table with phi_dst ->
> > phi_src where phi_src is the source with pred == block_before_loop.
> > 
> > In update_remap_tables, populate the remap table with phi_dst ->
> > remap(phi_src) where phi_src is the soure with pred ==
> > continue_block
> > 
> > Am I just over-simplifying things here?
> 
> I believe you are. The remap table is updated by the cloning process
> our job here is to simply make sure it is in the right state before
> we
> do the next clone. The key thing is that we are always cloning the
> original header/body (were are not cloning the previous clone).
> 
> So the above code is acting more as a reset, or initialisation of the
> remap table for the next iteration of the loop (although we want to
> keep what it already contains).
> 
> Essentially the code is doing what you are suggesting you are just
> leaving out the part where updating phi_src with the source from pred
> == continue_block only works for the first iteration. For the next
> iteration we use the value already in the remap table after the
> clone,
> or the case where there is no mov i.e no clone we need to set things
> up
> manually using the src_before_loop/src_after_loop hash tables.
> 
> Does this make sense? 
> 
> It would be nice if we could distill this into an easy to follow
> comment to put on the function itself, happy for your input to help
> get
> to something that not only I understand :)
> 
> How about something like:
> 
> /*
>  * The remap_table is updated by the cloning process, our job here
> is 
>  * to simply make sure it is in the right state before we do the next
>  * clone. The key thing is that we are always cloning the original 
>  * header/body (were are not cloning the previous clone).
>  *
>  * Since the cloning process is updating the remap_table we can think
>  * of this function as acting more as a reset, or initialisation of
> the
>  * remap table for the next iteration of the loop (although we want
> to
>  * keep what it already contains).
>  *
>  * After the first iteration we use the value already in remap_table
> to
>  * update the phi_src with the new src from the previous clone, or in
>  * the case where there is no mov i.e no clone, we update the 
>  * remap_table using the src_before_loop/src_after_loop hash tables.
>  */
> 

More simply here is an explanation of the functions of each individual
table:

- remap_table: is used during cloning, and for remapping lcssa phis
after unrolling.

- phi_remap: is used to remap the remap_table each iteration so that is
can be used to clone the original loop contents by pointing ssa_defs to
the latest src from the previous clone.

- src_{after,before}_loop: are use to remap both the remap_table and
phi_remap table when copy propagation has reduce the movs to phis that
simply reorder the src each iteration.




More information about the mesa-dev mailing list