public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/hubicka/heads/honza-gcc-benchmark-branch-v2)] Experimental modref changeset
@ 2021-12-09 19:12 Jan Hubicka
  0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2021-12-09 19:12 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:77a13853beb2d782359867954c6c97f8e8e6b3da

commit 77a13853beb2d782359867954c6c97f8e8e6b3da
Author: Jan Hubicka <jh@suse.cz>
Date:   Thu Dec 9 20:12:08 2021 +0100

    Experimental modref changeset

Diff:
---
 gcc/ipa-modref-tree.c |   7 ++-
 gcc/ipa-modref-tree.h |  12 +++--
 gcc/ipa-modref.c      | 131 ++++++++++++++++++++++++++++++++++++++++++++++----
 gcc/tree-ssa-alias.c  |  36 ++++++++++++++
 4 files changed, 172 insertions(+), 14 deletions(-)

diff --git a/gcc/ipa-modref-tree.c b/gcc/ipa-modref-tree.c
index 0671fa76199..47fd929864e 100644
--- a/gcc/ipa-modref-tree.c
+++ b/gcc/ipa-modref-tree.c
@@ -625,7 +625,9 @@ modref_access_node::dump (FILE *out)
 {
   if (parm_index != MODREF_UNKNOWN_PARM)
     {
-      if (parm_index >= 0)
+      if (parm_index == MODREF_GLOBAL_MEMORY_PARM)
+	fprintf (out, " Base in global memory");
+      else if (parm_index >= 0)
 	fprintf (out, " Parm %i", parm_index);
       else if (parm_index == MODREF_STATIC_CHAIN_PARM)
 	fprintf (out, " Static chain");
@@ -655,7 +657,8 @@ modref_access_node::dump (FILE *out)
 tree
 modref_access_node::get_call_arg (const gcall *stmt) const
 {
-  if (parm_index == MODREF_UNKNOWN_PARM)
+  if (parm_index == MODREF_UNKNOWN_PARM
+      || parm_index == MODREF_GLOBAL_MEMORY_PARM)
     return NULL;
   if (parm_index == MODREF_STATIC_CHAIN_PARM)
     return gimple_call_chain (stmt);
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index 35190c212ca..2145308fda4 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -48,10 +48,12 @@ enum modref_special_parms {
   MODREF_UNKNOWN_PARM = -1,
   MODREF_STATIC_CHAIN_PARM = -2,
   MODREF_RETSLOT_PARM = -3,
+  /* Used for bases that points to memory that escapes from function.  */
+  MODREF_GLOBAL_MEMORY_PARM = -4,
   /* Used in modref_parm_map to tak references which can be removed
      from the summary during summary update since they now points to loca
      memory.  */
-  MODREF_LOCAL_MEMORY_PARM = -4
+  MODREF_LOCAL_MEMORY_PARM = -5
 };
 
 /* Modref record accesses relative to function parameters.
@@ -174,6 +176,7 @@ struct GTY((user)) modref_ref_node
        in the caller.  */
     gcc_checking_assert (a.parm_index >= 0
 			 || a.parm_index == MODREF_STATIC_CHAIN_PARM
+			 || a.parm_index == MODREF_GLOBAL_MEMORY_PARM
 			 || a.parm_index == MODREF_UNKNOWN_PARM);
 
     if (!a.useful_p ())
@@ -580,7 +583,9 @@ struct GTY((user)) modref_tree
 
 		    if (a.parm_index != MODREF_UNKNOWN_PARM && parm_map)
 		      {
-			if (a.parm_index >= (int)parm_map->length ())
+			if (a.parm_index == MODREF_GLOBAL_MEMORY_PARM)
+			  ;
+			else if (a.parm_index >= (int)parm_map->length ())
 			  a.parm_index = MODREF_UNKNOWN_PARM;
 			else
 			  {
@@ -656,7 +661,8 @@ struct GTY((user)) modref_tree
 	    if (ref_node->every_access)
 	      return true;
 	    FOR_EACH_VEC_SAFE_ELT (ref_node->accesses, k, access_node)
-	      if (access_node->parm_index == MODREF_UNKNOWN_PARM)
+	      if (access_node->parm_index == MODREF_UNKNOWN_PARM
+		  || access_node->parm_index == MODREF_GLOBAL_MEMORY_PARM)
 		return true;
 	  }
       }
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 9e537b04196..1cf9609e8f3 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -754,7 +754,7 @@ get_modref_function_summary (cgraph_node *func)
      we don't want to return anything, even if we have summary for the target
      function.  */
   enum availability avail;
-  func = func->function_or_virtual_thunk_symbol
+  func = func->ultimate_alias_target
 		 (&avail, current_function_decl ?
 			  cgraph_node::get (current_function_decl) : NULL);
   if (avail <= AVAIL_INTERPOSABLE)
@@ -892,6 +892,8 @@ private:
   bool record_access_p (tree);
   bool record_unknown_load ();
   bool record_unknown_store ();
+  bool record_global_memory_load ();
+  bool record_global_memory_store ();
   bool merge_call_side_effects (gimple *, modref_summary *,
 				cgraph_node *, bool);
   modref_access_node get_access_for_fnspec (gcall *, attr_fnspec &,
@@ -1147,6 +1149,41 @@ modref_access_analysis::record_unknown_store ()
   return changed;
 }
 
+/* Record unknown load from gloal memory.  */
+
+bool
+modref_access_analysis::record_global_memory_load ()
+{
+  bool changed = false;
+  modref_access_node a = {0, -1, -1,
+			  0, MODREF_GLOBAL_MEMORY_PARM, false, 0};
+
+  if (m_summary && !m_summary->loads->every_base)
+    changed |= m_summary->loads->insert (current_function_decl, 0, 0, a, false);
+  if (m_summary_lto && !m_summary_lto->loads->every_base)
+    changed |= m_summary_lto->loads->insert (current_function_decl,
+					     0, 0, a, false);
+  return changed;
+}
+
+/* Record unknown store from gloal memory.  */
+
+bool
+modref_access_analysis::record_global_memory_store ()
+{
+  bool changed = false;
+  modref_access_node a = {0, -1, -1,
+			  0, MODREF_GLOBAL_MEMORY_PARM, false, 0};
+
+  if (m_summary && !m_summary->stores->every_base)
+    changed |= m_summary->stores->insert (current_function_decl,
+					  0, 0, a, false);
+  if (m_summary_lto && !m_summary_lto->stores->every_base)
+    changed |= m_summary_lto->stores->insert (current_function_decl,
+					     0, 0, a, false);
+  return changed;
+}
+
 /* Merge side effects of call STMT to function with CALLEE_SUMMARY.
    Return true if something changed.
    If IGNORE_STORES is true, do not merge stores.
@@ -1349,6 +1386,57 @@ modref_access_analysis::get_access_for_fnspec (gcall *call, attr_fnspec &fnspec,
   return a;
 }
 
+/* Return true if ARG with EAF flags FLAGS can not make any caller's parameter
+   used even if they are not escaped.  */
+
+static bool
+verify_arg (tree arg, int flags)
+{
+  if (flags & EAF_UNUSED)
+    return true;
+  if (!(flags & (EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE)))
+    return true;
+  if (is_gimple_constant (arg))
+    return true;
+  if (DECL_P (arg) && TREE_READONLY (arg))
+    return true;
+  if (TREE_CODE (arg) == ADDR_EXPR)
+    {
+      tree t = get_base_address (TREE_OPERAND (arg, 0));
+      if (is_gimple_constant (t))
+	return true;
+      if (DECL_P (t)
+	  && (TREE_READONLY (t) || TREE_CODE (t) == FUNCTION_DECL))
+	return true;
+    }
+  return false;
+}
+
+/* Return true if STMT may access memory that is pointed to by parameters
+   of caller and which is not seen as an escape by PTA.  */
+
+static bool
+may_access_nonescaping_parm_p (gcall *call, int callee_ecf_flags)
+{
+  int implicit_flags = false;
+
+  if (ignore_stores_p (current_function_decl, callee_ecf_flags))
+    implicit_flags |= ignore_stores_eaf_flags;
+  if (callee_ecf_flags & ECF_PURE)
+    implicit_flags |= implicit_pure_eaf_flags;
+  if (callee_ecf_flags & (ECF_CONST | ECF_NOVOPS))
+    implicit_flags |= implicit_const_eaf_flags;
+  if (gimple_call_chain (call)
+      && !verify_arg (gimple_call_chain (call),
+		      gimple_call_static_chain_flags (call) | implicit_flags))
+    return true;
+  for (unsigned int i = 0; i < gimple_call_num_args (call); i++)
+    if (!verify_arg (gimple_call_arg (call, i),
+		     gimple_call_arg_flags (call, i) | implicit_flags))
+      return true;
+  return false;
+}
+
 /* Apply side effects of call STMT to CUR_SUMMARY using FNSPEC.
    If IGNORE_STORES is true ignore them.
    Return false if no useful summary can be produced.   */
@@ -1381,14 +1469,28 @@ modref_access_analysis::process_fnspec (gcall *call)
       if (dump_file && gimple_call_builtin_p (call, BUILT_IN_NORMAL))
 	fprintf (dump_file, "      Builtin with no fnspec: %s\n",
 		 IDENTIFIER_POINTER (DECL_NAME (gimple_call_fndecl (call))));
-      record_unknown_load ();
       if (!ignore_stores_p (current_function_decl, flags))
-	record_unknown_store ();
+	{
+	  record_global_memory_store ();
+	  record_global_memory_load ();
+	}
+      else
+	{
+	  if (!may_access_nonescaping_parm_p (call, flags))
+	    record_global_memory_load ();
+	  else
+	    record_unknown_load ();
+	}
       return;
     }
   /* Process fnspec.  */
   if (fnspec.global_memory_read_p ())
-    record_unknown_load ();
+    {
+      if (may_access_nonescaping_parm_p (call, flags))
+	record_unknown_load ();
+      else
+	record_global_memory_load ();
+    }
   else
     {
       for (unsigned int i = 0; i < gimple_call_num_args (call); i++)
@@ -1420,7 +1522,12 @@ modref_access_analysis::process_fnspec (gcall *call)
   if (ignore_stores_p (current_function_decl, flags))
     return;
   if (fnspec.global_memory_written_p ())
-    record_unknown_store ();
+    {
+      if (may_access_nonescaping_parm_p (call, flags))
+	record_unknown_store ();
+      else
+	record_global_memory_store ();
+    }
   else
     {
       for (unsigned int i = 0; i < gimple_call_num_args (call); i++)
@@ -1468,6 +1575,12 @@ modref_access_analysis::analyze_call (gcall *stmt)
      simplified.  */
   int flags = gimple_call_flags (stmt);
 
+  if (dump_file)
+    {
+      fprintf (dump_file, " - Analyzing call:");
+      print_gimple_stmt (dump_file, stmt, 0);
+    }
+
   if ((flags & (ECF_CONST | ECF_NOVOPS))
       && !(flags & ECF_LOOPING_CONST_OR_PURE))
     {
@@ -4065,7 +4178,7 @@ ignore_edge (struct cgraph_edge *e)
   if (!e->inline_failed)
     return false;
   enum availability avail;
-  cgraph_node *callee = e->callee->function_or_virtual_thunk_symbol
+  cgraph_node *callee = e->callee->ultimate_alias_target
 			  (&avail, e->caller);
 
   return (avail <= AVAIL_INTERPOSABLE
@@ -4088,7 +4201,7 @@ compute_parm_map (cgraph_edge *callee_edge, vec<modref_parm_map> *parm_map)
       class ipa_call_summary *es
 	     = ipa_call_summaries->get (callee_edge);
       cgraph_node *callee
-	 = callee_edge->callee->function_or_virtual_thunk_symbol
+	 = callee_edge->callee->ultimate_alias_target
 			      (NULL, callee_edge->caller);
 
       caller_parms_info
@@ -4578,7 +4691,7 @@ modref_propagate_in_scc (cgraph_node *component_node)
 
 	      /* Get the callee and its summary.  */
 	      enum availability avail;
-	      callee = callee_edge->callee->function_or_virtual_thunk_symbol
+	      callee = callee_edge->callee->ultimate_alias_target
 			 (&avail, cur);
 
 	      /* It is not necessary to re-process calls outside of the
@@ -5021,7 +5134,7 @@ modref_propagate_flags_in_scc (cgraph_node *component_node)
 
 	      /* Get the callee and its summary.  */
 	      enum availability avail;
-	      callee = callee_edge->callee->function_or_virtual_thunk_symbol
+	      callee = callee_edge->callee->ultimate_alias_target
 			 (&avail, cur);
 
 	      /* It is not necessary to re-process calls outside of the
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 3c253e2843f..32cdc4b9590 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2547,6 +2547,30 @@ refs_output_dependent_p (tree store1, tree store2)
   return refs_may_alias_p_1 (&r1, &r2, false);
 }
 
+/* Return ture if REF may access global memory.  */
+
+bool
+ref_may_access_global_memory_p (ao_ref *ref)
+{
+  if (!ref->ref)
+    return true;
+  tree base = ao_ref_base (ref);
+  if (TREE_CODE (base) == MEM_REF
+      || TREE_CODE (base) == TARGET_MEM_REF)
+    {
+      if (ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0)))
+	return true;
+    }
+  else
+    {
+      if (!auto_var_in_fn_p (base, current_function_decl)
+	  || pt_solution_includes (&cfun->gimple_df->escaped,
+				   base))
+	return true;
+    }
+  return false;
+}
+
 /* Returns true if and only if REF may alias any access stored in TT.
    IF TBAA_P is true, use TBAA oracle.  */
 
@@ -2555,6 +2579,7 @@ modref_may_conflict (const gcall *stmt,
 		     modref_tree <alias_set_type> *tt, ao_ref *ref, bool tbaa_p)
 {
   alias_set_type base_set, ref_set;
+  bool global_memory_ok = false;
 
   if (tt->every_base)
     return true;
@@ -2605,6 +2630,17 @@ modref_may_conflict (const gcall *stmt,
 	      if (num_tests >= max_tests)
 		return true;
 
+	      if (access_node.parm_index == MODREF_GLOBAL_MEMORY_PARM)
+		{
+		  if (global_memory_ok)
+		    continue;
+		  if (ref_may_access_global_memory_p (ref))
+		    return true;
+		  global_memory_ok = true;
+		  num_tests++;
+		  continue;
+		}
+
 	      tree arg = access_node.get_call_arg (stmt);
 	      if (!arg)
 		return true;


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-12-09 19:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-09 19:12 [gcc(refs/users/hubicka/heads/honza-gcc-benchmark-branch-v2)] Experimental modref changeset Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).