From patchwork Mon Nov 1 08:10:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 46886 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 177283858027 for ; Mon, 1 Nov 2021 08:11:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 177283858027 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1635754261; bh=3q1GwJdRC5Hirc+VdYX+m0jnwvuPl8Dgs2Daw1o8djo=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=R1XZrAV4gom6KPvLTDSGLorJCH/nJ6Al7eHhVCe+H3tLrcTTyyObsd+cWmIxSJVKf PQNdcJgFP2RF+6S1ckLFL6hwIiMEspq5J5L7VX4mk1YMj1OLbTBUgyKNIcyuNPl455 cqqtE6qODGThbvdRW6Tt34IwPRjn5LOxxRIauP+w= 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 5B1B53858422 for ; Mon, 1 Nov 2021 08:10:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5B1B53858422 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id C23022809AB; Mon, 1 Nov 2021 09:10:27 +0100 (CET) Date: Mon, 1 Nov 2021 09:10:27 +0100 To: gcc-patches@gcc.gnu.org, rguenther@suse.de Subject: Add static_chain support to ipa-modref Message-ID: <20211101081027.GA74431@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=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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-Patchwork-Original-From: Jan Hubicka via Gcc-patches From: Jan Hubicka Reply-To: Jan Hubicka Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi, this is patchs teaches ipa-modref about the static chain that is, like retslot, a hiden argument. The patch is pretty much symemtric to what was done for retslot handling and I verified it does the intended job for Ada LTO bootstrap. Bootstrapped/regtested x86_64-linux, OK? Honza gcc/ChangeLog: * gimple.c (gimple_call_static_chain_flags): New function. * gimple.h (gimple_call_static_chain_flags): Declare * ipa-modref.c (modref_summary::modref_summary): Initialize static_chain_flags. (modref_summary_lto::modref_summary_lto): Likewise. (modref_summary::useful_p): Test static_chain_flags. (modref_summary_lto::useful_p): Likewise. (struct modref_summary_lto): Add static_chain_flags. (modref_summary::dump): Dump static_chain_flags. (modref_summary_lto::dump): Likewise. (struct escape_point): Add static_cahin_arg. (analyze_ssa_name_flags): Use gimple_call_static_chain_flags. (analyze_parms): Handle static chains. (modref_summaries::duplicate): Duplicate static_chain_flags. (modref_summaries_lto::duplicate): Likewise. (modref_write): Stream static_chain_flags. (read_section): Likewise. (modref_merge_call_site_flags): Handle static_chain_flags. * ipa-modref.h (struct modref_summary): Add static_chain_flags. * tree-ssa-structalias.c (handle_rhs_call): Use * gimple_static_chain_flags. gcc/testsuite/ChangeLog: * gcc.dg/ipa/modref-3.c: New test. diff --git a/gcc/gimple.c b/gcc/gimple.c index 22dd6417d19..ef07d9385c5 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -1647,6 +1647,33 @@ gimple_call_retslot_flags (const gcall *stmt) return flags; } +/* Detects argument flags for static chain on call STMT. */ + +int +gimple_call_static_chain_flags (const gcall *stmt) +{ + int flags = 0; + + tree callee = gimple_call_fndecl (stmt); + if (callee) + { + cgraph_node *node = cgraph_node::get (callee); + modref_summary *summary = node ? get_modref_function_summary (node) + : NULL; + + if (summary) + { + int modref_flags = summary->static_chain_flags; + + /* We have possibly optimized out load. Be conservative here. */ + gcc_checking_assert (node->binds_to_current_def_p ()); + if (dbg_cnt (ipa_mod_ref_pta)) + flags |= modref_flags; + } + } + return flags; +} + /* Detects return flags for the call STMT. */ int diff --git a/gcc/gimple.h b/gcc/gimple.h index 23a124ec769..3cde3cde7fe 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1590,6 +1590,7 @@ bool gimple_call_same_target_p (const gimple *, const gimple *); int gimple_call_flags (const gimple *); int gimple_call_arg_flags (const gcall *, unsigned); int gimple_call_retslot_flags (const gcall *); +int gimple_call_static_chain_flags (const gcall *); int gimple_call_return_flags (const gcall *); bool gimple_call_nonnull_result_p (gcall *); tree gimple_call_nonnull_arg (gcall *); diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c index d866d9ed6b3..ae8ed53b396 100644 --- a/gcc/ipa-modref.c +++ b/gcc/ipa-modref.c @@ -270,7 +270,8 @@ static GTY(()) fast_function_summary /* Summary for a single function which this pass produces. */ modref_summary::modref_summary () - : loads (NULL), stores (NULL), retslot_flags (0), writes_errno (false) + : loads (NULL), stores (NULL), retslot_flags (0), static_chain_flags (0), + writes_errno (false) { } @@ -325,6 +326,9 @@ modref_summary::useful_p (int ecf_flags, bool check_flags) arg_flags.release (); if (check_flags && remove_useless_eaf_flags (retslot_flags, ecf_flags, false)) return true; + if (check_flags + && remove_useless_eaf_flags (static_chain_flags, ecf_flags, false)) + return true; if (ecf_flags & ECF_CONST) return false; if (loads && !loads->every_base) @@ -367,6 +371,7 @@ struct GTY(()) modref_summary_lto modref_records_lto *stores; auto_vec GTY((skip)) arg_flags; eaf_flags_t retslot_flags; + eaf_flags_t static_chain_flags; bool writes_errno; modref_summary_lto (); @@ -378,7 +383,8 @@ struct GTY(()) modref_summary_lto /* Summary for a single function which this pass produces. */ modref_summary_lto::modref_summary_lto () - : loads (NULL), stores (NULL), retslot_flags (0), writes_errno (false) + : loads (NULL), stores (NULL), retslot_flags (0), static_chain_flags (0), + writes_errno (false) { } @@ -406,6 +412,9 @@ modref_summary_lto::useful_p (int ecf_flags, bool check_flags) arg_flags.release (); if (check_flags && remove_useless_eaf_flags (retslot_flags, ecf_flags, false)) return true; + if (check_flags + && remove_useless_eaf_flags (static_chain_flags, ecf_flags, false)) + return true; if (ecf_flags & ECF_CONST) return false; if (loads && !loads->every_base) @@ -619,6 +628,11 @@ modref_summary::dump (FILE *out) fprintf (out, " Retslot flags:"); dump_eaf_flags (out, retslot_flags); } + if (static_chain_flags) + { + fprintf (out, " Static chain flags:"); + dump_eaf_flags (out, static_chain_flags); + } } /* Dump summary. */ @@ -646,6 +660,11 @@ modref_summary_lto::dump (FILE *out) fprintf (out, " Retslot flags:"); dump_eaf_flags (out, retslot_flags); } + if (static_chain_flags) + { + fprintf (out, " Static chain flags:"); + dump_eaf_flags (out, static_chain_flags); + } } /* Get function summary for FUNC if it exists, return NULL otherwise. */ @@ -1415,7 +1434,8 @@ struct escape_point /* Extra hidden args we keep track of. */ enum hidden_args { - retslot_arg = -1 + retslot_arg = -1, + static_chain_arg = -2 }; /* Value escapes to this call. */ gcall *call; @@ -1776,11 +1796,9 @@ analyze_ssa_name_flags (tree name, vec &lattice, int depth, lattice[index].merge (gimple_call_retslot_flags (call)); } - /* We do not track accesses to the static chain (we could) - so give up. */ if (gimple_call_chain (call) && (gimple_call_chain (call) == name)) - lattice[index].merge (0); + lattice[index].merge (gimple_call_static_chain_flags (call)); /* Process internal functions and right away. */ bool record_ipa = ipa && !gimple_call_internal_p (call); @@ -1970,6 +1988,7 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto, unsigned int count = 0; int ecf_flags = flags_from_decl_or_type (current_function_decl); tree retslot = NULL; + tree static_chain = NULL; /* For novops functions we have nothing to gain by EAF flags. */ if (ecf_flags & ECF_NOVOPS) @@ -1979,12 +1998,14 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto, if (DECL_RESULT (current_function_decl) && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) retslot = ssa_default_def (cfun, DECL_RESULT (current_function_decl)); + if (cfun->static_chain_decl) + static_chain = ssa_default_def (cfun, cfun->static_chain_decl); for (tree parm = DECL_ARGUMENTS (current_function_decl); parm; parm = TREE_CHAIN (parm)) count++; - if (!count && !retslot) + if (!count && !retslot && !static_chain) return; auto_vec lattice; @@ -2058,6 +2079,22 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto, escape_point::retslot_arg, flags); } } + if (static_chain) + { + analyze_ssa_name_flags (static_chain, lattice, 0, ipa); + int flags = lattice[SSA_NAME_VERSION (static_chain)].flags; + + flags = remove_useless_eaf_flags (flags, ecf_flags, false); + if (flags) + { + if (summary) + summary->static_chain_flags = flags; + if (summary_lto) + summary_lto->static_chain_flags = flags; + record_escape_points (lattice[SSA_NAME_VERSION (static_chain)], + escape_point::static_chain_arg, flags); + } + } if (ipa) for (unsigned int i = 0; i < num_ssa_names; i++) lattice[i].release (); @@ -2342,6 +2379,7 @@ modref_summaries::duplicate (cgraph_node *, cgraph_node *dst, if (src_data->arg_flags.length ()) dst_data->arg_flags = src_data->arg_flags.copy (); dst_data->retslot_flags = src_data->retslot_flags; + dst_data->static_chain_flags = src_data->static_chain_flags; } /* Called when new clone is inserted to callgraph late. */ @@ -2368,6 +2406,7 @@ modref_summaries_lto::duplicate (cgraph_node *, cgraph_node *, if (src_data->arg_flags.length ()) dst_data->arg_flags = src_data->arg_flags.copy (); dst_data->retslot_flags = src_data->retslot_flags; + dst_data->static_chain_flags = src_data->static_chain_flags; } namespace @@ -2685,6 +2724,7 @@ modref_write () for (unsigned int i = 0; i < r->arg_flags.length (); i++) streamer_write_uhwi (ob, r->arg_flags[i]); streamer_write_uhwi (ob, r->retslot_flags); + streamer_write_uhwi (ob, r->static_chain_flags); write_modref_records (r->loads, ob); write_modref_records (r->stores, ob); @@ -2786,6 +2826,13 @@ read_section (struct lto_file_decl_data *file_data, const char *data, modref_sum->retslot_flags = flags; if (modref_sum_lto) modref_sum_lto->retslot_flags = flags; + + flags = streamer_read_uhwi (&ib); + if (modref_sum) + modref_sum->static_chain_flags = flags; + if (modref_sum_lto) + modref_sum_lto->static_chain_flags = flags; + read_modref_records (&ib, data_in, modref_sum ? &modref_sum->loads : NULL, modref_sum_lto ? &modref_sum_lto->loads : NULL); @@ -3871,6 +3918,8 @@ modref_merge_call_site_flags (escape_summary *sum, { eaf_flags_t &f = ee->parm_index == escape_point::retslot_arg ? cur_summary->retslot_flags + : ee->parm_index == escape_point::static_chain_arg + ? cur_summary->static_chain_flags : cur_summary->arg_flags[ee->parm_index]; if ((f & flags) != f) { @@ -3886,6 +3935,8 @@ modref_merge_call_site_flags (escape_summary *sum, { eaf_flags_t &f = ee->parm_index == escape_point::retslot_arg ? cur_summary_lto->retslot_flags + : ee->parm_index == escape_point::static_chain_arg + ? cur_summary_lto->static_chain_flags : cur_summary_lto->arg_flags[ee->parm_index]; if ((f & flags_lto) != f) { diff --git a/gcc/ipa-modref.h b/gcc/ipa-modref.h index a4db27471eb..ddc86869069 100644 --- a/gcc/ipa-modref.h +++ b/gcc/ipa-modref.h @@ -32,6 +32,7 @@ struct GTY(()) modref_summary modref_records *stores; auto_vec GTY((skip)) arg_flags; eaf_flags_t retslot_flags; + eaf_flags_t static_chain_flags; bool writes_errno; modref_summary (); diff --git a/gcc/testsuite/gcc.dg/ipa/modref-3.c b/gcc/testsuite/gcc.dg/ipa/modref-3.c new file mode 100644 index 00000000000..84013541ce8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/modref-3.c @@ -0,0 +1,20 @@ +/* { dg-options "-O2 -fdump-ipa-modref" } */ +/* { dg-do link } */ +int *ptr; +void linker_error (); +int +main () +{ + int a; + __attribute__((noinline)) int test2 () + { + ptr = 0; + return a; + } + a = 1; + test2 (); + if (a != 1) + linker_error (); + return 0; +} +/* { dg-final { scan-ipa-dump "Static chain flags: noclobber noescape nodirectescape" "modref" } } */ diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 99072df0768..d2a955dafeb 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4246,7 +4246,8 @@ handle_rhs_call (gcall *stmt, vec *results, /* The static chain escapes as well. */ if (gimple_call_chain (stmt)) handle_call_arg (stmt, gimple_call_chain (stmt), results, - implicit_eaf_flags, + implicit_eaf_flags + | gimple_call_static_chain_flags (stmt), callescape->id, writes_global_memory); /* And if we applied NRV the address of the return slot escapes as well. */