From 35c78c6fc54721e067ed3a30ddd9184b45c5981d Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Tue, 25 May 2021 14:41:16 -0400
Subject: [PATCH 5/8] Tweak location of non-null calls. revamp ranger debug
 output.

range_on_entry shouldnt be checking non-null, but we sometimes should
after calling it.
change the debug output a bit.

	* gimple-range.cc (gimple_ranger::range_of_expr): Non-null should be
	checked only after range_of_stmt, not range_on_entry.
	(gimple_ranger::range_on_entry): Check for non-null in any
	predecessor block, if it is not already non-null.
	(gimple_ranger::range_on_exit): DOnt check for non-null after
	range on entry call.
	(gimple_ranger::dump_bb): New.  Split from dump.
	(gimple_ranger::dump): Adjust.
	* gimple-range.h (class gimple_ranger): Adjust.
---
 gcc/gimple-range.cc | 149 ++++++++++++++++++++++----------------------
 gcc/gimple-range.h  |   1 +
 2 files changed, 74 insertions(+), 76 deletions(-)

diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 06e9804494b..593ddb1c3f8 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -976,23 +976,16 @@ gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt)
 
   // If name is defined in this block, try to get an range from S.
   if (def_stmt && gimple_bb (def_stmt) == bb)
-    range_of_stmt (r, def_stmt, expr);
+    {
+      range_of_stmt (r, def_stmt, expr);
+      if (!cfun->can_throw_non_call_exceptions && r.varying_p () &&
+	  m_cache.m_non_null.non_null_deref_p (expr, bb))
+	r = range_nonzero (TREE_TYPE (expr));
+    }
   else
     // Otherwise OP comes from outside this block, use range on entry.
     range_on_entry (r, bb, expr);
 
-  // No range yet, see if there is a dereference in the block.
-  // We don't care if it's between the def and a use within a block
-  // because the entire block must be executed anyway.
-  // FIXME:?? For non-call exceptions we could have a statement throw
-  // which causes an early block exit.
-  // in which case we may need to walk from S back to the def/top of block
-  // to make sure the deref happens between S and there before claiming
-  // there is a deref.   Punt for now.
-  if (!cfun->can_throw_non_call_exceptions && r.varying_p () &&
-      m_cache.m_non_null.non_null_deref_p (expr, bb))
-    r = range_nonzero (TREE_TYPE (expr));
-
   return true;
 }
 
@@ -1010,6 +1003,10 @@ gimple_ranger::range_on_entry (irange &r, basic_block bb, tree name)
   // Now see if there is any on_entry value which may refine it.
   if (m_cache.block_range (entry_range, bb, name))
     r.intersect (entry_range);
+
+  if (!cfun->can_throw_non_call_exceptions && r.varying_p () &&
+      m_cache.m_non_null.non_null_deref_p (name, bb))
+    r = range_nonzero (TREE_TYPE (name));
 }
 
 // Calculate the range for NAME at the end of block BB and return it in R.
@@ -1032,13 +1029,7 @@ gimple_ranger::range_on_exit (irange &r, basic_block bb, tree name)
   if (s)
     range_of_expr (r, name, s);
   else
-    {
-      range_on_entry (r, bb, name);
-      // See if there was a deref in this block, if applicable
-      if (!cfun->can_throw_non_call_exceptions && r.varying_p () &&
-	  m_cache.m_non_null.non_null_deref_p (name, bb))
-	r = range_nonzero (TREE_TYPE (name));
-    }
+    range_on_entry (r, bb, name);
   gcc_checking_assert (r.undefined_p ()
 		       || range_compatible_p (r.type (), TREE_TYPE (name)));
 }
@@ -1166,80 +1157,86 @@ gimple_ranger::export_global_ranges ()
 // Print the known table values to file F.
 
 void
