From patchwork Tue Dec 30 11:37:49 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 424620 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 5E93214009B for ; Tue, 30 Dec 2014 22:38:05 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=sok3DURz0Gi5OanZc1QCsJBXx8MV6Q6vQfkN6OBE0klJIiKCoaTqy qElENA5nI/blArUhbgZJ+I1ArJvXlx8O39+nj1cHtOpTTwe/6uO2wnYIzXPyeRe/ oLNqA5PJdNRHJksC+i0ovDjaFGkVFlDPpnPYUXOfE+q0mjnGKlCJVc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=1hB0oy+JHbBDEBLbnIYXKxTi4Sk=; b=FvGO690sKF/fTRGOOGm4 SWkz40iijPhfh6lPgUx6QMJe/Z+u+/Q8csXizZigTTMs00XQRTET2UMneDByv8eD 9jddt7QxDSkVAtTtYgZ2Wugv4grcaP7W6TUrxb6V7/RbqmjItmWUYHKkRfzaVXll QkpJ5Qz7HmTnn9EbxnRJboI= Received: (qmail 3815 invoked by alias); 30 Dec 2014 11:37:57 -0000 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 Received: (qmail 3800 invoked by uid 89); 30 Dec 2014 11:37:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 30 Dec 2014 11:37:54 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id F054154160B; Tue, 30 Dec 2014 12:37:49 +0100 (CET) Date: Tue, 30 Dec 2014 12:37:49 +0100 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Strenghten early inliner analysis Message-ID: <20141230113749.GB13958@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Hi, this patch enables inline predicates for early inlining, too. This is easy to do because we do have call stmt around and know if parameters are constants. Bootstrapped/regtested x86_64-linux, comitted. Honza * ipa-inline-analyssi.c (edge_set_predicate): Reset size/time when target is UNREACHABLE. (evaluate_properties_for_edge): If call statemet is available, use it to determine compile time constants. (estimate_function_body_sizes): Enable predicates for early inliner. (estimate_calls_size_and_time): Speedup. (inline_merge_summary): Evaluate properties for early inliner, too. * gcc.dg/ipa/inline-7.c: New testcase. =================================================================== --- ipa-inline-analysis.c (revision 219107) +++ ipa-inline-analysis.c (working copy) @@ -770,6 +770,8 @@ edge_set_predicate (struct cgraph_edge * e->redirect_callee (cgraph_node::get_create (builtin_decl_implicit (BUILT_IN_UNREACHABLE))); e->inline_failed = CIF_UNREACHABLE; + es->call_stmt_size = 0; + es->call_stmt_time = 0; if (callee) callee->remove_symbol_and_inline_clones (); } @@ -940,6 +942,14 @@ evaluate_properties_for_edge (struct cgr { struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i); tree cst = ipa_value_from_jfunc (parms_info, jf); + + if (!cst && e->call_stmt + && i < (int)gimple_call_num_args (e->call_stmt)) + { + cst = gimple_call_arg (e->call_stmt, i); + if (!is_gimple_min_invariant (cst)) + cst = NULL; + } if (cst) { gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO); @@ -958,6 +968,22 @@ evaluate_properties_for_edge (struct cgr known_aggs[i] = &jf->agg; } } + else if (e->call_stmt && !e->call_stmt_cannot_inline_p + && ((clause_ptr && info->conds) || known_vals_ptr)) + { + int i, count = (int)gimple_call_num_args (e->call_stmt); + + if (count && (info->conds || known_vals_ptr)) + known_vals.safe_grow_cleared (count); + for (i = 0; i < count; i++) + { + tree cst = gimple_call_arg (e->call_stmt, i); + if (!is_gimple_min_invariant (cst)) + cst = NULL; + if (cst) + known_vals[i] = cst; + } + } if (clause_ptr) *clause_ptr = evaluate_conditions_for_known_args (callee, inline_p, @@ -2464,10 +2490,22 @@ estimate_function_body_sizes (struct cgr info->conds = NULL; info->entry = NULL; - if (opt_for_fn (node->decl, optimize) && !early) + /* When optimizing and analyzing for IPA inliner, initialize loop optimizer + so we can produce proper inline hints. + + When optimizing and analyzing for early inliner, initialize node params + so we can produce correct BB predicates. */ + + if (opt_for_fn (node->decl, optimize)) { calculate_dominance_info (CDI_DOMINATORS); - loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS); + if (!early) + loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS); + else + { + ipa_check_create_node_params (); + ipa_initialize_node_params (node); + } if (ipa_node_params_sum) { @@ -2704,7 +2742,7 @@ estimate_function_body_sizes (struct cgr time = MAX_TIME; free (order); - if (!early && nonconstant_names.exists ()) + if (nonconstant_names.exists () && !early) { struct loop *loop; predicate loop_iterations = true_predicate (); @@ -2809,9 +2847,12 @@ estimate_function_body_sizes (struct cgr inline_summaries->get (node)->self_time = time; inline_summaries->get (node)->self_size = size; nonconstant_names.release (); - if (opt_for_fn (node->decl, optimize) && !early) + if (opt_for_fn (node->decl, optimize)) { - loop_optimizer_finalize (); + if (!early) + loop_optimizer_finalize (); + else + ipa_free_all_node_params (); free_dominance_info (CDI_DOMINATORS); } if (dump_file) @@ -3062,6 +3103,13 @@ estimate_calls_size_and_time (struct cgr for (e = node->callees; e; e = e->next_callee) { struct inline_edge_summary *es = inline_edge_summary (e); + + /* Do not care about zero sized builtins. */ + if (e->inline_failed && !es->call_stmt_size) + { + gcc_checking_assert (!es->call_stmt_time); + continue; + } if (!es->predicate || evaluate_predicate (es->predicate, possible_truths)) { @@ -3522,13 +3570,14 @@ inline_merge_summary (struct cgraph_edge else toplev_predicate = true_predicate (); + if (callee_info->conds) + evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL); if (ipa_node_params_sum && callee_info->conds) { struct ipa_edge_args *args = IPA_EDGE_REF (edge); int count = ipa_get_cs_argument_count (args); int i; - evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL); if (count) { operand_map.safe_grow_cleared (count); Index: testsuite/gcc.dg/ipa/inline-7.c =================================================================== --- testsuite/gcc.dg/ipa/inline-7.c (revision 0) +++ testsuite/gcc.dg/ipa/inline-7.c (revision 0) @@ -0,0 +1,25 @@ +/* Check that early inliner works out that a is empty of parameter 0. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-einline -fno-partial-inlining" } */ +void t(void); +int a (int b) +{ + if (!b) + { + t(); + t(); + t(); + t(); + t(); + t(); + t(); + } +} +void +m() +{ + a(1); + a(0); +} +/* { dg-final { scan-tree-dump-times "Inlining a into m" 1 "einline" } } */ +/* { dg-final { cleanup-tree-dump "einline" } } */