Re: Enable pure/const discovery in modref

2021-11-12 Thread Jan Hubicka via Gcc-patches
> Hi Honza,
> 
> On Thu, 11 Nov 2021 17:39:18 +0100
> Jan Hubicka via Gcc-patches  wrote:
> 
> > diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
> > index 422b52fba4b..550bdeded16 100644
> > --- a/gcc/ipa-pure-const.c
> > +++ b/gcc/ipa-pure-const.c
> > @@ -1513,6 +1611,9 @@ propagate_pure_const (void)
> >   enum pure_const_state_e edge_state = IPA_CONST;
> >   bool edge_looping = false;
> >  
> > + if (e->recursive_p ())
> > +   looping = true;
> > +
> >   if (e->recursive_p ())
> > looping = true;
> >  
> 
> This seems redundant, no?

Yes, artifact of breaking up the patch :(
I also noticed that I mixed up looping flag (there are two variables one
called looping and other this_looping while the second is one I should
use and first is one I used)

Fixed as follows.


gcc/ChangeLog:

* ipa-pure-const.c (propagate_pure_const): Remove redundant check;
fix call of ipa_make_function_const and ipa_make_function_pure.

diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index b831844afa6..5056850c0a8 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -1611,9 +1611,6 @@ propagate_pure_const (void)
  enum pure_const_state_e edge_state = IPA_CONST;
  bool edge_looping = false;
 
- if (e->recursive_p ())
-   looping = true;
-
  if (e->recursive_p ())
looping = true;
 
@@ -1800,11 +1797,11 @@ propagate_pure_const (void)
switch (this_state)
  {
  case IPA_CONST:
-   remove_p |= ipa_make_function_const (node, looping, false);
+   remove_p |= ipa_make_function_const (node, this_looping, false);
break;
 
  case IPA_PURE:
-   remove_p |= ipa_make_function_pure (node, looping, false);
+   remove_p |= ipa_make_function_pure (node, this_looping, false);
break;
 
  default:


Enable pure/const discovery in modref

2021-11-11 Thread Jan Hubicka via Gcc-patches
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