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);