From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id 8E21D398795E for ; Fri, 25 Sep 2020 11:15:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8E21D398795E 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 B453628299C; Fri, 25 Sep 2020 13:15:55 +0200 (CEST) Date: Fri, 25 Sep 2020 13:15:55 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org, d@dcepelik.cz Subject: Track arguments pointing to local or readonly memory in ipa-fnsummary Message-ID: <20200925111555.GC1129@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-15.0 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: , X-List-Received-Date: Fri, 25 Sep 2020 11:15:59 -0000 Hi, this patch implement trakcing wehther argument points to readonly memory. This is is useful for ipa-modref as well as for inline heuristics. It is desirable to inline functions that dereference pointers to local variables in order to support SRA. We always did the oposite heuristics (guessing that the dereferences will be optimized out with 50% probability) but here we could increase the probability for cases where we can track that argument is indeed a local memory (or readonly which is also good) Bootstrapped/regtested x86_64-linux. I plan to commit it later today unless there are comments. Honza * ipa-fnsummary.c (dump_ipa_call_summary): Dump points_to_local_or_readonly_memory flag. (analyze_function_body): Compute points_to_local_or_readonly_memory flag. (remap_edge_change_prob): Rename to ... (remap_edge_params): ... this one; update points_to_local_or_readonly_memory. (remap_edge_summaries): Update. (read_ipa_call_summary): Stream the new flag. (write_ipa_call_summary): Likewise. * ipa-predicate.h (struct inline_param_summary): Add points_to_local_or_readonly_memory. (inline_param_summary::equal_to): Update. (inline_param_summary::useless_p): Update. diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index bb703f62206..7f12b116dec 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -980,6 +980,9 @@ dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node, else if (prob != REG_BR_PROB_BASE) fprintf (f, "%*s op%i change %f%% of time\n", indent + 2, "", i, prob * 100.0 / REG_BR_PROB_BASE); + if (es->param[i].points_to_local_or_readonly_memory) + fprintf (f, "%*s op%i points to local or readonly memory\n", + indent + 2, "", i); } if (!edge->inline_failed) { @@ -2671,6 +2674,9 @@ analyze_function_body (struct cgraph_node *node, bool early) int prob = param_change_prob (&fbi, stmt, i); gcc_assert (prob >= 0 && prob <= REG_BR_PROB_BASE); es->param[i].change_prob = prob; + es->param[i].points_to_local_or_readonly_memory + = points_to_local_or_readonly_memory_p + (gimple_call_arg (stmt, i)); } } @@ -3783,15 +3789,17 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth) ipa_call_summaries->get (e)->loop_depth += depth; } -/* Update change_prob of EDGE after INLINED_EDGE has been inlined. +/* Update change_prob and points_to_local_or_readonly_memory of EDGE after + INLINED_EDGE has been inlined. + When function A is inlined in B and A calls C with parameter that changes with probability PROB1 and C is known to be passthrough of argument if B that change with probability PROB2, the probability of change is now PROB1*PROB2. */ static void -remap_edge_change_prob (struct cgraph_edge *inlined_edge, - struct cgraph_edge *edge) +remap_edge_params (struct cgraph_edge *inlined_edge, + struct cgraph_edge *edge) { if (ipa_node_params_sum) { @@ -3825,7 +3833,16 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge, prob = 1; es->param[i].change_prob = prob; + + if (inlined_es + ->param[id].points_to_local_or_readonly_memory) + es->param[i].points_to_local_or_readonly_memory = true; } + if (!es->param[i].points_to_local_or_readonly_memory + && jfunc->type == IPA_JF_CONST + && points_to_local_or_readonly_memory_p + (ipa_get_jf_constant (jfunc))) + es->param[i].points_to_local_or_readonly_memory = true; } } } @@ -3858,7 +3875,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge, if (e->inline_failed) { class ipa_call_summary *es = ipa_call_summaries->get (e); - remap_edge_change_prob (inlined_edge, e); + remap_edge_params (inlined_edge, e); if (es->predicate) { @@ -3884,7 +3901,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge, predicate p; next = e->next_callee; - remap_edge_change_prob (inlined_edge, e); + remap_edge_params (inlined_edge, e); if (es->predicate) { p = es->predicate->remap_after_inlining @@ -4210,12 +4227,19 @@ read_ipa_call_summary (class lto_input_block *ib, struct cgraph_edge *e, { es->param.safe_grow_cleared (length, true); for (i = 0; i < length; i++) - es->param[i].change_prob = streamer_read_uhwi (ib); + { + es->param[i].change_prob = streamer_read_uhwi (ib); + es->param[i].points_to_local_or_readonly_memory + = streamer_read_uhwi (ib); + } } else { for (i = 0; i < length; i++) - streamer_read_uhwi (ib); + { + streamer_read_uhwi (ib); + streamer_read_uhwi (ib); + } } } @@ -4440,7 +4464,10 @@ write_ipa_call_summary (struct output_block *ob, struct cgraph_edge *e) streamer_write_uhwi (ob, 0); streamer_write_uhwi (ob, es->param.length ()); for (i = 0; i < (int) es->param.length (); i++) - streamer_write_uhwi (ob, es->param[i].change_prob); + { + streamer_write_uhwi (ob, es->param[i].change_prob); + streamer_write_uhwi (ob, es->param[i].points_to_local_or_readonly_memory); + } } diff --git a/gcc/ipa-predicate.h b/gcc/ipa-predicate.h index 9b75ffcf280..05e37073817 100644 --- a/gcc/ipa-predicate.h +++ b/gcc/ipa-predicate.h @@ -76,14 +76,18 @@ struct inline_param_summary parameters REG_BR_PROB_BASE. Value 0 is reserved for compile time invariants. */ - int change_prob; + short change_prob; + unsigned points_to_local_or_readonly_memory : 1; bool equal_to (const inline_param_summary &other) const { - return change_prob == other.change_prob; + return change_prob == other.change_prob + && points_to_local_or_readonly_memory + == other.points_to_local_or_readonly_memory; } bool useless_p (void) const { - return change_prob == REG_BR_PROB_BASE; + return change_prob == REG_BR_PROB_BASE + && !points_to_local_or_readonly_memory; } };