From f6f704fd104b79fc88914978772737cd05423059 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 7 Nov 2021 18:20:45 +0100 Subject: Fix inter-procedural EAF flags propagation with respect to !binds_to_current_def_p While proofreading the code for handling EAF flags of !binds_to_current_def_p I noticed that the interprocedural dataflow actually ignores the flag possibly introducing wrong code on quite complex interposable functions in non-trivial recursion cycles (or at ltrans partition boundary). This patch unifies the flags changes to single place (remove_useless_eaf_flags) and does extend modref_merge_call_site_flags to do the right thing. lto-bootstrapped/regtested x86_64-linux. Plan to commit it today after bit more testing (firefox/clang build). gcc/ChangeLog: * gimple.c (gimple_call_arg_flags): Use interposable_eaf_flags. (gimple_call_retslot_flags): Likewise. (gimple_call_static_chain_flags): Likewise. * ipa-modref.c (remove_useless_eaf_flags): Do not remove everything for NOVOPS. (modref_summary::useful_p): Likewise. (modref_summary_lto::useful_p): Likewise. (analyze_parms): Do not give up on NOVOPS. (analyze_function): When dumping report chnages in EAF flags between IPA and local pass. (modref_merge_call_site_flags): Compute implicit eaf flags based on callee ecf_flags and fnspec; if the function does not bind to current defs use interposable_eaf_flags. (modref_propagate_flags_in_scc): Update. * ipa-modref.h (interposable_eaf_flags): New function. --- gcc/gimple.c | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) (limited to 'gcc/gimple.c') diff --git a/gcc/gimple.c b/gcc/gimple.c index 7a578f5..3d1d3a1 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -1595,17 +1595,7 @@ gimple_call_arg_flags (const gcall *stmt, unsigned arg) /* We have possibly optimized out load. Be conservative here. */ if (!node->binds_to_current_def_p ()) - { - if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED)) - { - modref_flags &= ~EAF_UNUSED; - modref_flags |= EAF_NOESCAPE; - } - if ((modref_flags & EAF_NOREAD) && !(flags & EAF_NOREAD)) - modref_flags &= ~EAF_NOREAD; - if ((modref_flags & EAF_DIRECT) && !(flags & EAF_DIRECT)) - modref_flags &= ~EAF_DIRECT; - } + modref_flags = interposable_eaf_flags (modref_flags, flags); if (dbg_cnt (ipa_mod_ref_pta)) flags |= modref_flags; } @@ -1633,13 +1623,7 @@ gimple_call_retslot_flags (const gcall *stmt) /* We have possibly optimized out load. Be conservative here. */ if (!node->binds_to_current_def_p ()) - { - if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED)) - { - modref_flags &= ~EAF_UNUSED; - modref_flags |= EAF_NOESCAPE; - } - } + modref_flags = interposable_eaf_flags (modref_flags, flags); if (dbg_cnt (ipa_mod_ref_pta)) flags |= modref_flags; } @@ -1665,19 +1649,9 @@ gimple_call_static_chain_flags (const gcall *stmt) { int modref_flags = summary->static_chain_flags; - /* We have possibly optimized out load. Be conservative here. */ + /* ??? Nested functions should always bind to current def. */ if (!node->binds_to_current_def_p ()) - { - if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED)) - { - modref_flags &= ~EAF_UNUSED; - modref_flags |= EAF_NOESCAPE; - } - if ((modref_flags & EAF_NOREAD) && !(flags & EAF_NOREAD)) - modref_flags &= ~EAF_NOREAD; - if ((modref_flags & EAF_DIRECT) && !(flags & EAF_DIRECT)) - modref_flags &= ~EAF_DIRECT; - } + modref_flags = interposable_eaf_flags (modref_flags, flags); if (dbg_cnt (ipa_mod_ref_pta)) flags |= modref_flags; } -- cgit v1.1