On Mon, 9 Nov 2020, Martin Jambor wrote:

> Hi,
> 
> This patch adds loop iteration macros FOR_EACH_ENCLOSED_LOOP and
> FOR_EACH_ENCLOSED_LOOP_FN which can loop only over inner loops of a
> given loop.
> 
> The patch is required for a follow-up patch which enables loop
> invariant motion to only work on a selected loop.  I have bootstrapped
> and tested the two patches on x86_64-linux and aarch64-linux.  OK for
> trunk once the follow-up patch is accepted too?

OK for trunk.

Thanks,
Richard.

> Thanks,
> 
> Martin
> 
> 
> gcc/ChangeLog:
> 
> 2020-10-29  Martin Jambor  <mjam...@suse.cz>
> 
>       * cfgloop.h (loop_iterator::loop_iterator): Add parameter to the
>       constructor, make it iterate over sub-loops if non-NULL.
>       (FOR_EACH_LOOP): Pass extra NULL to loop_iterator::loop_iterator.
>       (FOR_EACH_LOOP_FN): Likewise.
>       (FOR_EACH_ENCLOSED_LOOP): New macro.
>       (FOR_EACH_ENCLOSED_LOOP_FN): Likewise.
> ---
>  gcc/cfgloop.h | 44 ++++++++++++++++++++++++++++++++------------
>  1 file changed, 32 insertions(+), 12 deletions(-)
> 
> diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
> index d14689dc31f..e8ffa5b2964 100644
> --- a/gcc/cfgloop.h
> +++ b/gcc/cfgloop.h
> @@ -663,7 +663,7 @@ enum li_flags
>  class loop_iterator
>  {
>  public:
> -  loop_iterator (function *fn, loop_p *loop, unsigned flags);
> +  loop_iterator (function *fn, loop_p top, loop_p *loop, unsigned flags);
>  
>    inline loop_p next ();
>  
> @@ -693,8 +693,15 @@ loop_iterator::next ()
>    return NULL;
>  }
>  
> +/* Constructor to set up iteration over loops.  FN is the function in which 
> the
> +   loop tree resides.  If TOP is NULL iterate over all loops in the function,
> +   otherwise iterate only over sub-loops of TOP (including TOP).  LOOP points
> +   to the iteration pointer in the iteration.  FLAGS modify the iteration as
> +   described in enum li_flags.  */
> +
>  inline
> -loop_iterator::loop_iterator (function *fn, loop_p *loop, unsigned flags)
> +loop_iterator::loop_iterator (function *fn, loop_p top, loop_p *loop,
> +                           unsigned flags)
>  {
>    class loop *aloop;
>    unsigned i;
> @@ -716,13 +723,16 @@ loop_iterator::loop_iterator (function *fn, loop_p 
> *loop, unsigned flags)
>        for (i = 0; vec_safe_iterate (loops_for_fn (fn)->larray, i, &aloop); 
> i++)
>       if (aloop != NULL
>           && aloop->inner == NULL
> -         && aloop->num >= mn)
> +         && aloop->num >= mn
> +         && (!top || flow_loop_nested_p (top, aloop)))
>         this->to_visit.quick_push (aloop->num);
>      }
>    else if (flags & LI_FROM_INNERMOST)
>      {
> +      if (!top)
> +     top = loops_for_fn (fn)->tree_root;
>        /* Push the loops to LI->TO_VISIT in postorder.  */
> -      for (aloop = loops_for_fn (fn)->tree_root;
> +      for (aloop = top;
>          aloop->inner != NULL;
>          aloop = aloop->inner)
>       continue;
> @@ -732,15 +742,15 @@ loop_iterator::loop_iterator (function *fn, loop_p 
> *loop, unsigned flags)
>         if (aloop->num >= mn)
>           this->to_visit.quick_push (aloop->num);
>  
> -       if (aloop->next)
> +       if (aloop == top)
> +         break;
> +       else if (aloop->next)
>           {
>             for (aloop = aloop->next;
>                  aloop->inner != NULL;
>                  aloop = aloop->inner)
>               continue;
>           }
> -       else if (!loop_outer (aloop))
> -         break;
>         else
>           aloop = loop_outer (aloop);
>       }
> @@ -748,7 +758,7 @@ loop_iterator::loop_iterator (function *fn, loop_p *loop, 
> unsigned flags)
>    else
>      {
>        /* Push the loops to LI->TO_VISIT in preorder.  */
> -      aloop = loops_for_fn (fn)->tree_root;
> +      aloop = top ? top : loops_for_fn (fn)->tree_root;
>        while (1)
>       {
>         if (aloop->num >= mn)
> @@ -758,9 +768,9 @@ loop_iterator::loop_iterator (function *fn, loop_p *loop, 
> unsigned flags)
>           aloop = aloop->inner;
>         else
>           {
> -           while (aloop != NULL && aloop->next == NULL)
> +           while (aloop != top && aloop->next == NULL)
>               aloop = loop_outer (aloop);
> -           if (aloop == NULL)
> +           if (aloop == top)
>               break;
>             aloop = aloop->next;
>           }
> @@ -771,12 +781,22 @@ loop_iterator::loop_iterator (function *fn, loop_p 
> *loop, unsigned flags)
>  }
>  
>  #define FOR_EACH_LOOP(LOOP, FLAGS) \
> -  for (loop_iterator li(cfun, &(LOOP), FLAGS); \
> +  for (loop_iterator li(cfun, NULL, &(LOOP), FLAGS); \
>         (LOOP); \
>         (LOOP) = li.next ())
>  
>  #define FOR_EACH_LOOP_FN(FN, LOOP, FLAGS) \
> -  for (loop_iterator li(FN, &(LOOP), FLAGS); \
> +  for (loop_iterator li(FN, NULL, &(LOOP), FLAGS);   \
> +       (LOOP); \
> +       (LOOP) = li.next ())
> +
> +#define FOR_EACH_ENCLOSED_LOOP(TOP, LOOP, FLAGS)             \
> +  for (loop_iterator li(cfun, TOP, &(LOOP), FLAGS);  \
> +       (LOOP); \
> +       (LOOP) = li.next ())
> +
> +#define FOR_EACH_ENCLOSED_LOOP_FN(FN, TOP, LOOP, FLAGS) \
> +  for (loop_iterator li(FN, TOP, &(LOOP), FLAGS);    \
>         (LOOP); \
>         (LOOP) = li.next ())
>  
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imend

Reply via email to