From patchwork Thu Aug 13 16:34:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 1344332 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=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (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 4BSBxr21C7z9sTF for ; Fri, 14 Aug 2020 02:35:12 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7018C384402C; Thu, 13 Aug 2020 16:35:09 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa3.mentor.iphmx.com (esa3.mentor.iphmx.com [68.232.137.180]) by sourceware.org (Postfix) with ESMTPS id 5FFC43850404 for ; Thu, 13 Aug 2020 16:35:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 5FFC43850404 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=Sandra_Loosemore@mentor.com IronPort-SDR: esusb4AvGepFO82JVNTl1Oya1jLFXpmESf1JWkL8Lr050EjRVxRd9riQciFzLTPhLKr3OM1vUJ BdUc/2pT3b07cLDsEw5TUrjb3WSOzWbBEsYOG6ml6p072PZP297idf6M1WcffwkcWnCiIQ3lxa PYX3oTB1Pm2vmuuRUeNdFHPzxW1fBxaGx8RVC8I5vxuZMv1fNH/4LBMZsdO3gj9Sj2DgjNN1tD ofNe67l5yapEaIzmh/Dlqywz8Cl6rjg3WziFCSGSGvrx9josgB1QHO6AksWSX8UXy/PHQ4A/Qb 9R8= X-IronPort-AV: E=Sophos;i="5.76,308,1592899200"; d="scan'208";a="51877670" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa3.mentor.iphmx.com with ESMTP; 13 Aug 2020 08:35:05 -0800 IronPort-SDR: pGWAgl0jbxcgcTW4IJnCLB9CctmKixd4TXUNW/mTByVFzQB+JJob1P8LDvEjY1f7PuGPJuyXgb 3WqZhx8feQZ2uJ2Od8tAizHfzjp3TfTvId5UqIbBsMvstRd7BfSPcxjb2BiCNYCg02oNUjMzyo jC6OHx5tmAom53jy+rDywd+elmGBB+iKsQO24X2XjK0hIXuiWLNZIRHtKErzaDQePGCoG2Ozo8 FTjxczSYY1guGoXn+46VF7WL6S7XhUxKWwH20PcbZUHw0xGfS55Ejz0G+sGnOtPBknA30xGzqF HRk= From: Sandra Loosemore To: Subject: [PATCH V2 2/4] Use C-style loop lowering instead of C++-style. Date: Thu, 13 Aug 2020 10:34:30 -0600 Message-ID: <20200813163432.1067-3-sandra@codesourcery.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200813163432.1067-1-sandra@codesourcery.com> References: <20200813163432.1067-1-sandra@codesourcery.com> MIME-Version: 1.0 X-ClientProxiedBy: SVR-ORW-MBX-09.mgc.mentorg.com (147.34.90.209) To svr-orw-mbx-03.mgc.mentorg.com (147.34.90.203) X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, 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: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The C and C++ front ends used to use the same strategy of lowering loops to gotos with the end test canonicalized to the bottom of the loop. In 2014 the C++ front end was changed to emit LOOP_EXPRs instead (commit 1a45860e7757ee054f6bf98bee4ebe5c661dfb90). As part of the unification of the C and C++ loop handling, it's desirable to use the same lowering strategy for both languages. Applying the C++ strategy to C caused a number of regressions in C optimization tests, related to flipping the sense of the COND_EXPR for the exit test and changes in block ordering in the output code. Many of these regressions just require updating regexps in the test cases but a few appear to be genuine optimization failures. Since it appears the optimizers handle the C code better than C++ code, let's go back to using the C strategy for both languages. The rationale for the 2014 C++ patch (support for constexpr evaluation) has been solved in other ways meanwhile. 2020-08-12 Sandra Loosemore gcc/c-family/ * c-gimplify.c (genericize_c_loop): Rewrite to match c_finish_loop in c-typeck.c. --- gcc/c-family/c-gimplify.c | 110 ++++++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 48 deletions(-) diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c index db930fc..8b326c9 100644 --- a/gcc/c-family/c-gimplify.c +++ b/gcc/c-family/c-gimplify.c @@ -217,9 +217,10 @@ genericize_c_loop (tree *stmt_p, location_t start_locus, tree cond, tree body, void *data, walk_tree_fn func, walk_tree_lh lh) { tree blab, clab; - tree exit = NULL; + tree entry = NULL, exit = NULL, t; tree stmt_list = NULL; - tree debug_begin = NULL; + location_t cond_locus = expr_loc_or_loc (cond, start_locus); + location_t incr_locus = expr_loc_or_loc (incr, start_locus); protected_set_expr_location_if_unset (incr, start_locus); @@ -232,35 +233,68 @@ genericize_c_loop (tree *stmt_p, location_t start_locus, tree cond, tree body, walk_tree_1 (&body, func, data, NULL, lh); *walk_subtrees = 0; - if (MAY_HAVE_DEBUG_MARKER_STMTS - && (!cond || !integer_zerop (cond))) + /* If condition is zero don't generate a loop construct. */ + if (cond && integer_zerop (cond)) { - debug_begin = build0 (DEBUG_BEGIN_STMT, void_type_node); - SET_EXPR_LOCATION (debug_begin, expr_loc_or_loc (cond, start_locus)); + if (cond_is_first) + { + t = build1_loc (start_locus, GOTO_EXPR, void_type_node, + get_bc_label (bc_break)); + append_to_statement_list (t, &stmt_list); + } } - - if (cond && TREE_CODE (cond) != INTEGER_CST) + else { - /* If COND is constant, don't bother building an exit. If it's false, - we won't build a loop. If it's true, any exits are in the body. */ - location_t cloc = expr_loc_or_loc (cond, start_locus); - exit = build1_loc (cloc, GOTO_EXPR, void_type_node, - get_bc_label (bc_break)); - exit = fold_build3_loc (cloc, COND_EXPR, void_type_node, cond, - build_empty_stmt (cloc), exit); - } + /* Expand to gotos. */ + tree top = build1 (LABEL_EXPR, void_type_node, + create_artificial_label (start_locus)); - if (exit && cond_is_first) - { - append_to_statement_list (debug_begin, &stmt_list); - debug_begin = NULL_TREE; - append_to_statement_list (exit, &stmt_list); + /* If we have an exit condition, then we build an IF with gotos either + out of the loop, or to the top of it. If there's no exit condition, + then we just build a jump back to the top. */ + exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top)); + + if (cond && !integer_nonzerop (cond)) + { + /* Canonicalize the loop condition to the end. This means + generating a branch to the loop condition. Reuse the + continue label, if there is no incr expression. */ + if (cond_is_first) + { + if (incr) + { + entry = build1 (LABEL_EXPR, void_type_node, + create_artificial_label (start_locus)); + t = build1_loc (start_locus, GOTO_EXPR, void_type_node, + LABEL_EXPR_LABEL (entry)); + } + else + t = build1_loc (start_locus, GOTO_EXPR, void_type_node, + get_bc_label (bc_continue)); + append_to_statement_list (t, &stmt_list); + } + + t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break)); + exit = fold_build3_loc (cond_locus, + COND_EXPR, void_type_node, cond, exit, t); + } + else + { + /* For the backward-goto's location of an unconditional loop + use the beginning of the body, or, if there is none, the + top of the loop. */ + location_t loc = expr_loc_or_loc (expr_first (body), + start_locus); + SET_EXPR_LOCATION (exit, loc); + } + append_to_statement_list (top, &stmt_list); } + append_to_statement_list (body, &stmt_list); finish_bc_block (&stmt_list, bc_continue, clab); if (incr) { - if (MAY_HAVE_DEBUG_MARKER_STMTS) + if (MAY_HAVE_DEBUG_MARKER_STMTS && incr_locus != UNKNOWN_LOCATION) { tree d = build0 (DEBUG_BEGIN_STMT, void_type_node); SET_EXPR_LOCATION (d, expr_loc_or_loc (incr, start_locus)); @@ -268,35 +302,15 @@ genericize_c_loop (tree *stmt_p, location_t start_locus, tree cond, tree body, } append_to_statement_list (incr, &stmt_list); } - append_to_statement_list (debug_begin, &stmt_list); - if (exit && !cond_is_first) - append_to_statement_list (exit, &stmt_list); + append_to_statement_list (entry, &stmt_list); - if (!stmt_list) - stmt_list = build_empty_stmt (start_locus); - - tree loop; - if (cond && integer_zerop (cond)) + if (MAY_HAVE_DEBUG_MARKER_STMTS && cond_locus != UNKNOWN_LOCATION) { - if (cond_is_first) - loop = fold_build3_loc (start_locus, COND_EXPR, - void_type_node, cond, stmt_list, - build_empty_stmt (start_locus)); - else - loop = stmt_list; - } - else - { - location_t loc = start_locus; - if (!cond || integer_nonzerop (cond)) - loc = EXPR_LOCATION (expr_first (body)); - if (loc == UNKNOWN_LOCATION) - loc = start_locus; - loop = build1_loc (loc, LOOP_EXPR, void_type_node, stmt_list); + tree d = build0 (DEBUG_BEGIN_STMT, void_type_node); + SET_EXPR_LOCATION (d, cond_locus); + append_to_statement_list (d, &stmt_list); } - - stmt_list = NULL; - append_to_statement_list (loop, &stmt_list); + append_to_statement_list (exit, &stmt_list); finish_bc_block (&stmt_list, bc_break, blab); if (!stmt_list) stmt_list = build_empty_stmt (start_locus);