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