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?

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 ())
 
-- 
2.29.2

Reply via email to