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