public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-4988] Add loads/stores relative to static chain in ipa-modref
@ 2021-11-08  6:53 Jan Hubicka
  0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2021-11-08  6:53 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:1f3a33633dd06a8e4861180ab20c9136361c69e6

commit r12-4988-g1f3a33633dd06a8e4861180ab20c9136361c69e6
Author: Jan Hubicka <hubicka@ucw.cz>
Date:   Mon Nov 8 07:52:45 2021 +0100

    Add loads/stores relative to static chain in ipa-modref
    
    Adds tracking of accesses relative to static chain into modref
    load/stores analysis.  This helps some Fortran benchmarks however it is still
    quite limited.  One problem is that we never discover functions with nested
    functions as const, pure or not accessing global memory because it contains
    __builtin_dward_cfa call which we believe to be non-pure.
    
    Bootstrapped/regtested x86_64-linux.  Plan to commit it tomorrow if there are
    no complains and once periodic testers picks today modref changes.
    
    Honza
    
    gcc/ChangeLog:
    
            * ipa-modref-tree.h (enum modref_special_parms): New enum.
            (struct modref_access_node): update for special parms.
            (struct modref_ref_node): Likewise.
            (struct modref_parm_map): Likewise.
            (struct modref_tree): Likewise.
            * ipa-modref.c (dump_access): Likewise.
            (get_access): Detect static chain.
            (parm_map_for_arg): Take tree as arg instead of
            stmt and index.
            (merge_call_side_effects): Compute map for static chain.
            (process_fnspec): Update.
            (struct escape_point): Remove retslot_arg and static_chain_arg.
            (analyze_parms): Update.
            (compute_parm_map): Update.
            (propagate_unknown_call): Update.
            (modref_propagate_in_scc): Update.
            (modref_merge_call_site_flags): Update.
            (ipa_merge_modref_summary_after_inlining): Update.
            * tree-ssa-alias.c (modref_may_conflict): Handle static chain.
            * ipa-modref-tree.c (test_merge): Update.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/tree-ssa/modref-12.c: New test.

Diff:
---
 gcc/ipa-modref-tree.c                     |   2 +-
 gcc/ipa-modref-tree.h                     |  71 ++++++++------
 gcc/ipa-modref.c                          | 152 +++++++++++++++++-------------
 gcc/testsuite/gcc.dg/tree-ssa/modref-12.c |  16 ++++
 gcc/tree-ssa-alias.c                      |  12 ++-
 5 files changed, 158 insertions(+), 95 deletions(-)

diff --git a/gcc/ipa-modref-tree.c b/gcc/ipa-modref-tree.c
index 8d147a18aed..d0ee487f9fa 100644
--- a/gcc/ipa-modref-tree.c
+++ b/gcc/ipa-modref-tree.c
@@ -138,7 +138,7 @@ test_merge ()
   t2->insert (3, 4, a, false);
   t2->insert (3, 5, a, false);
 
-  t1->merge (t2, NULL, false);
+  t1->merge (t2, NULL, NULL, false);
 
   ASSERT_FALSE (t1->every_base);
   ASSERT_NE (t1->bases, NULL);
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index 54ae9e1df4e..be5efcbb68f 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -42,6 +42,18 @@ along with GCC; see the file COPYING3.  If not see
 
 struct ipa_modref_summary;
 
