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

https://gcc.gnu.org/g:3e40f07606c458ec6f05c2c9ea04be828bc4aeca

commit 3e40f07606c458ec6f05c2c9ea04be828bc4aeca
Author: Jan Hubicka <jh@suse.cz>
Date:   Sat Dec 11 20:48:26 2021 +0100

    Improved modref

Diff:
---
 gcc/doc/invoke.texi   |   8 +++
 gcc/ipa-modref-tree.c |   7 ++-
 gcc/ipa-modref-tree.h |  21 ++++---
 gcc/ipa-modref.c      | 161 +++++++++++++++++++++++++++++---------------------
 4 files changed, 122 insertions(+), 75 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3bddfbaae6a..cd03fd93c7c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13587,6 +13587,14 @@ The maximum number of backtrack attempts the scheduler should make
 when modulo scheduling a loop.  Larger values can exponentially increase
 compilation time.
 
+@item max-inline-functions-called-once-loop-depth
+Maximal loop depth of a call considered by inline heuristics that tries to
+inline all functions called once.
+
+@item max-inline-functions-called-once-insns
+Maximal estimated size of functions produced while inlining functions called
+once.
+
 @item max-inline-insns-single
 Several parameters control the tree inliner used in GCC@.  This number sets the
 maximum number of instructions (counted in GCC's internal representation) in a
diff --git a/gcc/ipa-modref-tree.c b/gcc/ipa-modref-tree.c
index 47fd929864e..8b86757c632 100644
--- a/gcc/ipa-modref-tree.c
+++ b/gcc/ipa-modref-tree.c
@@ -36,7 +36,8 @@ modref_access_node::operator == (modref_access_node &a) const
 {
   if (parm_index != a.parm_index)
     return false;
-  if (parm_index != MODREF_UNKNOWN_PARM)
+  if (parm_index != MODREF_UNKNOWN_PARM
+      && parm_index != MODREF_GLOBAL_MEMORY_PARM)
     {
       if (parm_offset_known != a.parm_offset_known)
 	return false;
@@ -613,7 +614,9 @@ modref_access_node::insert (vec <modref_access_node, va_gc> *&accesses,
 bool
 modref_access_node::range_info_useful_p () const
 {
-  return parm_index != MODREF_UNKNOWN_PARM && parm_offset_known
+  return parm_index != MODREF_UNKNOWN_PARM
+	 && parm_index != MODREF_GLOBAL_MEMORY_PARM
+	 && parm_offset_known
 	 && (known_size_p (size)
 	     || known_size_p (max_size)
 	     || known_ge (offset, 0));
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index 2145308fda4..4b68475b30e 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -88,6 +88,7 @@ struct GTY(()) modref_access_node
   bool useful_for_kill_p () const
     {
       return parm_offset_known && parm_index != MODREF_UNKNOWN_PARM
+	     && parm_index != MODREF_GLOBAL_MEMORY_PARM
 	     && parm_index != MODREF_RETSLOT_PARM && known_size_p (size)
 	     && known_eq (max_size, size);
     }
@@ -526,7 +527,8 @@ struct GTY((user)) modref_tree
 	      unsigned int max_accesses,
 	      modref_tree <T> *other, vec <modref_parm_map> *parm_map,
 	      modref_parm_map *static_chain_map,
-	      bool record_accesses)
+	      bool record_accesses,
+	      bool promote_unknown_to_global = false)
   {
     if (!other || every_base)
       return false;
@@ -581,11 +583,11 @@ struct GTY((user)) modref_tree
 		  {
 		    modref_access_node a = *access_node;
 
-		    if (a.parm_index != MODREF_UNKNOWN_PARM && parm_map)
+		    if (a.parm_index != MODREF_UNKNOWN_PARM
+			&& a.parm_index != MODREF_GLOBAL_MEMORY_PARM
+			&& parm_map)
 		      {
-			if (a.parm_index == MODREF_GLOBAL_MEMORY_PARM)
-			  ;
-			else if (a.parm_index >= (int)parm_map->length ())
+			if (a.parm_index >= (int)parm_map->length ())
 			  a.parm_index = MODREF_UNKNOWN_PARM;
 			else
 			  {
@@ -600,6 +602,9 @@ struct GTY((user)) modref_tree
 			    a.parm_index = m.parm_index;
 			  }
 		      }
+		    if (a.parm_index == MODREF_UNKNOWN_PARM
+			&& promote_unknown_to_global)
+		      a.parm_index = MODREF_GLOBAL_MEMORY_PARM;
 		    changed |= insert (max_bases, max_refs, max_accesses,
 				       base_node->base, ref_node->ref,
 				       a, record_accesses);
@@ -618,12 +623,14 @@ struct GTY((user)) modref_tree
   bool merge (tree fndecl,
 	      modref_tree <T> *other, vec <modref_parm_map> *parm_map,
 	      modref_parm_map *static_chain_map,
-	      bool record_accesses)
+	      bool record_accesses,
+	      bool promote_unknown_to_global = false)
   {
      return merge (opt_for_fn (fndecl, param_modref_max_bases),
 		   opt_for_fn (fndecl, param_modref_max_refs),
 		   opt_for_fn (fndecl, param_modref_max_accesses),
-		   other, parm_map, static_chain_map, record_accesses);
+		   other, parm_map, static_chain_map, record_accesses,
+		   promote_unknown_to_global);
   }
 
   /* Copy OTHER to THIS.  */
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 1cf9609e8f3..1c0b16f7040 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -869,6 +869,76 @@ parm_map_for_ptr (tree op)
   return parm_map;
 }
 
+/* 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, bool use_escape, bool load)
+{
+  if (flags & EAF_UNUSED)
+    return true;
+  if (load && (flags & EAF_NO_DIRECT_READ))
+    return true;
+  if (!load
+      && (flags & (EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER))
+	  == (EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER))
+    return true;
+  if (use_escape && !(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,
+			       bool use_escape, bool load)
+{
+  int implicit_flags = 0;
+  tree callee = gimple_call_fndecl (call);
+
+  /* Do not use escape info when it may get imroved: that is when we
+     run in IPA mode, or call is indirect (and may be promoted to direct)
+     or call is recursive.  */
+  if (!callee)
+    use_escape = false;
+  else if (recursive_call_p (current_function_decl, callee))
+    use_escape = 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,
+		      use_escape, load))
+    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,
+		     use_escape, load))
+      return true;
+  return false;
+}
+
+
 /* Analyze memory accesses (loads, stores and kills) performed
    by the function.  Set also side_effects, calls_interposable
    and nondeterminism flags.  */