-gimple_ranger::dump (FILE *f)
+gimple_ranger::dump_bb (FILE *f, basic_block bb)
 {
-  basic_block bb;
-
-  FOR_EACH_BB_FN (bb, cfun)
-    {
-      unsigned x;
-      edge_iterator ei;
-      edge e;
-      int_range_max range;
-      fprintf (f, "\n=========== BB %d ============\n", bb->index);
-      m_cache.dump (f, bb);
+  unsigned x;
+  edge_iterator ei;
+  edge e;
+  int_range_max range;
+  fprintf (f, "\n=========== BB %d ============\n", bb->index);
+  m_cache.dump (f, bb);
 
-      dump_bb (f, bb, 4, TDF_NONE);
+  ::dump_bb (f, bb, 4, TDF_NONE);
 
-      // Now find any globals defined in this block.
-      for (x = 1; x < num_ssa_names; x++)
+  // Now find any globals defined in this block.
+  for (x = 1; x < num_ssa_names; x++)
+    {
+      tree name = ssa_name (x);
+      if (gimple_range_ssa_p (name) && SSA_NAME_DEF_STMT (name) &&
+	  gimple_bb (SSA_NAME_DEF_STMT (name)) == bb &&
+	  m_cache.get_global_range (range, name))
 	{
-	  tree name = ssa_name (x);
-	  if (gimple_range_ssa_p (name) && SSA_NAME_DEF_STMT (name) &&
-	      gimple_bb (SSA_NAME_DEF_STMT (name)) == bb &&
-	      m_cache.get_global_range (range, name))
+	  if (!range.varying_p ())
 	    {
-	      if (!range.varying_p ())
-	       {
-		 print_generic_expr (f, name, TDF_SLIM);
-		 fprintf (f, " : ");
-		 range.dump (f);
-		 fprintf (f, "\n");
-	       }
-
+	      print_generic_expr (f, name, TDF_SLIM);
+	      fprintf (f, " : ");
+	      range.dump (f);
+	      fprintf (f, "\n");
 	    }
+
 	}
+    }
 
-      // And now outgoing edges, if they define anything.
-      FOR_EACH_EDGE (e, ei, bb->succs)
+  // And now outgoing edges, if they define anything.
+  FOR_EACH_EDGE (e, ei, bb->succs)
+    {
+      for (x = 1; x < num_ssa_names; x++)
 	{
-	  for (x = 1; x < num_ssa_names; x++)
+	  tree name = gimple_range_ssa_p (ssa_name (x));
+	  if (name && m_cache.outgoing_edge_range_p (range, e, name))
 	    {
-	      tree name = gimple_range_ssa_p (ssa_name (x));
-	      if (name && m_cache.outgoing_edge_range_p (range, e, name))
+	      gimple *s = SSA_NAME_DEF_STMT (name);
+	      // Only print the range if this is the def block, or
+	      // the on entry cache for either end of the edge is
+	      // set.
+	      if ((s && bb == gimple_bb (s)) ||
+		  m_cache.block_range (range, bb, name, false) ||
+		  m_cache.block_range (range, e->dest, name, false))
 		{
-		  gimple *s = SSA_NAME_DEF_STMT (name);
-		  // Only print the range if this is the def block, or
-		  // the on entry cache for either end of the edge is
-		  // set.
-		  if ((s && bb == gimple_bb (s)) ||
-		      m_cache.block_range (range, bb, name, false) ||
-		      m_cache.block_range (range, e->dest, name, false))
+		  range_on_edge (range, e, name);
+		  if (!range.varying_p ())
 		    {
-		      range_on_edge (range, e, name);
-		      if (!range.varying_p ())
-			{
-			  fprintf (f, "%d->%d ", e->src->index,
-				   e->dest->index);
-			  char c = ' ';
-			  if (e->flags & EDGE_TRUE_VALUE)
-			    fprintf (f, " (T)%c", c);
-			  else if (e->flags & EDGE_FALSE_VALUE)
-			    fprintf (f, " (F)%c", c);
-			  else
-			    fprintf (f, "     ");
-			  print_generic_expr (f, name, TDF_SLIM);
-			  fprintf(f, " : \t");
-			  range.dump(f);
-			  fprintf (f, "\n");
-			}
+		      fprintf (f, "%d->%d ", e->src->index,
+			       e->dest->index);
+		      char c = ' ';
+		      if (e->flags & EDGE_TRUE_VALUE)
+			fprintf (f, " (T)%c", c);
+		      else if (e->flags & EDGE_FALSE_VALUE)
+			fprintf (f, " (F)%c", c);
+		      else
+			fprintf (f, "     ");
+		      print_generic_expr (f, name, TDF_SLIM);
+		      fprintf(f, " : \t");
+		      range.dump(f);
+		      fprintf (f, "\n");
 		    }
 		}
 	    }
 	}
     }
+}
+
+// Print the known table values to file F.
+
+void
+gimple_ranger::dump (FILE *f)
+{
+  basic_block bb;
+
+  FOR_EACH_BB_FN (bb, cfun)
+    dump_bb (f, bb);
 
-  m_cache.dump (dump_file, (dump_flags & TDF_DETAILS) != 0);
+  m_cache.dump (f, false);
 }
 
 // If SCEV has any information about phi node NAME, return it as a range in R.
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index 53205066ab4..08035a53238 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -66,6 +66,7 @@ public:
   virtual void range_on_exit (irange &r, basic_block bb, tree name);
   void export_global_ranges ();
   void dump (FILE *f);
+  void dump_bb (FILE *f, basic_block bb);
 protected:
   bool fold_range_internal (irange &r, gimple *s, tree name);
   ranger_cache m_cache;
-- 
2.17.2