+/* parm indexes greater than 0 are normal parms.
+   Some negative values have special meaning.  */
+enum modref_special_parms {
+  MODREF_UNKNOWN_PARM = -1,
+  MODREF_STATIC_CHAIN_PARM = -2,
+  MODREF_RETSLOT_PARM = -3,
+  /* 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
+};
+
 /* Memory access.  */
 struct GTY(()) modref_access_node
 {
@@ -65,12 +77,12 @@ struct GTY(()) modref_access_node
   /* Return true if access node holds no useful info.  */
   bool useful_p () const
     {
-      return parm_index != -1;
+      return parm_index != MODREF_UNKNOWN_PARM;
     }
   /* Return true if range info is useful.  */
   bool range_info_useful_p () const
     {
-      return parm_index != -1 && parm_offset_known
+      return parm_index != MODREF_UNKNOWN_PARM && parm_offset_known
 	     && (known_size_p (size)
 		 || known_size_p (max_size)
 		 || known_ge (offset, 0));
@@ -80,7 +92,7 @@ struct GTY(()) modref_access_node
     {
       if (parm_index != a.parm_index)
 	return false;
-      if (parm_index >= 0)
+      if (parm_index != MODREF_UNKNOWN_PARM)
 	{
 	  if (parm_offset_known != a.parm_offset_known)
 	    return false;
@@ -101,7 +113,7 @@ struct GTY(()) modref_access_node
   bool contains (const modref_access_node &a) const
     {
       poly_int64 aoffset_adj = 0;
-      if (parm_index >= 0)
+      if (parm_index != MODREF_UNKNOWN_PARM)
 	{
 	  if (parm_index != a.parm_index)
 	    return false;
@@ -211,7 +223,7 @@ struct GTY(()) modref_access_node
 
       /* We assume that containment was tested earlier.  */
       gcc_checking_assert (!contains (a) && !a.contains (*this));
-      if (parm_index >= 0)
+      if (parm_index != MODREF_UNKNOWN_PARM)
 	{
 	  if (parm_index != a.parm_index)
 	    return false;
@@ -350,8 +362,8 @@ struct GTY(()) modref_access_node
     {
       if (parm_index != a.parm_index)
 	{
-	  gcc_checking_assert (parm_index != -1);
-	  parm_index = -1;
+	  gcc_checking_assert (parm_index != MODREF_UNKNOWN_PARM);
+	  parm_index = MODREF_UNKNOWN_PARM;
 	  return;
 	}
 
@@ -454,7 +466,7 @@ private:
 
 /* Access node specifying no useful info.  */
 const modref_access_node unspecified_modref_access_node
-		 = {0, -1, -1, 0, -1, false, 0};
+		 = {0, -1, -1, 0, MODREF_UNKNOWN_PARM, false, 0};
 
 template <typename T>
 struct GTY((user)) modref_ref_node
@@ -506,6 +518,12 @@ struct GTY((user)) modref_ref_node
     size_t i, j;
     modref_access_node *a2;
 
+    /* Only the following kind of paramters needs to be tracked.
+       We do not track return slots because they are seen as a direct store
+       in the caller.  */
+    gcc_checking_assert (a.parm_index >= 0
+			 || a.parm_index == MODREF_STATIC_CHAIN_PARM
+			 || a.parm_index == MODREF_UNKNOWN_PARM);
     if (flag_checking)
       verify ();
 
@@ -734,9 +752,7 @@ struct GTY((user)) modref_base_node
 struct modref_parm_map
 {
   /* Index of parameter we translate to.
-     -1 indicates that parameter is unknown
-     -2 indicates that parameter points to local memory and access can be
-	discarded.  */
+     Values from special_params enum are permitted too.  */
   int parm_index;
   bool parm_offset_known;
   poly_int64 parm_offset;
@@ -946,10 +962,11 @@ struct GTY((user)) modref_tree
  }
 
   /* Merge OTHER into the tree.
-     PARM_MAP, if non-NULL, maps parm indexes of callee to caller.  -2 is used
-     to signalize that parameter is local and does not need to be tracked.
+     PARM_MAP, if non-NULL, maps parm indexes of callee to caller.
+     Similar CHAIN_MAP, if non-NULL, maps static chain of callee to caller.
      Return true if something has changed.  */
   bool merge (modref_tree <T> *other, vec <modref_parm_map> *parm_map,
+	      modref_parm_map *static_chain_map,
 	      bool record_accesses)
   {
     if (!other || every_base)
@@ -1003,21 +1020,21 @@ struct GTY((user)) modref_tree
 		  {
 		    modref_access_node a = *access_node;
 
-		    if (a.parm_index != -1 && parm_map)
+		    if (a.parm_index != MODREF_UNKNOWN_PARM && parm_map)
 		      {
 			if (a.parm_index >= (int)parm_map->length ())
-			  a.parm_index = -1;
-			else if ((*parm_map) [a.parm_index].parm_index == -2)
-			  continue;
+			  a.parm_index = MODREF_UNKNOWN_PARM;
 			else
 			  {
-			    a.parm_offset
-				 += (*parm_map) [a.parm_index].parm_offset;
-			    a.parm_offset_known
-				 &= (*parm_map)
-					 [a.parm_index].parm_offset_known;
-			    a.parm_index
-				 = (*parm_map) [a.parm_index].parm_index;
+			    modref_parm_map &m
+				    = a.parm_index == MODREF_STATIC_CHAIN_PARM
+				      ? *static_chain_map
+				      : (*parm_map) [a.parm_index];
+			    if (m.parm_index == MODREF_LOCAL_MEMORY_PARM)
+			      continue;
+			    a.parm_offset += m.parm_offset;
+			    a.parm_offset_known &= m.parm_offset_known;
+			    a.parm_index = m.parm_index;
 			  }
 		      }
 		    changed |= insert (base_node->base, ref_node->ref, a,
@@ -1033,7 +1050,7 @@ struct GTY((user)) modref_tree
   /* Copy OTHER to THIS.  */
   void copy_from (modref_tree <T> *other)
   {
-    merge (other, NULL, false);
+    merge (other, NULL, NULL, false);
   }
 
   /* Search BASE in tree; return NULL if failed.  */
@@ -1065,7 +1082,7 @@ 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 < 0)
+	      if (access_node->parm_index == MODREF_UNKNOWN_PARM)
 		return true;
 	  }
       }
@@ -1127,7 +1144,7 @@ struct GTY((user)) modref_tree
 		  if (access_node->parm_index < (int)map->length ())
 		    access_node->parm_index = (*map)[access_node->parm_index];
 		  else
-		    access_node->parm_index = -1;
+		    access_node->parm_index = MODREF_UNKNOWN_PARM;
 		}
 	  }
       }
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 4e64ee5d9fd..4429bcea803 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -426,9 +426,14 @@ static void
 dump_access (modref_access_node *a, FILE *out)
 {
   fprintf (out, "          access:");
-  if (a->parm_index != -1)
+  if (a->parm_index != MODREF_UNKNOWN_PARM)
     {
-      fprintf (out, " Parm %i", a->parm_index);
+      if (a->parm_index >= 0)
+	fprintf (out, " Parm %i", a->parm_index);
+      else if (a->parm_index == MODREF_STATIC_CHAIN_PARM)
+	fprintf (out, " Static chain");
+      else
+	gcc_unreachable ();
       if (a->parm_offset_known)
 	{
 	  fprintf (out, " param offset:");
@@ -697,40 +702,40 @@ get_access (ao_ref *ref)
 
   base = ao_ref_base (ref);
   modref_access_node a = {ref->offset, ref->size, ref->max_size,
-			  0, -1, false, 0};
+			  0, MODREF_UNKNOWN_PARM, false, 0};
   if (TREE_CODE (base) == MEM_REF || TREE_CODE (base) == TARGET_MEM_REF)
     {
       tree memref = base;
       base = TREE_OPERAND (base, 0);
+
       if (TREE_CODE (base) == SSA_NAME
 	  && SSA_NAME_IS_DEFAULT_DEF (base)
 	  && TREE_CODE (SSA_NAME_VAR (base)) == PARM_DECL)
 	{
 	  a.parm_index = 0;
-	  for (tree t = DECL_ARGUMENTS (current_function_decl);
-	       t != SSA_NAME_VAR (base); t = DECL_CHAIN (t))
-	    {
-	      if (!t)
-		{
-		  a.parm_index = -1;
-		  break;
-		}
-	      a.parm_index++;
-	    }
-	  if (TREE_CODE (memref) == MEM_REF)
-	    {
-	      a.parm_offset_known
-		 = wi::to_poly_wide (TREE_OPERAND
-					 (memref, 1)).to_shwi (&a.parm_offset);
-	    }
+	  if (cfun->static_chain_decl
+	      && base == ssa_default_def (cfun, cfun->static_chain_decl))
+	    a.parm_index = MODREF_STATIC_CHAIN_PARM;
 	  else
-	    a.parm_offset_known = false;
+	    for (tree t = DECL_ARGUMENTS (current_function_decl);
+		 t != SSA_NAME_VAR (base); t = DECL_CHAIN (t))
+	      a.parm_index++;
+	}
+      else
+	a.parm_index = MODREF_UNKNOWN_PARM;
+
+      if (a.parm_index != MODREF_UNKNOWN_PARM
+	  && TREE_CODE (memref) == MEM_REF)
+	{
+	  a.parm_offset_known
+	     = wi::to_poly_wide (TREE_OPERAND
+				     (memref, 1)).to_shwi (&a.parm_offset);
 	}
       else
-	a.parm_index = -1;
+	a.parm_offset_known = false;
     }
   else
-    a.parm_index = -1;
+    a.parm_index = MODREF_UNKNOWN_PARM;
   return a;
 }
 
@@ -858,12 +863,11 @@ ignore_stores_p (tree caller, int flags)
   return false;
 }
 
-/* Determine parm_map for argument I of STMT.  */
+/* Determine parm_map for argument OP.  */
 
 modref_parm_map
-parm_map_for_arg (gimple *stmt, int i)
+parm_map_for_arg (tree op)
 {
-  tree op = gimple_call_arg (stmt, i);
   bool offset_known;
   poly_int64 offset;
   struct modref_parm_map parm_map;
@@ -882,7 +886,7 @@ parm_map_for_arg (gimple *stmt, int i)
 	{
 	  if (!t)
 	    {
-	      index = -1;
+	      index = MODREF_UNKNOWN_PARM;
 	      break;
 	    }
 	  index++;
@@ -892,9 +896,9 @@ parm_map_for_arg (gimple *stmt, int i)
       parm_map.parm_offset = offset;
     }
   else if (points_to_local_or_readonly_memory_p (op))
-    parm_map.parm_index = -2;
+    parm_map.parm_index = MODREF_LOCAL_MEMORY_PARM;
   else
-    parm_map.parm_index = -1;
+    parm_map.parm_index = MODREF_UNKNOWN_PARM;
   return parm_map;
 }
 
@@ -911,6 +915,7 @@ merge_call_side_effects (modref_summary *cur_summary,
 			 bool record_adjustments)
 {
   auto_vec <modref_parm_map, 32> parm_map;
+  modref_parm_map chain_map;
   bool changed = false;
 
   /* We can not safely optimize based on summary of callee if it does
@@ -931,7 +936,7 @@ merge_call_side_effects (modref_summary *cur_summary,
   parm_map.safe_grow_cleared (gimple_call_num_args (stmt), true);
   for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
     {
-      parm_map[i] = parm_map_for_arg (stmt, i);
+      parm_map[i] = parm_map_for_arg (gimple_call_arg (stmt, i));
       if (dump_file)
 	{
 	  fprintf (dump_file, " %i", parm_map[i].parm_index);
@@ -943,16 +948,30 @@ merge_call_side_effects (modref_summary *cur_summary,
 	    }
 	}
     }
+  if (gimple_call_chain (stmt))
+    {
+      chain_map = parm_map_for_arg (gimple_call_chain (stmt));
+      if (dump_file)
+	{
+	  fprintf (dump_file, "static chain %i", chain_map.parm_index);
+	  if (chain_map.parm_offset_known)
+	    {
+	      fprintf (dump_file, " offset:");
+	      print_dec ((poly_int64_pod)chain_map.parm_offset,
+			 dump_file, SIGNED);
+	    }
+	}
+    }
   if (dump_file)
     fprintf (dump_file, "\n");
 
   /* Merge with callee's summary.  */
   changed |= cur_summary->loads->merge (callee_summary->loads, &parm_map,
-					record_adjustments);
+					&chain_map, record_adjustments);
   if (!ignore_stores)
     {
       changed |= cur_summary->stores->merge (callee_summary->stores,
-					     &parm_map,
+					     &parm_map, &chain_map,
 					     record_adjustments);
       if (!cur_summary->writes_errno
 	  && callee_summary->writes_errno)
@@ -1078,11 +1097,12 @@ process_fnspec (modref_summary *cur_summary,
 	else if (!fnspec.arg_specified_p (i)
 		 || fnspec.arg_maybe_read_p (i))
 	  {
-	    modref_parm_map map = parm_map_for_arg (call, i);
+	    modref_parm_map map = parm_map_for_arg
+					(gimple_call_arg (call, i));
 
-	    if (map.parm_index == -2)
+	    if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
 	      continue;
-	    if (map.parm_index == -1)
+	    if (map.parm_index == MODREF_UNKNOWN_PARM)
 	      {
 		collapse_loads (cur_summary, cur_summary_lto);
 		break;
@@ -1113,11 +1133,12 @@ process_fnspec (modref_summary *cur_summary,
 	else if (!fnspec.arg_specified_p (i)
 		 || fnspec.arg_maybe_written_p (i))
 	  {
-	    modref_parm_map map = parm_map_for_arg (call, i);
+	    modref_parm_map map = parm_map_for_arg
+					 (gimple_call_arg (call, i));
 
-	    if (map.parm_index == -2)
+	    if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
 	      continue;
-	    if (map.parm_index == -1)
+	    if (map.parm_index == MODREF_UNKNOWN_PARM)
 	      {
 		collapse_stores (cur_summary, cur_summary_lto);
 		break;
@@ -1429,12 +1450,6 @@ deref_flags (int flags, bool ignore_stores)
 
 struct escape_point
 {
-  /* Extra hidden args we keep track of.  */
-  enum hidden_args
-  {
-    retslot_arg = -1,
-    static_chain_arg = -2
-  };
   /* Value escapes to this call.  */
   gcall *call;
   /* Argument it escapes to.  */
@@ -2410,7 +2425,7 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
 	  if (summary_lto)
 	    summary_lto->retslot_flags = flags;
 	  eaf_analysis.record_escape_points (retslot,
-					     escape_point::retslot_arg, flags);
+					     MODREF_RETSLOT_PARM, flags);
 	}
     }
   if (static_chain)
@@ -2425,7 +2440,7 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
 	  if (summary_lto)
 	    summary_lto->static_chain_flags = flags;
 	  eaf_analysis.record_escape_points (static_chain,
-					     escape_point::static_chain_arg,
+					     MODREF_STATIC_CHAIN_PARM,
 					     flags);
 	}
     }
@@ -3586,7 +3601,7 @@ compute_parm_map (cgraph_edge *callee_edge, vec<modref_parm_map> *parm_map)
 	{
 	  if (es && es->param[i].points_to_local_or_readonly_memory)
 	    {
-	      (*parm_map)[i].parm_index = -2;
+	      (*parm_map)[i].parm_index = MODREF_LOCAL_MEMORY_PARM;
 	      continue;
 	    }
 
@@ -3600,7 +3615,7 @@ compute_parm_map (cgraph_edge *callee_edge, vec<modref_parm_map> *parm_map)
 						 (callee_pi, i));
 	      if (cst && points_to_local_or_readonly_memory_p (cst))
 		{
-		  (*parm_map)[i].parm_index = -2;
+		  (*parm_map)[i].parm_index = MODREF_LOCAL_MEMORY_PARM;
 		  continue;
 		}
 	    }
@@ -3798,9 +3813,9 @@ propagate_unknown_call (cgraph_node *node,
 		   || fnspec.arg_maybe_read_p (i))
 	    {
 	      modref_parm_map map = parm_map[i];
-	      if (map.parm_index == -2)
+	      if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
 		continue;
-	      if (map.parm_index == -1)
+	      if (map.parm_index == MODREF_UNKNOWN_PARM)
 		{
 		  collapse_loads (cur_summary, cur_summary_lto);
 		  break;
@@ -3828,9 +3843,9 @@ propagate_unknown_call (cgraph_node *node,
 		   || fnspec.arg_maybe_written_p (i))
 	    {
 	      modref_parm_map map = parm_map[i];
-	      if (map.parm_index == -2)
+	      if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
 		continue;
-	      if (map.parm_index == -1)
+	      if (map.parm_index == MODREF_UNKNOWN_PARM)
 		{
 		  collapse_stores (cur_summary, cur_summary_lto);
 		  break;
@@ -4030,6 +4045,10 @@ modref_propagate_in_scc (cgraph_node *component_node)
 
 
 	      auto_vec <modref_parm_map, 32> parm_map;
+	      modref_parm_map chain_map;
+	      /* TODO: Once we get jump functions for static chains we could
+		 compute this.  */
+	      chain_map.parm_index = MODREF_UNKNOWN_PARM;
 
 	      compute_parm_map (callee_edge, &parm_map);
 
@@ -4037,12 +4056,13 @@ modref_propagate_in_scc (cgraph_node *component_node)
 	      if (callee_summary)
 		{
 		  changed |= cur_summary->loads->merge
-				  (callee_summary->loads, &parm_map, !first);
+				  (callee_summary->loads, &parm_map,
+				   &chain_map, !first);
 		  if (!ignore_stores)
 		    {
 		      changed |= cur_summary->stores->merge
 				      (callee_summary->stores, &parm_map,
-				       !first);
+				       &chain_map, !first);
 		      if (!cur_summary->writes_errno
 			  && callee_summary->writes_errno)
 			{
@@ -4055,12 +4075,12 @@ modref_propagate_in_scc (cgraph_node *component_node)
 		{
 		  changed |= cur_summary_lto->loads->merge
 				  (callee_summary_lto->loads, &parm_map,
-				   !first);
+				   &chain_map, !first);
 		  if (!ignore_stores)
 		    {
 		      changed |= cur_summary_lto->stores->merge
 				      (callee_summary_lto->stores, &parm_map,
-				       !first);
+				       &chain_map, !first);
 		      if (!cur_summary_lto->writes_errno
 			  && callee_summary_lto->writes_errno)
 			{
@@ -4223,9 +4243,9 @@ modref_merge_call_site_flags (escape_summary *sum,
       if (!(flags & EAF_UNUSED)
 	  && cur_summary && ee->parm_index < (int)cur_summary->arg_flags.length ())
 	{
-	  eaf_flags_t &f = ee->parm_index == escape_point::retslot_arg
+	  eaf_flags_t &f = ee->parm_index == MODREF_RETSLOT_PARM
 			   ? cur_summary->retslot_flags
-			   : ee->parm_index == escape_point::static_chain_arg
+			   : ee->parm_index == MODREF_STATIC_CHAIN_PARM
 			   ? cur_summary->static_chain_flags
 			   : cur_summary->arg_flags[ee->parm_index];
 	  if ((f & flags) != f)
@@ -4240,9 +4260,9 @@ modref_merge_call_site_flags (escape_summary *sum,
 	  && cur_summary_lto
 	  && ee->parm_index < (int)cur_summary_lto->arg_flags.length ())
 	{
-	  eaf_flags_t &f = ee->parm_index == escape_point::retslot_arg
+	  eaf_flags_t &f = ee->parm_index == MODREF_RETSLOT_PARM
 			   ? cur_summary_lto->retslot_flags
-			   : ee->parm_index == escape_point::static_chain_arg
+			   : ee->parm_index == MODREF_STATIC_CHAIN_PARM
 			   ? cur_summary_lto->static_chain_flags
 			   : cur_summary_lto->arg_flags[ee->parm_index];
 	  if ((f & flags_lto) != f)
@@ -4428,24 +4448,30 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
   if (callee_info || callee_info_lto)
     {
       auto_vec <modref_parm_map, 32> parm_map;
+      modref_parm_map chain_map;
+      /* TODO: Once we get jump functions for static chains we could
+	 compute this.  */
+      chain_map.parm_index = MODREF_UNKNOWN_PARM;
 
       compute_parm_map (edge, &parm_map);
 
       if (!ignore_stores)
 	{
 	  if (to_info && callee_info)
-	    to_info->stores->merge (callee_info->stores, &parm_map, false);
+	    to_info->stores->merge (callee_info->stores, &parm_map,
+				    &chain_map, false);
 	  if (to_info_lto && callee_info_lto)
 	    to_info_lto->stores->merge (callee_info_lto->stores, &parm_map,
-					false);
+					&chain_map, false);
 	}
       if (!(flags & (ECF_CONST | ECF_NOVOPS)))
 	{
 	  if (to_info && callee_info)
-	    to_info->loads->merge (callee_info->loads, &parm_map, false);
+	    to_info->loads->merge (callee_info->loads, &parm_map,
+				   &chain_map, false);
 	  if (to_info_lto && callee_info_lto)
 	    to_info_lto->loads->merge (callee_info_lto->loads, &parm_map,
-				       false);
+				       &chain_map, false);
 	}
     }
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-12.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-12.c
new file mode 100644
index 00000000000..f8ce0470c4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-12.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized"  } */
+void foo ();
+int
+test()
+{
+  struct {int a,b;} a = {0,0};
+  __attribute__ ((noinline))
+  void nested ()
+  {
+	  a.b++;
+  }
+  nested ();
+  return a.a;
+}
+/* { dg-final { scan-tree-dump "return 0" "optimized"} } */
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index ce667ff32b9..eabf6805f2b 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2594,14 +2594,18 @@ modref_may_conflict (const gimple *stmt,
 	      if (num_tests >= max_tests)
 		return true;
 
-	      if (access_node->parm_index == -1
-		  || (unsigned)access_node->parm_index
-		     >= gimple_call_num_args (stmt))
+	      if (access_node->parm_index == MODREF_UNKNOWN_PARM
+		  || access_node->parm_index
+		     >= (int)gimple_call_num_args (stmt))
 		return true;
 
 	      alias_stats.modref_baseptr_tests++;
+	      tree arg;
 
-	      tree arg = gimple_call_arg (stmt, access_node->parm_index);
+	      if (access_node->parm_index == MODREF_STATIC_CHAIN_PARM)
+		arg = gimple_call_chain (stmt);
+	      else
+		arg = gimple_call_arg (stmt, access_node->parm_index);
 
 	      if (integer_zerop (arg) && flag_delete_null_pointer_checks)
 		continue;


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

only message in thread, other threads:[~2021-11-08  6:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-08  6:53 [gcc r12-4988] Add loads/stores relative to static chain in ipa-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).