@@ -1195,7 +1265,8 @@ modref_access_analysis::merge_call_side_effects
 	 (gimple *stmt, modref_summary *callee_summary,
 	  cgraph_node *callee_node, bool record_adjustments)
 {
-  int flags = gimple_call_flags (stmt);
+  gcall *call = as_a <gcall *> (stmt);
+  int flags = gimple_call_flags (call);
 
   /* Nothing to do for non-looping cont functions.  */
   if ((flags & (ECF_CONST | ECF_NOVOPS))
@@ -1258,10 +1329,10 @@ modref_access_analysis::merge_call_side_effects
     fprintf (dump_file, "   Parm map:");
 
   auto_vec <modref_parm_map, 32> parm_map;
-  parm_map.safe_grow_cleared (gimple_call_num_args (stmt), true);
-  for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
+  parm_map.safe_grow_cleared (gimple_call_num_args (call), true);
+  for (unsigned i = 0; i < gimple_call_num_args (call); i++)
     {
-      parm_map[i] = parm_map_for_ptr (gimple_call_arg (stmt, i));
+      parm_map[i] = parm_map_for_ptr (gimple_call_arg (call, i));
       if (dump_file)
 	{
 	  fprintf (dump_file, " %i", parm_map[i].parm_index);
@@ -1275,9 +1346,9 @@ modref_access_analysis::merge_call_side_effects
     }
 
   modref_parm_map chain_map;
-  if (gimple_call_chain (stmt))
+  if (gimple_call_chain (call))
     {
-      chain_map = parm_map_for_ptr (gimple_call_chain (stmt));
+      chain_map = parm_map_for_ptr (gimple_call_chain (call));
       if (dump_file)
 	{
 	  fprintf (dump_file, "static chain %i", chain_map.parm_index);
@@ -1297,7 +1368,7 @@ modref_access_analysis::merge_call_side_effects
   if (m_always_executed
       && callee_summary->kills.length ()
       && (!cfun->can_throw_non_call_exceptions
-	  || !stmt_could_throw_p (cfun, stmt)))
+	  || !stmt_could_throw_p (cfun, call)))
     {
       /* Watch for self recursive updates.  */
       auto_vec<modref_access_node, 32> saved_kills;
@@ -1330,14 +1401,18 @@ modref_access_analysis::merge_call_side_effects
   changed |= m_summary->loads->merge (current_function_decl,
 				      callee_summary->loads,
 				      &parm_map, &chain_map,
-				      record_adjustments);
+				      record_adjustments,
+				      !may_access_nonescaping_parm_p
+					 (call, flags, !m_ipa, true));
   /* Merge in stores.  */
   if (!ignore_stores_p (current_function_decl, flags))
     {
       changed |= m_summary->stores->merge (current_function_decl,
 					   callee_summary->stores,
 					   &parm_map, &chain_map,
-					   record_adjustments);
+					   record_adjustments,
+					   !may_access_nonescaping_parm_p
+					       (call, flags, !m_ipa, false));
       if (!m_summary->writes_errno
 	  && callee_summary->writes_errno)
 	{
@@ -1385,58 +1460,6 @@ 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.   */
@@ -1471,12 +1494,18 @@ modref_access_analysis::process_fnspec (gcall *call)
 		 IDENTIFIER_POINTER (DECL_NAME (gimple_call_fndecl (call))));
       if (!ignore_stores_p (current_function_decl, flags))
 	{
-	  record_global_memory_store ();
-	  record_global_memory_load ();
+	  if (!may_access_nonescaping_parm_p (call, flags, !m_ipa, false))
+	    record_global_memory_store ();
+	  else
+	    record_unknown_store ();
+	  if (!may_access_nonescaping_parm_p (call, flags, !m_ipa, true))
+	    record_global_memory_load ();
+	  else
+	    record_unknown_load ();
 	}
       else
 	{
-	  if (!may_access_nonescaping_parm_p (call, flags))
+	  if (!may_access_nonescaping_parm_p (call, flags, !m_ipa, true))
 	    record_global_memory_load ();
 	  else
 	    record_unknown_load ();
@@ -1486,7 +1515,7 @@ modref_access_analysis::process_fnspec (gcall *call)
   /* Process fnspec.  */
   if (fnspec.global_memory_read_p ())
     {
-      if (may_access_nonescaping_parm_p (call, flags))
+      if (may_access_nonescaping_parm_p (call, flags, !m_ipa, true))
 	record_unknown_load ();
       else
 	record_global_memory_load ();
@@ -1523,7 +1552,7 @@ modref_access_analysis::process_fnspec (gcall *call)
     return;
   if (fnspec.global_memory_written_p ())
     {
-      if (may_access_nonescaping_parm_p (call, flags))
+      if (may_access_nonescaping_parm_p (call, flags, !m_ipa, false))
 	record_unknown_store ();
       else
 	record_global_memory_store ();


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

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

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-12 10:38 [gcc(refs/users/hubicka/heads/honza-gcc-benchmark-branch-v2)] Improved modref 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).