@@ -620,7 +620,9 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
if (dump_file && (dump_flags & TDF_DETAILS) && rel != VREL_NONE)
{
fprintf (dump_file, " folding with relation ");
+ print_generic_expr (dump_file, op1, TDF_SLIM);
print_relation (dump_file, rel);
+ print_generic_expr (dump_file, op2, TDF_SLIM);
fputc ('\n', dump_file);
}
// Fold range, and register any dependency if available.
@@ -316,6 +316,9 @@ path_range_query::compute_ranges_in_block (basic_block bb)
int_range_max r, cached_range;
unsigned i;
+ if (m_resolve && !at_entry ())
+ compute_phi_relations (bb, prev_bb ());
+
// Force recalculation of any names in the cache that are defined in
// this block. This can happen on interdependent SSA/phis in loops.
EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi)
@@ -341,7 +344,8 @@ path_range_query::compute_ranges_in_block (basic_block bb)
return;
// Solve imports that are exported to the next block.
- edge e = find_edge (bb, next_bb ());
+ basic_block next = next_bb ();
+ edge e = find_edge (bb, next);
EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi)
{
tree name = ssa_name (i);
@@ -369,6 +373,9 @@ path_range_query::compute_ranges_in_block (basic_block bb)
}
}
}
+
+ if (m_resolve)
+ compute_outgoing_relations (bb, next);
}
// Adjust all pointer imports in BB with non-null information.
@@ -485,7 +492,6 @@ path_range_query::compute_ranges (const vec<basic_block> &path,
{
add_copies_to_imports ();
get_path_oracle ()->reset_path ();
- compute_relations (path);
}
if (DEBUG_SOLVER)
@@ -527,7 +533,12 @@ path_range_query::compute_ranges (const vec<basic_block> &path,
}
if (DEBUG_SOLVER)
- dump (dump_file);
+ {
+ fprintf (dump_file, "\npath_oracle:\n");
+ get_path_oracle ()->dump (dump_file);
+ fprintf (dump_file, "\n");
+ dump (dump_file);
+ }
}
// A folding aid used to register and query relations along a path.
@@ -624,49 +635,23 @@ path_range_query::range_of_stmt (irange &r, gimple *stmt, tree)
return true;
}
-// 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::compute_relations (const vec<basic_block> &path)
+path_range_query::maybe_register_phi_relation (gphi *phi, tree arg)
{
- if (!dom_info_available_p (CDI_DOMINATORS))
- return;
+ basic_block bb = gimple_bb (phi);
+ tree result = gimple_phi_result (phi);
+ gimple *def = SSA_NAME_DEF_STMT (arg);
- jt_fur_source src (NULL, this, &m_ranger.gori (), path);
- basic_block prev = NULL;
- for (unsigned i = path.length (); i > 0; --i)
- {
- basic_block bb = path[i - 1];
- gimple *stmt = last_stmt (bb);
+ // Avoid recording the equivalence if the arg is defined in this
+ // block, as that would create an ordering problem.
+ if (def && gimple_bb (def) == bb)
+ return;
- compute_phi_relations (bb, prev);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " from bb%d:", bb->index);
- // Compute relations in outgoing edges along the path. Skip the
- // final conditional which we don't know yet.
- if (i > 1
- && stmt
- && gimple_code (stmt) == GIMPLE_COND
- && irange::supports_type_p (TREE_TYPE (gimple_cond_lhs (stmt))))
- {
- 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 (e0->dest == next)
- gcond_edge_range (r, e0);
- else if (e1->dest == next)
- gcond_edge_range (r, e1);
- else
- gcc_unreachable ();
-
- src.register_outgoing_edges (cond, r, e0, e1);
- }
- prev = bb;
- }
+ get_path_oracle ()->killing_def (result);
+ m_oracle->register_relation (entry_bb (), EQ_EXPR, arg, result);
}
// Compute relations for each PHI in BB. For example:
@@ -681,15 +666,12 @@ path_range_query::compute_phi_relations (basic_block bb, basic_block prev)
if (prev == NULL)
return;
- basic_block entry = entry_bb ();
edge e_in = find_edge (prev, bb);
- gcc_checking_assert (e_in);
for (gphi_iterator iter = gsi_start_phis (bb); !gsi_end_p (iter);
gsi_next (&iter))
{
gphi *phi = iter.phi ();
- tree result = gimple_phi_result (phi);
unsigned nargs = gimple_phi_num_args (phi);
for (size_t i = 0; i < nargs; ++i)
@@ -698,17 +680,36 @@ path_range_query::compute_phi_relations (basic_block bb, basic_block prev)
tree arg = gimple_phi_arg_def (phi, i);
if (gimple_range_ssa_p (arg))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " from bb%d:", bb->index);
+ maybe_register_phi_relation (phi, arg);
+ break;
+ }
+ }
+}
- // Throw away any previous relation.
- get_path_oracle ()->killing_def (result);
+// Compute outgoing relations from BB to NEXT.
- m_oracle->register_relation (entry, EQ_EXPR, arg, result);
- }
+void
+path_range_query::compute_outgoing_relations (basic_block bb, basic_block next)
+{
+ gimple *stmt = last_stmt (bb);
- break;
- }
+ if (stmt
+ && gimple_code (stmt) == GIMPLE_COND
+ && irange::supports_type_p (TREE_TYPE (gimple_cond_lhs (stmt))))
+ {
+ int_range<2> r;
+ gcond *cond = as_a<gcond *> (stmt);
+ edge e0 = EDGE_SUCC (bb, 0);
+ edge e1 = 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 ();
+
+ jt_fur_source src (NULL, this, &m_ranger.gori (), *m_path);
+ src.register_outgoing_edges (cond, r, e0, e1);
}
}
@@ -57,8 +57,9 @@ private:
void compute_ranges_in_block (basic_block bb);
void adjust_for_non_null_uses (basic_block bb);
void ssa_range_in_phi (irange &r, gphi *phi);
- void compute_relations (const vec<basic_block> &);
+ void compute_outgoing_relations (basic_block bb, basic_block next);
void compute_phi_relations (basic_block bb, basic_block prev);
+ void maybe_register_phi_relation (gphi *, tree arg);
void add_copies_to_imports ();
bool add_to_imports (tree name, bitmap imports);