From patchwork Tue Sep 27 14:42:41 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 116614 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 3B511B6F68 for ; Wed, 28 Sep 2011 00:43:15 +1000 (EST) Received: (qmail 29492 invoked by alias); 27 Sep 2011 14:43:14 -0000 Received: (qmail 29474 invoked by uid 22791); 27 Sep 2011 14:43:12 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, TW_TM X-Spam-Check-By: sourceware.org Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 27 Sep 2011 14:42:42 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 6D28F9AC81D; Tue, 27 Sep 2011 16:42:41 +0200 (CEST) Date: Tue, 27 Sep 2011 16:42:41 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Make ipa-inline-analysis to track parameters passed by reference again Message-ID: <20110927144241.GE21364@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, it has turned out that I was bit too optimistic in my expectations that improved ipa-inline-analysis on scalar parameters will be enough to solve needs of tramp3d. In tramp3d as in many of C++ programs most code is passed by reference and while I have some patches in this area, the tracking is difficult by lack of jump functions that is something Martin promise only after GCC 4.7. This patch makes ipa-inline-analysis to guess again that param->field loads will be optimized away with 50% probability. This recovers most of tramp3d performance (not quite all). While constructin gtestcase for this I also noticed that we don't really handle returns of structures in the cases NRV is not happening. This is added as TODO. Bootstrapped/regtested x86_64-linux, will commit it shortly. * gcc.dg/ipa/inline-5.c: New testcase. * ipa-inline-analysis.c (eliminated_by_inlining_prob): Handle parameters passed by reference; handle loads from non-SSA scalars and update comments. Index: testsuite/gcc.dg/ipa/inline-5.c =================================================================== --- testsuite/gcc.dg/ipa/inline-5.c (revision 0) +++ testsuite/gcc.dg/ipa/inline-5.c (revision 0) @@ -0,0 +1,35 @@ +/* Check statements that are eliminated by inlining. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-ipa-inline-details -fno-early-inlining -fno-partial-inlining -fno-ipa-cp" } */ +struct a {int a,b,c,d,e;}; + +void +accessfield (struct a a) +{ + t(a.a); + /* Should compile as: + tmp = a.a + Will be eliminated by inlining + t (tmp); */ + t2(&a); + t(a.a); + return; + /* Will be eliminated by inlining */ +} +void +accessreference (struct a *a) +{ + t(a->a); + /* Should compile as: + a.0_1 = a; + Will be eliminated by inlining + tmp = a.0_1->a; + 50% will be eliminated by inlining + t (tmp) */ + t2(&a); + return; + /* Will be eliminated by inlining */ +} + +/* { dg-final { scan-ipa-dump-times "Will be eliminated" 4 "inline" } } */ +/* { dg-final { scan-ipa-dump-times "50. will be eliminated" 1 "inline" } } */ Index: ipa-inline-analysis.c =================================================================== --- ipa-inline-analysis.c (revision 179205) +++ ipa-inline-analysis.c (working copy) @@ -1290,18 +1290,65 @@ eliminated_by_inlining_prob (gimple stmt if (!inner_lhs) inner_lhs = lhs; + /* Reads of parameter are expected to be free. */ if (unmodified_parm (stmt, inner_rhs)) rhs_free = true; + + /* When parameter is not SSA register because its address is taken + and it is just copied into one, the statement will be completely + free after inlining (we will copy propagate backward). */ + if (rhs_free && is_gimple_reg (lhs)) + return 2; + + /* Reads of parameters passed by reference + expected to be free (i.e. optimized out after inlining). */ + if (TREE_CODE(inner_rhs) == MEM_REF + && unmodified_parm (stmt, TREE_OPERAND (inner_rhs, 0))) + rhs_free = true; + + /* Copying parameter passed by reference into gimple register is + probably also going to copy propagate, but we can't be quite + sure. */ if (rhs_free && is_gimple_reg (lhs)) lhs_free = true; - if (((TREE_CODE (inner_lhs) == PARM_DECL - || (TREE_CODE (inner_lhs) == SSA_NAME - && SSA_NAME_IS_DEFAULT_DEF (inner_lhs) - && TREE_CODE (SSA_NAME_VAR (inner_lhs)) == PARM_DECL)) - && inner_lhs != lhs) - || TREE_CODE (inner_lhs) == RESULT_DECL - || (TREE_CODE (inner_lhs) == SSA_NAME - && TREE_CODE (SSA_NAME_VAR (inner_lhs)) == RESULT_DECL)) + + /* Writes to parameters, parameters passed by value and return value + (either dirrectly or passed via invisible reference) are free. + + TODO: We ought to handle testcase like + struct a {int a,b;}; + struct a + retrurnsturct (void) + { + struct a a ={1,2}; + return a; + } + + This translate into: + + retrurnsturct () + { + int a$b; + int a$a; + struct a a; + struct a D.2739; + + : + D.2739.a = 1; + D.2739.b = 2; + return D.2739; + + } + For that we either need to copy ipa-split logic detecting writes + to return value. */ + if (TREE_CODE (inner_lhs) == PARM_DECL + || TREE_CODE (inner_lhs) == RESULT_DECL + || (TREE_CODE(inner_lhs) == MEM_REF + && (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0)) + || (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME + && TREE_CODE (SSA_NAME_VAR + (TREE_OPERAND (inner_lhs, 0))) + == RESULT_DECL)))) lhs_free = true; if (lhs_free && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs))) @@ -1919,7 +1966,7 @@ estimate_function_body_sizes (struct cgr if (prob == 1 && dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "\t\t50%% will be eliminated by inlining\n"); if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "\t\twill eliminated by inlining\n"); + fprintf (dump_file, "\t\tWill be eliminated by inlining\n"); if (parms_info) p = and_predicates (info->conds, &bb_predicate,