mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 10:54:07 +08:00
Fix handling of ICF_NOVOPS in ipa-modref
As shown in somewhat convoluted testcase, ipa-modref is mistreating ECF_NOVOPS as "having no side effects". This come from time when modref cared only about memory accesses and thus it was possible to shortcut on it. This patch removes (hopefully) all those bad shortcuts. Bootstrapped/regtested x86_64-linux, comitted. gcc/ChangeLog: PR ipa/109985 * ipa-modref.cc (modref_summary::useful_p): Fix handling of ECF_NOVOPS. (modref_access_analysis::process_fnspec): Likevise. (modref_access_analysis::analyze_call): Likevise. (propagate_unknown_call): Likevise. (modref_propagate_in_scc): Likevise. (modref_propagate_flags_in_scc): Likewise. (ipa_merge_modref_summary_after_inlining): Likewise.
This commit is contained in:
parent
6f81b7fa79
commit
efcbe7b985
@ -334,7 +334,7 @@ modref_summary::useful_p (int ecf_flags, bool check_flags)
|
||||
if (check_flags
|
||||
&& remove_useless_eaf_flags (static_chain_flags, ecf_flags, false))
|
||||
return true;
|
||||
if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
|
||||
if (ecf_flags & ECF_CONST)
|
||||
return ((!side_effects || !nondeterministic)
|
||||
&& (ecf_flags & ECF_LOOPING_CONST_OR_PURE));
|
||||
if (loads && !loads->every_base)
|
||||
@ -1263,7 +1263,7 @@ modref_access_analysis::merge_call_side_effects
|
||||
int flags = gimple_call_flags (call);
|
||||
|
||||
/* Nothing to do for non-looping cont functions. */
|
||||
if ((flags & (ECF_CONST | ECF_NOVOPS))
|
||||
if ((flags & ECF_CONST)
|
||||
&& !(flags & ECF_LOOPING_CONST_OR_PURE))
|
||||
return false;
|
||||
|
||||
@ -1276,7 +1276,7 @@ modref_access_analysis::merge_call_side_effects
|
||||
/* Merge side effects and non-determinism.
|
||||
PURE/CONST flags makes functions deterministic and if there is
|
||||
no LOOPING_CONST_OR_PURE they also have no side effects. */
|
||||
if (!(flags & (ECF_CONST | ECF_NOVOPS | ECF_PURE))
|
||||
if (!(flags & (ECF_CONST | ECF_PURE))
|
||||
|| (flags & ECF_LOOPING_CONST_OR_PURE))
|
||||
{
|
||||
if (!m_summary->side_effects && callee_summary->side_effects)
|
||||
@ -1465,7 +1465,7 @@ modref_access_analysis::process_fnspec (gcall *call)
|
||||
|
||||
/* PURE/CONST flags makes functions deterministic and if there is
|
||||
no LOOPING_CONST_OR_PURE they also have no side effects. */
|
||||
if (!(flags & (ECF_CONST | ECF_NOVOPS | ECF_PURE))
|
||||
if (!(flags & (ECF_CONST | ECF_PURE))
|
||||
|| (flags & ECF_LOOPING_CONST_OR_PURE)
|
||||
|| (cfun->can_throw_non_call_exceptions
|
||||
&& stmt_could_throw_p (cfun, call)))
|
||||
@ -1604,12 +1604,12 @@ modref_access_analysis::analyze_call (gcall *stmt)
|
||||
print_gimple_stmt (dump_file, stmt, 0);
|
||||
}
|
||||
|
||||
if ((flags & (ECF_CONST | ECF_NOVOPS))
|
||||
if ((flags & ECF_CONST)
|
||||
&& !(flags & ECF_LOOPING_CONST_OR_PURE))
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
" - ECF_CONST | ECF_NOVOPS, ignoring all stores and all loads "
|
||||
" - ECF_CONST, ignoring all stores and all loads "
|
||||
"except for args.\n");
|
||||
return;
|
||||
}
|
||||
@ -1624,7 +1624,13 @@ modref_access_analysis::analyze_call (gcall *stmt)
|
||||
if (dump_file)
|
||||
fprintf (dump_file, gimple_call_internal_p (stmt)
|
||||
? " - Internal call" : " - Indirect call.\n");
|
||||
process_fnspec (stmt);
|
||||
if (flags & ECF_NOVOPS)
|
||||
{
|
||||
set_side_effects ();
|
||||
set_nondeterministic ();
|
||||
}
|
||||
else
|
||||
process_fnspec (stmt);
|
||||
return;
|
||||
}
|
||||
/* We only need to handle internal calls in IPA mode. */
|
||||
@ -4568,7 +4574,7 @@ propagate_unknown_call (cgraph_node *node,
|
||||
return changed;
|
||||
}
|
||||
|
||||
if (!(ecf_flags & (ECF_CONST | ECF_NOVOPS | ECF_PURE))
|
||||
if (!(ecf_flags & (ECF_CONST | ECF_PURE))
|
||||
|| (ecf_flags & ECF_LOOPING_CONST_OR_PURE)
|
||||
|| nontrivial_scc)
|
||||
{
|
||||
@ -4782,7 +4788,7 @@ modref_propagate_in_scc (cgraph_node *component_node)
|
||||
struct cgraph_node *callee;
|
||||
|
||||
if (!callee_edge->inline_failed
|
||||
|| ((flags & (ECF_CONST | ECF_NOVOPS))
|
||||
|| ((flags & ECF_CONST)
|
||||
&& !(flags & ECF_LOOPING_CONST_OR_PURE)))
|
||||
continue;
|
||||
|
||||
@ -5205,8 +5211,8 @@ modref_propagate_flags_in_scc (cgraph_node *component_node)
|
||||
{
|
||||
escape_summary *sum = escape_summaries->get (e);
|
||||
|
||||
if (!sum || (e->indirect_info->ecf_flags
|
||||
& (ECF_CONST | ECF_NOVOPS)))
|
||||
if (!sum || ((e->indirect_info->ecf_flags & ECF_CONST)
|
||||
&& !(e->indirect_info->ecf_flags & ECF_LOOPING_CONST_OR_PURE)))
|
||||
continue;
|
||||
|
||||
changed |= modref_merge_call_site_flags
|
||||
@ -5231,8 +5237,8 @@ modref_propagate_flags_in_scc (cgraph_node *component_node)
|
||||
modref_summary_lto *callee_summary_lto = NULL;
|
||||
struct cgraph_node *callee;
|
||||
|
||||
if (ecf_flags & (ECF_CONST | ECF_NOVOPS)
|
||||
|| !callee_edge->inline_failed)
|
||||
if ((ecf_flags & ECF_CONST)
|
||||
&& !(ecf_flags & ECF_LOOPING_CONST_OR_PURE))
|
||||
continue;
|
||||
|
||||
/* Get the callee and its summary. */
|
||||
@ -5330,7 +5336,7 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
|
||||
|
||||
if (!callee_info && to_info)
|
||||
{
|
||||
if (!(flags & (ECF_CONST | ECF_NOVOPS)))
|
||||
if (!(flags & (ECF_CONST | ECF_PURE | ECF_NOVOPS)))
|
||||
to_info->loads->collapse ();
|
||||
if (!ignore_stores)
|
||||
to_info->stores->collapse ();
|
||||
@ -5345,7 +5351,7 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
|
||||
/* Merge side effects and non-determinism.
|
||||
PURE/CONST flags makes functions deterministic and if there is
|
||||
no LOOPING_CONST_OR_PURE they also have no side effects. */
|
||||
if (!(flags & (ECF_CONST | ECF_NOVOPS | ECF_PURE))
|
||||
if (!(flags & (ECF_CONST | ECF_PURE))
|
||||
|| (flags & ECF_LOOPING_CONST_OR_PURE))
|
||||
{
|
||||
if (to_info)
|
||||
|
Loading…
Reference in New Issue
Block a user