Hi,
this patch enables the pure/const discovery in modref, so we newly can handle
some extra cases, for example:
struct a {int a,b,c;};
__attribute__ ((noinline))
int init (struct a *a)
{
a->a=1;
a->b=2;
a->c=3;
}
int const_fn ()
{
struct a a;
init ();
return a.a + a.b + a.c;
}
Here pure/const stops on the fact that const_fn calls non-const init, while
modref knows that the memory it initializes is local to const_fn.
I ended up reordering passes so early modref is done after early pure-const
mostly to avoid need to change testsuite which greps for const functions
being detects in pure-const. Stil some testuiste compensation is needed.
Boostrapped/regtested x86_64-linux. Will commit it shortly.
gcc/ChangeLog:
2021-11-11 Jan Hubicka
* ipa-modref.c (analyze_function): Do pure/const discovery, return
true on success.
(pass_modref::execute): If pure/const is discovered fixup cfg.
(ignore_edge): Do not ignore pure/const edges.
(modref_propagate_in_scc): Do pure/const discovery, return true if
cdtor was promoted pure/const.
(pass_ipa_modref::execute): If needed remove unreachable functions.
* ipa-pure-const.c (warn_function_noreturn): Fix whitespace.
(warn_function_cold): Likewise.
(skip_function_for_local_pure_const): Move earlier.
(ipa_make_function_const): Break out from ...
(ipa_make_function_pure): Break out from ...
(propagate_pure_const): ... here.
(pass_local_pure_const::execute): Use it.
* ipa-utils.h (ipa_make_function_const): Declare.
(ipa_make_function_pure): Declare.
* passes.def: Move early modref after pure-const.
gcc/testsuite/ChangeLog:
2021-11-11 Jan Hubicka
* c-c++-common/tm/inline-asm.c: Disable pure-const.
* g++.dg/ipa/modref-1.C: Update template.
* gcc.dg/tree-ssa/modref-11.c: Disable pure-const.
* gcc.dg/tree-ssa/modref-14.c: New test.
* gcc.dg/tree-ssa/modref-8.c: Do not optimize sibling calls.
* gfortran.dg/do_subscript_3.f90: Add -O0.
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 45b391a565e..72006251f29 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -2603,11 +2603,13 @@ analyze_parms (modref_summary *summary,
modref_summary_lto *summary_lto,
}
/* Analyze function F. IPA indicates whether we're running in local mode
- (false) or the IPA mode (true). */
+ (false) or the IPA mode (true).
+ Return true if fixup cfg is needed after the pass. */
-static void
+static bool
analyze_function (function *f, bool ipa)
{
+ bool fixup_cfg = false;
if (dump_file)
fprintf (dump_file, "modref analyzing '%s' (ipa=%i)%s%s\n",
function_name (f), ipa,
@@ -2617,7 +2619,7 @@ analyze_function (function *f, bool ipa)
/* Don't analyze this function if it's compiled with -fno-strict-aliasing.
*/
if (!flag_ipa_modref
|| lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl)))
-return;
+return false;
/* Compute no-LTO summaries when local optimization is going to happen. */
bool nolto = (!ipa || ((!flag_lto || flag_fat_lto_objects) && !in_lto_p)
@@ -2774,12 +2776,32 @@ analyze_function (function *f, bool ipa)
if (!summary->useful_p (ecf_flags, false))
{
remove_summary (lto, nolto, ipa);
- return;
+ return false;
}
}
first = false;
}
}
+ if (summary && !summary->global_memory_written_p () && !summary->side_effects
+ && !finite_function_p ())
+summary->side_effects = true;
+ if (summary_lto && !summary_lto->side_effects && !finite_function_p ())
+summary_lto->side_effects = true;
+
+ if (!ipa && flag_ipa_pure_const)
+{
+ if (!summary->stores->every_base && !summary->stores->bases)
+ {
+ if (!summary->loads->every_base && !summary->loads->bases)
+ fixup_cfg = ipa_make_function_const
+ (cgraph_node::get (current_function_decl),
+ summary->side_effects, true);
+ else
+ fixup_cfg = ipa_make_function_pure
+ (cgraph_node::get (current_function_decl),
+ summary->side_effects, true);
+ }
+}
if (summary && !summary->useful_p (ecf_flags))
{
if (!ipa)
@@ -2793,11 +2815,6 @@ analyze_function (function *f, bool ipa)
summaries_lto->remove (fnode);
summary_lto = NULL;
}
- if (summary && !summary->global_memory_written_p () && !summary->side_effects
- && !finite_function_p ())
-summary->side_effects = true;
- if (summary_lto && !summary_lto->side_effects && !finite_function_p ())
-summary_lto->side_effects = true;
if (ipa && !summary && !summary_lto)
remove_modref_edge_summaries (fnode);
@@ -2907,6 +2924,7 @@ analyze_function (function *f, bool ipa)
}
}
}
+ return