adjust_for_non_null_uses walks every exit dependency of the path in
every block of the path just to pick out the pointer ones, and then
asks the infer oracle about each of them. Since the pointer
dependencies do not change while a path is being solved, collect them
once. Querying the oracle for each of them also forces it to populate
its per-block summaries, which lets us skip the common case: a block
with no inferred range at all.
Measured in perf instructions retired over our stage1 .ii corpus, this
drops back_threader::thread_blocks() by a further 3.6%
(pass_thread_jumps 4.4%, pass_thread_jumps_full 3.0%,
pass_early_thread_jumps 1.0%) and the whole compile by a further 0.05%
over 806 TUs. Over the three patches back_threader::thread_blocks()
is 11.9% cheaper (pass_thread_jumps 13.6%, pass_thread_jumps_full
9.2%, pass_early_thread_jumps 8.1%) and the whole compile 0.14%.
Tested on ppc64le Linux. The assembly is identical over the .ii
files, so this is a NFC.
Pushed.
gcc/ChangeLog:
* gimple-range-path.h (path_range_query::m_pointer_exit_dependencies):
New.
* gimple-range-path.cc (path_range_query::adjust_for_non_null_uses):
Walk m_pointer_exit_dependencies, and return early for a block with no
inferred ranges.
(path_range_query::compute_ranges): Fill in m_pointer_exit_dependencies.
---
gcc/gimple-range-path.cc | 34 ++++++++++++++++++++++++++--------
gcc/gimple-range-path.h | 3 +++
2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index aa60db65f4f..1e9f2b0be6c 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -465,17 +465,16 @@ path_range_query::compute_ranges_in_block (basic_block bb)
void
path_range_query::adjust_for_non_null_uses (basic_block bb)
{
+ // If there are no pointer exit dependencies with an inferred range, there's
+ // nothing to do.
+ if (m_pointer_exit_dependencies.is_empty ()
+ || !infer_oracle ().has_range_p (bb))
+ return;
+
prange r;
- bitmap_iterator bi;
- unsigned i;
- EXECUTE_IF_SET_IN_BITMAP (m_exit_dependencies, 0, i, bi)
+ for (tree name : m_pointer_exit_dependencies)
{
- tree name = ssa_name (i);
-
- if (!POINTER_TYPE_P (TREE_TYPE (name)))
- continue;
-
if (get_cache (r, name))
{
if (!r.contains_zero_p ())
@@ -585,6 +584,25 @@ path_range_query::compute_ranges (const bitmap_head
*dependencies)
path_oracle *p = get_path_oracle ();
p->reset_path (&(m_ranger.relation ()));
+ // Collect the pointer exit dependencies once per path.
+ m_pointer_exit_dependencies.truncate (0);
+ {
+ bitmap_iterator bi;
+ unsigned i;
+ EXECUTE_IF_SET_IN_BITMAP (m_exit_dependencies, 0, i, bi)
+ {
+ tree name = ssa_name (i);
+ if (POINTER_TYPE_P (TREE_TYPE (name)))
+ {
+ // Querying the infer oracle here is what populates its
+ // per-block summaries, so that adjust_for_non_null_uses can
+ // skip a block with no inferred range in it at all.
+ infer_oracle ().has_range_p (entry_bb (), name);
+ m_pointer_exit_dependencies.safe_push (name);
+ }
+ }
+ }
+
if (DEBUG_SOLVER)
{
fprintf (dump_file, "path_range_query: compute_ranges for path: ");
diff --git a/gcc/gimple-range-path.h b/gcc/gimple-range-path.h
index 4c162ef11f6..6008e565cb1 100644
--- a/gcc/gimple-range-path.h
+++ b/gcc/gimple-range-path.h
@@ -83,6 +83,9 @@ private:
// Range cache for SSA names.
ssa_lazy_cache m_cache;
+ // All the pointer typed exit dependencies in the path.
+ auto_vec<tree> m_pointer_exit_dependencies;
+
// Path being analyzed.
auto_vec<basic_block> m_path;
--
2.53.0