From c838119946c9f75f1e42f4320275355822cc86fc Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 7 Nov 2022 15:07:35 -0500 Subject: Add transitive inferred range processing. Rewalk statements at the end of a block to see if any inferred ranges affect earlier calculations and register those as inferred ranges. gcc/ PR tree-optimization/104530 * gimple-range-cache.cc (ranger_cache::register_inferred_value): New. Split from: (ranger_cache::apply_inferred_ranges): Move setting cache to separate function. * gimple-range-cache.h (register_inferred_value): New prototype. * gimple-range-infer.cc (infer_range_manager::has_range_p): New. * gimple-range-infer.h (has_range_p): New prototype. * gimple-range.cc (register_transitive_inferred_ranges): New. * gimple-range.h (register_transitive_inferred_ranges): New proto. * tree-vrp.cc (rvrp_folder::fold_stmt): Check for transitive inferred ranges at the end of the block before folding final stmt. gcc/testsuite/ * gcc.dg/pr104530.c: New. --- gcc/gimple-range.cc | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'gcc/gimple-range.cc') diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index 806386918bd..2885d0fa21e 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -482,6 +482,54 @@ gimple_ranger::register_inferred_ranges (gimple *s) m_cache.apply_inferred_ranges (s); } +// This function will walk the statements in BB to determine if any +// discovered inferred ranges in the block have any transitive effects, +// and if so, register those effects in BB. + +void +gimple_ranger::register_transitive_inferred_ranges (basic_block bb) +{ + // Return if there are no inferred ranges in BB. + infer_range_manager &infer = m_cache.m_exit; + if (!infer.has_range_p (bb)) + return; + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Checking for transitive inferred ranges in BB %d\n", + bb->index); + + for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); + gsi_next (&si)) + { + gimple *s = gsi_stmt (si); + tree lhs = gimple_get_lhs (s); + // If the LHS alreayd has an inferred effect, leave it be. + if (!gimple_range_ssa_p (lhs) || infer.has_range_p (lhs, bb)) + continue; + // Pick up global value. + Value_Range g (TREE_TYPE (lhs)); + range_of_expr (g, lhs); + + // If either dependency has an inferred range, check if recalculating + // the LHS is different than the global value. If so, register it as + // an inferred range as well. + Value_Range r (TREE_TYPE (lhs)); + r.set_undefined (); + tree name1 = gori ().depend1 (lhs); + tree name2 = gori ().depend2 (lhs); + if ((name1 && infer.has_range_p (name1, bb)) + || (name2 && infer.has_range_p (name2, bb))) + { + // Check if folding S produces a different result. + if (fold_range (r, s, this) && g != r) + { + infer.add_range (lhs, bb, r); + m_cache.register_inferred_value (r, lhs, bb); + } + } + } +} + // When a statement S has changed since the result was cached, re-evaluate // and update the global cache. -- cgit v1.2.1