The current non-null processing only sets a bit for the block which contains a non-null setting event.

We should check the dom tree to see if a predecessor dom block sets non-null, otherwise we can miss it.  We don't need to do this within the propagation engines like the on-entry cache.  They will propagate the range as appropriate without looking at the dom tree. So it just as the client level query this is needed, make it the default.

Later, the non-null processing will be replaced, but at least get it right for now.

Bootstraps on  x86_64-pc-linux-gnu with no testsuite regressions.

Pushed.

Andrew

commit 37935ca2f4b5a89322a24620fbec3f3c9f2845fd
Author: Andrew MacLeod <amacl...@redhat.com>
Date:   Tue Apr 27 08:44:46 2021 -0400

    When searching for non-null, check the dominator tree.
    
    The non-null bitmap only indicates which blocks non-null setting occurs.
    Generalized queries need to search the dom tree, whereas propagation
    engines only need to know the current block.  Add a flag for this purpose.
    
            * gimple-range-cache.cc (non_null_ref::non_null_deref_p): Search
            dominator tree is available and requested.
            (ranger_cache::ssa_range_in_bb): Don't search dom tree here.
            (ranger_cache::fill_block_cache): Don't search dom tree here either.
            * gimple-range-cache.h (non_null_deref_p): Add dom_search param.

diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 38e4fe1c7c0..9b401927bd6 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -48,9 +48,10 @@ non_null_ref::~non_null_ref ()
 
 // Return true if NAME has a non-null dereference in block bb.  If this is the
 // first query for NAME, calculate the summary first.
+// If SEARCH_DOM is true, the search the dominator tree as well.
 
 bool
-non_null_ref::non_null_deref_p (tree name, basic_block bb)
+non_null_ref::non_null_deref_p (tree name, basic_block bb, bool search_dom)
 {
   if (!POINTER_TYPE_P (TREE_TYPE (name)))
     return false;
@@ -59,7 +60,24 @@ non_null_ref::non_null_deref_p (tree name, basic_block bb)
   if (!m_nn[v])
     process_name (name);
 
-  return bitmap_bit_p (m_nn[v], bb->index);
+  if (bitmap_bit_p (m_nn[v], bb->index))
+    return true;
+
+  // See if any dominator has set non-zero.
+  if (search_dom && dom_info_available_p (CDI_DOMINATORS))
+    {
+      // Search back to the Def block, or the top, whichever is closer.
+      basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (name));
+      basic_block def_dom = def_bb
+			    ? get_immediate_dominator (CDI_DOMINATORS, def_bb)
+			    : NULL;
+      for ( ;
+	    bb && bb != def_dom;
+	    bb = get_immediate_dominator (CDI_DOMINATORS, bb))
+	if (bitmap_bit_p (m_nn[v], bb->index))
+	  return true;
+    }
+  return false;
 }
 
 // Allocate an populate the bitmap for NAME.  An ON bit for a block
@@ -800,7 +818,7 @@ ranger_cache::ssa_range_in_bb (irange &r, tree name, basic_block bb)
   // Check if pointers have any non-null dereferences.  Non-call
   // exceptions mean we could throw in the middle of the block, so just
   // punt for now on those.
-  if (r.varying_p () && m_non_null.non_null_deref_p (name, bb) &&
+  if (r.varying_p () && m_non_null.non_null_deref_p (name, bb, false) &&
       !cfun->can_throw_non_call_exceptions)
     r = range_nonzero (TREE_TYPE (name));
 }
@@ -1066,7 +1084,8 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
 
 	  // Regardless of whether we have visited pred or not, if the
 	  // pred has a non-null reference, revisit this block.
-	  if (m_non_null.non_null_deref_p (name, pred))
+	  // Don't search the DOM tree.
+	  if (m_non_null.non_null_deref_p (name, pred, false))
 	    {
 	      if (DEBUG_RANGE_CACHE)
 		fprintf (dump_file, "nonnull: update ");
diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h
index 2b36a02654b..986a68a9e06 100644
--- a/gcc/gimple-range-cache.h
+++ b/gcc/gimple-range-cache.h
@@ -33,7 +33,7 @@ class non_null_ref
 public:
   non_null_ref ();
   ~non_null_ref ();
-  bool non_null_deref_p (tree name, basic_block bb);
+  bool non_null_deref_p (tree name, basic_block bb, bool search_dom = true);
 private:
   vec <bitmap> m_nn;
   void process_name (tree name);

Reply via email to