diff options
-rw-r--r-- | gcc/gimple-range-path.cc | 22 | ||||
-rw-r--r-- | gcc/gimple-range-path.h | 6 | ||||
-rw-r--r-- | gcc/tree-ssa-threadbackward.c | 14 |
3 files changed, 31 insertions, 11 deletions
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc index db15eb3..f4509b5 100644 --- a/gcc/gimple-range-path.cc +++ b/gcc/gimple-range-path.cc @@ -115,7 +115,7 @@ path_range_query::debug () // Return the range of NAME at the end of the path being analyzed. bool -path_range_query::range_of_expr (irange &r, tree name, gimple *stmt) +path_range_query::internal_range_of_expr (irange &r, tree name, gimple *stmt) { if (!irange::supports_type_p (TREE_TYPE (name))) return false; @@ -135,6 +135,25 @@ path_range_query::range_of_expr (irange &r, tree name, gimple *stmt) return true; } +bool +path_range_query::range_of_expr (irange &r, tree name, gimple *stmt) +{ + if (internal_range_of_expr (r, name, stmt)) + { + if (r.undefined_p ()) + m_undefined_path = true; + + return true; + } + return false; +} + +bool +path_range_query::unreachable_path_p () +{ + return m_undefined_path; +} + // Return the range of STMT at the end of the path being analyzed. // Anything but the final conditional in a BB will return VARYING. @@ -345,6 +364,7 @@ path_range_query::precompute_ranges (const vec<basic_block> &path, { set_path (path); m_imports = imports; + m_undefined_path = false; if (DEBUG_SOLVER) { diff --git a/gcc/gimple-range-path.h b/gcc/gimple-range-path.h index 5177313..c75721f 100644 --- a/gcc/gimple-range-path.h +++ b/gcc/gimple-range-path.h @@ -41,10 +41,13 @@ public: const bitmap_head *imports); bool range_of_expr (irange &r, tree name, gimple * = NULL) override; bool range_of_stmt (irange &r, gimple *, tree name = NULL) override; + bool unreachable_path_p (); void dump (FILE *) override; void debug (); private: + bool internal_range_of_expr (irange &r, tree name, gimple *); + // Cache manipulation. void set_cache (const irange &r, tree name); bool get_cache (irange &r, tree name); @@ -82,6 +85,9 @@ private: const bitmap_head *m_imports; gimple_ranger &m_ranger; non_null_ref m_non_null; + + // Set if there were any undefined expressions while pre-calculating path. + bool m_undefined_path; }; #endif // GCC_TREE_SSA_THREADSOLVER_H diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c index 6827d00..449232c 100644 --- a/gcc/tree-ssa-threadbackward.c +++ b/gcc/tree-ssa-threadbackward.c @@ -213,20 +213,14 @@ edge back_threader::find_taken_edge_cond (const vec<basic_block> &path, gcond *cond) { - m_solver.precompute_ranges (path, m_imports); - - // Check if either operand is unreachable since this knowledge could - // help the caller cut down the search space. int_range_max r; - m_solver.range_of_expr (r, gimple_cond_lhs (cond)); - if (r.undefined_p ()) - return UNREACHABLE_EDGE; - m_solver.range_of_expr (r, gimple_cond_rhs (cond)); - if (r.undefined_p ()) - return UNREACHABLE_EDGE; + m_solver.precompute_ranges (path, m_imports); m_solver.range_of_stmt (r, cond); + if (m_solver.unreachable_path_p ()) + return UNREACHABLE_EDGE; + int_range<2> true_range (boolean_true_node, boolean_true_node); int_range<2> false_range (boolean_false_node, boolean_false_node); |