From patchwork Wed Oct 21 23:47:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 1385832 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=ucw.cz 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 4CGnGS4rSfz9sSn for ; Thu, 22 Oct 2020 10:47:11 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 41871385042F; Wed, 21 Oct 2020 23:47:08 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id E46933857019 for ; Wed, 21 Oct 2020 23:47:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E46933857019 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: sourceware.org; spf=none smtp.mailfrom=hubicka@kam.mff.cuni.cz Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 5A2AA2811BC; Thu, 22 Oct 2020 01:47:03 +0200 (CEST) Date: Thu, 22 Oct 2020 01:47:03 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Increase weight of builtin_constant_p hint Message-ID: <20201021234703.GC41258@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-13.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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" hi, this patch makes builtin_constant_p hint to combine with other loop hints we already support. This is necessary for it to be realy effective since most such functions will already get big_speedup hint. Bootstrapped/regtested x86_64-linux, comitted. gcc/ChangeLog: 2020-10-22 Jan Hubicka PR ipa/97445 * ipa-inline.c (inline_insns_single): Add hint2 parameter. (inline_insns_auto): Add hint2 parameter. (can_inline_edge_by_limits_p): Update. (want_inline_small_function_p): Update. (wrapper_heuristics_may_apply): Update. diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index bc846eabb58..9555c607a3d 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -398,26 +398,42 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, return inlinable; } -/* Return inlining_insns_single limit for function N. If HINT is true +/* Return inlining_insns_single limit for function N. If HINT or HINT2 is true scale up the bound. */ static int -inline_insns_single (cgraph_node *n, bool hint) +inline_insns_single (cgraph_node *n, bool hint, bool hint2) { - if (hint) + if (hint && hint2) + { + int64_t spd = opt_for_fn (n->decl, param_inline_heuristics_hint_percent); + spd = spd * spd; + if (spd > 100000) + spd = 100000; + return opt_for_fn (n->decl, param_max_inline_insns_single) * spd / 100; + } + if (hint || hint2) return opt_for_fn (n->decl, param_max_inline_insns_single) * opt_for_fn (n->decl, param_inline_heuristics_hint_percent) / 100; return opt_for_fn (n->decl, param_max_inline_insns_single); } -/* Return inlining_insns_auto limit for function N. If HINT is true +/* Return inlining_insns_auto limit for function N. If HINT or HINT2 is true scale up the bound. */ static int -inline_insns_auto (cgraph_node *n, bool hint) +inline_insns_auto (cgraph_node *n, bool hint, bool hint2) { int max_inline_insns_auto = opt_for_fn (n->decl, param_max_inline_insns_auto); - if (hint) + if (hint && hint2) + { + int64_t spd = opt_for_fn (n->decl, param_inline_heuristics_hint_percent); + spd = spd * spd; + if (spd > 100000) + spd = 100000; + return max_inline_insns_auto * spd / 100; + } + if (hint || hint2) return max_inline_insns_auto * opt_for_fn (n->decl, param_inline_heuristics_hint_percent) / 100; return max_inline_insns_auto; @@ -566,8 +582,8 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool report, int growth = estimate_edge_growth (e); if (growth > opt_for_fn (caller->decl, param_max_inline_insns_size) && (!DECL_DECLARED_INLINE_P (callee->decl) - && growth >= MAX (inline_insns_single (caller, false), - inline_insns_auto (caller, false)))) + && growth >= MAX (inline_insns_single (caller, false, false), + inline_insns_auto (caller, false, false)))) { e->inline_failed = CIF_OPTIMIZATION_MISMATCH; inlinable = false; @@ -806,7 +822,7 @@ inlining_speedup (struct cgraph_edge *edge, } /* Return true if the speedup for inlining E is bigger than - PARAM_MAX_INLINE_MIN_SPEEDUP. */ + param_inline_min_speedup. */ static bool big_speedup_p (struct cgraph_edge *e) @@ -855,7 +871,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report) && (!e->count.ipa ().initialized_p () || !e->maybe_hot_p ())) && ipa_fn_summaries->get (callee)->min_size - ipa_call_summaries->get (e)->call_stmt_size - > inline_insns_auto (e->caller, true)) + > inline_insns_auto (e->caller, true, true)) { e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT; want_inline = false; @@ -864,7 +880,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report) || e->count.ipa ().nonzero_p ()) && ipa_fn_summaries->get (callee)->min_size - ipa_call_summaries->get (e)->call_stmt_size - > inline_insns_single (e->caller, true)) + > inline_insns_single (e->caller, true, true)) { e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl) ? CIF_MAX_INLINE_INSNS_SINGLE_LIMIT @@ -875,11 +891,14 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report) { int growth = estimate_edge_growth (e); ipa_hints hints = estimate_edge_hints (e); + /* We have two independent groups of hints. If one matches in each + of groups the limits are inreased. If both groups matches, limit + is increased even more. */ bool apply_hints = (hints & (INLINE_HINT_indirect_call | INLINE_HINT_known_hot | INLINE_HINT_loop_iterations - | INLINE_HINT_loop_stride - | INLINE_HINT_builtin_constant_p)); + | INLINE_HINT_loop_stride)); + bool apply_hints2 = (hints & INLINE_HINT_builtin_constant_p); if (growth <= opt_for_fn (to->decl, param_max_inline_insns_size)) @@ -889,9 +908,11 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report) Avoid computation of big_speedup_p when not necessary to change outcome of decision. */ else if (DECL_DECLARED_INLINE_P (callee->decl) - && growth >= inline_insns_single (e->caller, apply_hints) - && (apply_hints - || growth >= inline_insns_single (e->caller, true) + && growth >= inline_insns_single (e->caller, apply_hints, + apply_hints2) + && (apply_hints || apply_hints2 + || growth >= inline_insns_single (e->caller, true, + apply_hints2) || !big_speedup_p (e))) { e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT; @@ -903,7 +924,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report) param_max_inline_insns_small)) { /* growth_positive_p is expensive, always test it last. */ - if (growth >= inline_insns_single (e->caller, false) + if (growth >= inline_insns_single (e->caller, false, false) || growth_positive_p (callee, e, growth)) { e->inline_failed = CIF_NOT_DECLARED_INLINED; @@ -913,13 +934,15 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report) /* Apply param_max_inline_insns_auto limit for functions not declared inline. Bypass the limit when speedup seems big. */ else if (!DECL_DECLARED_INLINE_P (callee->decl) - && growth >= inline_insns_auto (e->caller, apply_hints) - && (apply_hints - || growth >= inline_insns_auto (e->caller, true) + && growth >= inline_insns_auto (e->caller, apply_hints, + apply_hints2) + && (apply_hints || apply_hints2 + || growth >= inline_insns_auto (e->caller, true, + apply_hints2) || !big_speedup_p (e))) { /* growth_positive_p is expensive, always test it last. */ - if (growth >= inline_insns_single (e->caller, false) + if (growth >= inline_insns_single (e->caller, false, false) || growth_positive_p (callee, e, growth)) { e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT; @@ -928,7 +951,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report) } /* If call is cold, do not inline when function body would grow. */ else if (!e->maybe_hot_p () - && (growth >= inline_insns_single (e->caller, false) + && (growth >= inline_insns_single (e->caller, false, false) || growth_positive_p (callee, e, growth))) { e->inline_failed = CIF_UNLIKELY_CALL; @@ -1112,8 +1135,8 @@ static bool wrapper_heuristics_may_apply (struct cgraph_node *where, int size) { return size < (DECL_DECLARED_INLINE_P (where->decl) - ? inline_insns_single (where, false) - : inline_insns_auto (where, false)); + ? inline_insns_single (where, false, false) + : inline_insns_auto (where, false, false)); } /* A cost model driving the inlining heuristics in a way so the edges with