Commit 6566b0fb by Jeff Law Committed by Jeff Law

gimple-ssa-evrp.c (class evrp_range_analyzer): New class extracted from evrp_dom_walker class.

	* gimple-ssa-evrp.c (class evrp_range_analyzer): New class extracted
	from evrp_dom_walker class.  Various methods moved into new class.
	(evrp_range_analyzer::evrp_range_analyzer): Constructor for new class.
	(evrp_range_analyzer::enter): New method.
	(evrp_range_analyzer::leave): New method.
	(evrp_dom_walker): Remove delegators no longer needed by this class.
	Replace vr_values data member with evrp_range_analyzer

From-SVN: r254884
parent 0dee5a2a
2017-11-17 Jeff Law <law@redhat.com>
* gimple-ssa-evrp.c (class evrp_range_analyzer): New class extracted
from evrp_dom_walker class. Various methods moved into new class.
(evrp_range_analyzer::evrp_range_analyzer): Constructor for new class.
(evrp_range_analyzer::enter): New method.
(evrp_range_analyzer::leave): New method.
(evrp_dom_walker): Remove delegators no longer needed by this class.
Replace vr_values data member with evrp_range_analyzer
* gimple-ssa-evrp.c (evrp_dom_walker::record_ranges_from_phis): New
method extracted from evrp_dom_walker::before_dom_children.
(evrp_dom_walker::record_ranges_from_stmt): Likewise.
......@@ -55,43 +55,28 @@ evrp_folder::get_value (tree op)
return vr_values->op_with_constant_singleton_value_range (op);
}
/* evrp_dom_walker visits the basic blocks in the dominance order and set
the Value Ranges (VR) for SSA_NAMEs in the scope. Use this VR to
discover more VRs. */
class evrp_dom_walker : public dom_walker
class evrp_range_analyzer
{
public:
evrp_dom_walker ()
: dom_walker (CDI_DOMINATORS), stack (10)
{
need_eh_cleanup = BITMAP_ALLOC (NULL);
}
~evrp_dom_walker ()
{
BITMAP_FREE (need_eh_cleanup);
}
virtual edge before_dom_children (basic_block);
virtual void after_dom_children (basic_block);
void cleanup (void);
public:
evrp_range_analyzer (void);
~evrp_range_analyzer (void) { stack.release (); }
void enter (basic_block);
void leave (basic_block);
void record_ranges_from_stmt (gimple *);
class vr_values vr_values;
private:
DISABLE_COPY_AND_ASSIGN (evrp_dom_walker);
DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
void push_value_range (tree var, value_range *vr);
value_range *pop_value_range (tree var);
value_range *try_find_new_range (tree, tree op, tree_code code, tree limit);
void record_ranges_from_incoming_edge (basic_block);
void record_ranges_from_phis (basic_block);
void record_ranges_from_stmt (gimple *);
/* STACK holds the old VR. */
auto_vec<std::pair <tree, value_range*> > stack;
bitmap need_eh_cleanup;
auto_vec<gimple *> stmts_to_fixup;
auto_vec<gimple *> stmts_to_remove;
class vr_values vr_values;
/* Temporary delegators. */
value_range *get_value_range (const_tree op)
......@@ -100,17 +85,9 @@ public:
{ return vr_values.update_value_range (op, vr); }
void extract_range_from_phi_node (gphi *phi, value_range *vr)
{ vr_values.extract_range_from_phi_node (phi, vr); }
void extract_range_for_var_from_comparison_expr (tree var,
enum tree_code cond_code,
tree op, tree limit,
value_range *vr_p)
{ vr_values.extract_range_for_var_from_comparison_expr (var, cond_code,
op, limit, vr_p); }
void adjust_range_with_scev (value_range *vr, struct loop *loop,
gimple *stmt, tree var)
{ vr_values.adjust_range_with_scev (vr, loop, stmt, var); }
tree op_with_constant_singleton_value_range (tree op)
{ return vr_values.op_with_constant_singleton_value_range (op); }
void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
tree *output_p, value_range *vr)
{ vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); }
......@@ -118,16 +95,76 @@ public:
{ return vr_values.set_defs_to_varying (stmt); }
void set_vr_value (tree name, value_range *vr)
{ vr_values.set_vr_value (name, vr); }
void simplify_cond_using_ranges_2 (gcond *stmt)
{ vr_values.simplify_cond_using_ranges_2 (stmt); }
void extract_range_for_var_from_comparison_expr (tree var,
enum tree_code cond_code,
tree op, tree limit,
value_range *vr_p)
{ vr_values.extract_range_for_var_from_comparison_expr (var, cond_code,
op, limit, vr_p); }
};
evrp_range_analyzer::evrp_range_analyzer () : stack (10)
{
edge e;
edge_iterator ei;
basic_block bb;
FOR_EACH_BB_FN (bb, cfun)
{
bb->flags &= ~BB_VISITED;
FOR_EACH_EDGE (e, ei, bb->preds)
e->flags |= EDGE_EXECUTABLE;
}
}
/* evrp_dom_walker visits the basic blocks in the dominance order and set
the Value Ranges (VR) for SSA_NAMEs in the scope. Use this VR to
discover more VRs. */
class evrp_dom_walker : public dom_walker
{
public:
evrp_dom_walker () : dom_walker (CDI_DOMINATORS)
{
need_eh_cleanup = BITMAP_ALLOC (NULL);
}
~evrp_dom_walker ()
{
BITMAP_FREE (need_eh_cleanup);
}
virtual edge before_dom_children (basic_block);
virtual void after_dom_children (basic_block);
void cleanup (void);
private:
DISABLE_COPY_AND_ASSIGN (evrp_dom_walker);
bitmap need_eh_cleanup;
auto_vec<gimple *> stmts_to_fixup;
auto_vec<gimple *> stmts_to_remove;
class evrp_range_analyzer evrp_range_analyzer;
/* Temporary delegators. */
value_range *get_value_range (const_tree op)
{ return evrp_range_analyzer.vr_values.get_value_range (op); }
tree op_with_constant_singleton_value_range (tree op)
{ return evrp_range_analyzer.vr_values.op_with_constant_singleton_value_range (op); }
void vrp_visit_cond_stmt (gcond *cond, edge *e)
{ vr_values.vrp_visit_cond_stmt (cond, e); }
{ evrp_range_analyzer.vr_values.vrp_visit_cond_stmt (cond, e); }
};
/* Find new range for NAME such that (OP CODE LIMIT) is true. */
void
evrp_range_analyzer::enter (basic_block bb)
{
stack.safe_push (std::make_pair (NULL_TREE, (value_range *)NULL));
record_ranges_from_incoming_edge (bb);
record_ranges_from_phis (bb);
}
/* Find new range for NAME such that (OP CODE LIMIT) is true. */
value_range *
evrp_dom_walker::try_find_new_range (tree name,
evrp_range_analyzer::try_find_new_range (tree name,
tree op, tree_code code, tree limit)
{
value_range vr = VR_INITIALIZER;
......@@ -155,10 +192,8 @@ evrp_dom_walker::try_find_new_range (tree name,
then derive ranges implied by traversing that edge. */
void
evrp_dom_walker::record_ranges_from_incoming_edge (basic_block bb)
evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
{
/* See if there is any new scope is entered with new VR and set that VR to
ssa_name before visiting the statements in the scope. */
edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
if (pred_e)
{
......@@ -207,10 +242,8 @@ evrp_dom_walker::record_ranges_from_incoming_edge (basic_block bb)
}
}
/* Record ranges from any PHI nodes at the start of basic block BB. */
void
evrp_dom_walker::record_ranges_from_phis (basic_block bb)
evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
{
/* Visit PHI stmts and discover any new VRs possible. */
bool has_unvisited_preds = false;
......@@ -231,15 +264,10 @@ evrp_dom_walker::record_ranges_from_phis (basic_block bb)
tree lhs = PHI_RESULT (phi);
if (virtual_operand_p (lhs))
continue;
value_range vr_result = VR_INITIALIZER;
bool interesting = stmt_interesting_for_vrp (phi);
if (interesting && dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Visiting PHI node ");
print_gimple_stmt (dump_file, phi, 0);
}
if (!has_unvisited_preds
&& interesting)
if (!has_unvisited_preds && interesting)
extract_range_from_phi_node (phi, &vr_result);
else
{
......@@ -281,7 +309,7 @@ evrp_dom_walker::record_ranges_from_phis (basic_block bb)
/* Record any ranges created by statement STMT. */
void
evrp_dom_walker::record_ranges_from_stmt (gimple *stmt)
evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt)
{
tree output = NULL_TREE;
......@@ -372,9 +400,7 @@ evrp_dom_walker::before_dom_children (basic_block bb)
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Visiting BB%d\n", bb->index);
stack.safe_push (std::make_pair (NULL_TREE, (value_range *)NULL));
record_ranges_from_incoming_edge (bb);
record_ranges_from_phis (bb);
evrp_range_analyzer.enter (bb);
for (gphi_iterator gpi = gsi_start_phis (bb);
!gsi_end_p (gpi); gsi_next (&gpi))
......@@ -411,7 +437,8 @@ evrp_dom_walker::before_dom_children (basic_block bb)
print_gimple_stmt (dump_file, stmt, 0);
}
record_ranges_from_stmt (stmt);
evrp_range_analyzer.record_ranges_from_stmt (stmt);
if (gcond *cond = dyn_cast <gcond *> (stmt))
{
vrp_visit_cond_stmt (cond, &taken_edge);
......@@ -432,10 +459,10 @@ evrp_dom_walker::before_dom_children (basic_block bb)
output = get_output_for_vrp (stmt);
if (output)
{
tree val;
vr = *get_value_range (output);
/* Mark stmts whose output we fully propagate for removal. */
tree val;
if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
&& (val = op_with_constant_singleton_value_range (output))
&& may_propagate_copy (output, val)
......@@ -450,7 +477,7 @@ evrp_dom_walker::before_dom_children (basic_block bb)
/* Try folding stmts with the VR discovered. */
class evrp_folder evrp_folder;
evrp_folder.vr_values = &vr_values;
evrp_folder.vr_values = &evrp_range_analyzer.vr_values;
bool did_replace = evrp_folder.replace_uses_in (stmt);
if (fold_stmt (&gsi, follow_single_use_edges)
|| did_replace)
......@@ -508,10 +535,16 @@ evrp_dom_walker::before_dom_children (basic_block bb)
return taken_edge;
}
void
evrp_dom_walker::after_dom_children (basic_block bb)
{
evrp_range_analyzer.leave (bb);
}
/* Restore/pop VRs valid only for BB when we leave BB. */
void
evrp_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
evrp_range_analyzer::leave (basic_block bb ATTRIBUTE_UNUSED)
{
gcc_checking_assert (!stack.is_empty ());
while (stack.last ().first != NULL_TREE)
......@@ -522,7 +555,7 @@ evrp_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
/* Push the Value Range of VAR to the stack and update it with new VR. */
void
evrp_dom_walker::push_value_range (tree var, value_range *vr)
evrp_range_analyzer::push_value_range (tree var, value_range *vr)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
......@@ -539,7 +572,7 @@ evrp_dom_walker::push_value_range (tree var, value_range *vr)
/* Pop the Value Range from the vrp_stack and update VAR with it. */
value_range *
evrp_dom_walker::pop_value_range (tree var)
evrp_range_analyzer::pop_value_range (tree var)
{
value_range *vr = stack.last ().second;
gcc_checking_assert (var == stack.last ().first);
......@@ -564,7 +597,7 @@ evrp_dom_walker::cleanup (void)
if (dump_file)
{
fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
vr_values.dump_all_value_ranges (dump_file);
evrp_range_analyzer.vr_values.dump_all_value_ranges (dump_file);
fprintf (dump_file, "\n");
}
......@@ -610,10 +643,6 @@ evrp_dom_walker::cleanup (void)
static unsigned int
execute_early_vrp ()
{
edge e;
edge_iterator ei;
basic_block bb;
/* Ideally this setup code would move into the ctor for the dominator
walk. However, this setup can change the number of blocks which
invalidates the internal arrays that are set up by the dominator
......@@ -622,12 +651,6 @@ execute_early_vrp ()
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
scev_initialize ();
calculate_dominance_info (CDI_DOMINATORS);
FOR_EACH_BB_FN (bb, cfun)
{
bb->flags &= ~BB_VISITED;
FOR_EACH_EDGE (e, ei, bb->preds)
e->flags |= EDGE_EXECUTABLE;
}
/* Walk stmts in dominance order and propagate VRP. */
evrp_dom_walker walker;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment