From patchwork Thu Nov 11 14:01:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 47465 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C0989385AC22 for ; Thu, 11 Nov 2021 14:02:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C0989385AC22 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1636639351; bh=o/zjlS79eRkRqqJvqpkp4TSbGmc9RVcIKsvIJ3tAepA=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=s9xqX9B7jLa0EB2y7CIP5aUlDUTkOVMM3zhuabfIRPpbShPMjLg5g3p/hG5CzI7o+ exvluJAC65Xk+p6Wtk9B7lNdD1QZDbZMwzCJm51s4UT2ciqli1cM4octp4E8+0yq8N gS6om9xl2ynejU54bEYiIY5Bv7wkjMtzvVE/zgfw= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id 72A2D3858014 for ; Thu, 11 Nov 2021 14:01:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 72A2D3858014 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 47D601F770 for ; Thu, 11 Nov 2021 14:01:03 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 2DC2413DBA for ; Thu, 11 Nov 2021 14:01:03 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id vK5vCR8ijWHGQAAAMHmgww (envelope-from ) for ; Thu, 11 Nov 2021 14:01:03 +0000 Date: Thu, 11 Nov 2021 15:01:02 +0100 (CET) To: gcc-patches@gcc.gnu.org Subject: [PATCH] tree-optimization/103188 - avoid running ranger on not-up-to-date SSA Message-ID: <125s9n8o-7n3-69s8-1qqq-3536995q64p@fhfr.qr> MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: , X-Patchwork-Original-From: Richard Biener via Gcc-patches From: Richard Biener Reply-To: Richard Biener Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" The following splits loop header copying into an analysis phase that uses ranger and a transform phase that can do without to avoid running ranger on IL that has SSA form not updated. Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. 2021-11-11 Richard Biener PR tree-optimization/103188 * tree-ssa-loop-ch.c (should_duplicate_loop_header_p): Remove query parameter, split out check for size optimization. (ch_base::m_ranger, cb_base::m_query): Remove. (ch_base::copy_headers): Split processing loop into analysis around which we allocate and use ranger and transform where we do not. (pass_ch::execute): Do not allocate/free ranger here. (pass_ch_vect::execute): Likewise. * gcc.dg/torture/pr103188.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr103188.c | 38 +++++++++++++ gcc/tree-ssa-loop-ch.c | 72 ++++++++++++++----------- 2 files changed, 78 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr103188.c diff --git a/gcc/testsuite/gcc.dg/torture/pr103188.c b/gcc/testsuite/gcc.dg/torture/pr103188.c new file mode 100644 index 00000000000..0412f6f9b79 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr103188.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ + +int a, b, c, d = 10, e = 1, f, g, h, i; +int main() +{ + int j = -1; +k: + h = c; +l: + c = ~c; + if (e) + m: + a = 0; + if (j > 1) + goto m; + if (!e) + goto l; + if (c) + goto p; +n: + goto m; +o: + if (f) { + if (g) + goto k; + j = 0; + p: + if (d) + goto o; + goto n; + } + if (i) + goto l; + for (; a < 1; a++) + while (a > d) + b++; + return 0; +} diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index c7d86d751d4..0cee38159fb 100644 --- a/gcc/tree-ssa-loop-ch.c +++ b/gcc/tree-ssa-loop-ch.c @@ -69,26 +69,12 @@ entry_loop_condition_is_static (class loop *l, path_range_query *query) static bool should_duplicate_loop_header_p (basic_block header, class loop *loop, - int *limit, path_range_query *query) + int *limit) { gimple_stmt_iterator bsi; gcc_assert (!header->aux); - /* Avoid loop header copying when optimizing for size unless we can - determine that the loop condition is static in the first - iteration. */ - if (optimize_loop_for_size_p (loop) - && !loop->force_vectorize - && !entry_loop_condition_is_static (loop, query)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - " Not duplicating bb %i: optimizing for size.\n", - header->index); - return false; - } - gcc_assert (EDGE_COUNT (header->succs) > 0); if (single_succ_p (header)) { @@ -223,8 +209,6 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, return false; } - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Will duplicate bb %i\n", header->index); return true; } @@ -289,9 +273,6 @@ class ch_base : public gimple_opt_pass /* Return true to copy headers of LOOP or false to skip. */ virtual bool process_loop_p (class loop *loop) = 0; - - gimple_ranger *m_ranger = NULL; - path_range_query *m_query = NULL; }; const pass_data pass_data_ch = @@ -386,8 +367,11 @@ ch_base::copy_headers (function *fun) copied_bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun)); bbs_size = n_basic_blocks_for_fn (fun); + auto_vec candidates; auto_vec > copied; + gimple_ranger *ranger = new gimple_ranger; + path_range_query *query = new path_range_query (*ranger, /*resolve=*/true); for (auto loop : loops_list (cfun, 0)) { int initial_limit = param_max_loop_header_insns; @@ -406,6 +390,37 @@ ch_base::copy_headers (function *fun) || !process_loop_p (loop)) continue; + /* Avoid loop header copying when optimizing for size unless we can + determine that the loop condition is static in the first + iteration. */ + if (optimize_loop_for_size_p (loop) + && !loop->force_vectorize + && !entry_loop_condition_is_static (loop, query)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Not duplicating bb %i: optimizing for size.\n", + header->index); + continue; + } + + if (should_duplicate_loop_header_p (header, loop, &remaining_limit)) + candidates.safe_push (loop); + } + /* Do not use ranger after we change the IL and not have updated SSA. */ + delete query; + delete ranger; + + for (auto loop : candidates) + { + int initial_limit = param_max_loop_header_insns; + int remaining_limit = initial_limit; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "Copying headers of loop %i\n", loop->num); + + header = loop->header; + /* Iterate the header copying up to limit; this takes care of the cases like while (a && b) {...}, where we want to have both of the conditions copied. TODO -- handle while (a || b) - like cases, by not requiring @@ -414,9 +429,11 @@ ch_base::copy_headers (function *fun) exit = NULL; n_bbs = 0; - while (should_duplicate_loop_header_p (header, loop, &remaining_limit, - m_query)) + while (should_duplicate_loop_header_p (header, loop, &remaining_limit)) { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Will duplicate bb %i\n", header->index); + /* Find a successor of header that is inside a loop; i.e. the new header after the condition is copied. */ if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest)) @@ -552,13 +569,9 @@ pass_ch::execute (function *fun) loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES | LOOPS_HAVE_RECORDED_EXITS); - m_ranger = new gimple_ranger; - m_query = new path_range_query (*m_ranger, /*resolve=*/true); unsigned int res = copy_headers (fun); - delete m_query; - delete m_ranger; loop_optimizer_finalize (); return res; } @@ -570,12 +583,7 @@ pass_ch::execute (function *fun) unsigned int pass_ch_vect::execute (function *fun) { - m_ranger = new gimple_ranger; - m_query = new path_range_query (*m_ranger, /*resolve=*/true); - unsigned int res = copy_headers (fun); - delete m_query; - delete m_ranger; - return res; + return copy_headers (fun); } /* Apply header copying according to a very simple test of do-while shape. */