aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-range-path.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimple-range-path.cc')
-rw-r--r--gcc/gimple-range-path.cc95
1 files changed, 35 insertions, 60 deletions
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index e65c799..422abfd 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -34,14 +34,11 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-iterator.h"
// Internal construct to help facilitate debugging of solver.
-#define DEBUG_SOLVER (0 && dump_file)
+#define DEBUG_SOLVER (dump_file && dump_flags & TDF_THREADING)
path_range_query::path_range_query (gimple_ranger &ranger, bool resolve)
: m_ranger (ranger)
{
- if (DEBUG_SOLVER)
- fprintf (dump_file, "\n*********** path_range_query ******************\n");
-
m_cache = new ssa_global_cache;
m_has_cache_entry = BITMAP_ALLOC (NULL);
m_path = NULL;
@@ -139,14 +136,23 @@ path_range_query::range_on_path_entry (irange &r, tree name)
{
int_range_max tmp;
basic_block entry = entry_bb ();
+ bool changed = false;
+
r.set_undefined ();
for (unsigned i = 0; i < EDGE_COUNT (entry->preds); ++i)
{
edge e = EDGE_PRED (entry, i);
if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
&& m_ranger.range_on_edge (tmp, e, name))
- r.union_ (tmp);
+ {
+ r.union_ (tmp);
+ changed = true;
+ }
}
+
+ // Make sure we don't return UNDEFINED by mistake.
+ if (!changed)
+ r.set_varying (TREE_TYPE (name));
}
// Return the range of NAME at the end of the path being analyzed.
@@ -163,10 +169,6 @@ path_range_query::internal_range_of_expr (irange &r, tree name, gimple *stmt)
if (m_resolve && defined_outside_path (name))
{
range_on_path_entry (r, name);
-
- if (r.varying_p ())
- improve_range_with_equivs (r, name);
-
set_cache (r, name);
return true;
}
@@ -177,9 +179,6 @@ path_range_query::internal_range_of_expr (irange &r, tree name, gimple *stmt)
if (TREE_CODE (name) == SSA_NAME)
r.intersect (gimple_range_global (name));
- if (m_resolve && r.varying_p ())
- improve_range_with_equivs (r, name);
-
set_cache (r, name);
return true;
}
@@ -201,33 +200,6 @@ path_range_query::range_of_expr (irange &r, tree name, gimple *stmt)
return false;
}
-// Improve the range of NAME with the range of any of its equivalences.
-
-void
-path_range_query::improve_range_with_equivs (irange &r, tree name)
-{
- if (TREE_CODE (name) != SSA_NAME)
- return;
-
- basic_block entry = entry_bb ();
- relation_oracle *oracle = m_ranger.oracle ();
-
- if (const bitmap_head *equivs = oracle->equiv_set (name, entry))
- {
- int_range_max t;
- bitmap_iterator bi;
- unsigned i;
-
- EXECUTE_IF_SET_IN_BITMAP (equivs, 0, i, bi)
- if (i != SSA_NAME_VERSION (name) && r.varying_p ())
- {
- tree equiv = ssa_name (i);
- range_on_path_entry (t, equiv);
- r.intersect (t);
- }
- }
-}
-
bool
path_range_query::unreachable_path_p ()
{
@@ -330,11 +302,11 @@ path_range_query::range_defined_in_block (irange &r, tree name, basic_block bb)
return true;
}
-// Precompute ranges defined in the current block, or ranges
-// that are exported on an edge to the next block.
+// Compute ranges defined in the current block, or exported to the
+// next block.
void
-path_range_query::precompute_ranges_in_block (basic_block bb)
+path_range_query::compute_ranges_in_block (basic_block bb)
{
bitmap_iterator bi;
int_range_max r, cached_range;
@@ -489,15 +461,18 @@ path_range_query::add_copies_to_imports ()
}
}
-// Precompute the ranges for IMPORTS along PATH.
+// Compute the ranges for IMPORTS along PATH.
//
// IMPORTS are the set of SSA names, any of which could potentially
// change the value of the final conditional in PATH.
void
-path_range_query::precompute_ranges (const vec<basic_block> &path,
- const bitmap_head *imports)
+path_range_query::compute_ranges (const vec<basic_block> &path,
+ const bitmap_head *imports)
{
+ if (DEBUG_SOLVER)
+ fprintf (dump_file, "\n*********** path_range_query ******************\n");
+
set_path (path);
bitmap_copy (m_imports, imports);
m_undefined_path = false;
@@ -505,13 +480,13 @@ path_range_query::precompute_ranges (const vec<basic_block> &path,
if (m_resolve)
{
add_copies_to_imports ();
- m_oracle->reset_path ();
- precompute_relations (path);
+ get_path_oracle ()->reset_path ();
+ compute_relations (path);
}
if (DEBUG_SOLVER)
{
- fprintf (dump_file, "\npath_range_query: precompute_ranges for path: ");
+ fprintf (dump_file, "\npath_range_query: compute_ranges for path: ");
for (unsigned i = path.length (); i > 0; --i)
{
basic_block bb = path[i - 1];
@@ -538,7 +513,7 @@ path_range_query::precompute_ranges (const vec<basic_block> &path,
bitmap_set_bit (m_imports, SSA_NAME_VERSION (name));
}
- precompute_ranges_in_block (bb);
+ compute_ranges_in_block (bb);
adjust_for_non_null_uses (bb);
if (at_exit ())
@@ -645,12 +620,12 @@ path_range_query::range_of_stmt (irange &r, gimple *stmt, tree)
return true;
}
-// Precompute relations on a path. This involves two parts: relations
+// Compute relations on a path. This involves two parts: relations
// along the conditionals joining a path, and relations determined by
// examining PHIs.
void
-path_range_query::precompute_relations (const vec<basic_block> &path)
+path_range_query::compute_relations (const vec<basic_block> &path)
{
if (!dom_info_available_p (CDI_DOMINATORS))
return;
@@ -662,7 +637,7 @@ path_range_query::precompute_relations (const vec<basic_block> &path)
basic_block bb = path[i - 1];
gimple *stmt = last_stmt (bb);
- precompute_phi_relations (bb, prev);
+ compute_phi_relations (bb, prev);
// Compute relations in outgoing edges along the path. Skip the
// final conditional which we don't know yet.
@@ -674,30 +649,30 @@ path_range_query::precompute_relations (const vec<basic_block> &path)
basic_block next = path[i - 2];
int_range<2> r;
gcond *cond = as_a<gcond *> (stmt);
+ edge e0 = EDGE_SUCC (bb, 0);
+ edge e1 = EDGE_SUCC (bb, 1);
- if (EDGE_SUCC (bb, 0)->dest == next)
- gcond_edge_range (r, EDGE_SUCC (bb, 0));
- else if (EDGE_SUCC (bb, 1)->dest == next)
- gcond_edge_range (r, EDGE_SUCC (bb, 1));
+ if (e0->dest == next)
+ gcond_edge_range (r, e0);
+ else if (e1->dest == next)
+ gcond_edge_range (r, e1);
else
gcc_unreachable ();
- edge e0 = EDGE_SUCC (bb, 0);
- edge e1 = EDGE_SUCC (bb, 1);
src.register_outgoing_edges (cond, r, e0, e1);
}
prev = bb;
}
}
-// Precompute relations for each PHI in BB. For example:
+// Compute relations for each PHI in BB. For example:
//
// x_5 = PHI<y_9(5),...>
//
// If the path flows through BB5, we can register that x_5 == y_9.
void
-path_range_query::precompute_phi_relations (basic_block bb, basic_block prev)
+path_range_query::compute_phi_relations (basic_block bb, basic_block prev)
{
if (prev == NULL)
return;