From patchwork Mon Nov 9 19:57:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Jambor X-Patchwork-Id: 1397085 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=suse.cz Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CVMGY39fNz9sRK for ; Tue, 10 Nov 2020 06:57:25 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 877AA388A409; Mon, 9 Nov 2020 19:57:23 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id C19513887025 for ; Mon, 9 Nov 2020 19:57:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C19513887025 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.cz Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mjambor@suse.cz X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id B4AB1ABD6 for ; Mon, 9 Nov 2020 19:57:19 +0000 (UTC) From: Martin Jambor To: GCC Patches Subject: [PATCH 1/2] cfgloop: Extend loop iteration macros to loop only over sub-loops User-Agent: Notmuch/0.31 (https://notmuchmail.org) Emacs/26.3 (x86_64-suse-linux-gnu) Date: Mon, 09 Nov 2020 20:57:19 +0100 Message-ID: MIME-Version: 1.0 X-Spam-Status: No, score=-3039.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Biener Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" 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 * 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 ())