Initialize vr_values.
(evrp_range_analyzer::try_find_new_range): Call methods attached to
vr_values via vr_values class instance rather than delegators.
(evrp_range_analyzer::record_ranges_from_phis): Likewise.
(evrp_range_analyzer::record_ranges_from_stmt): Likewise.
(evrp_range_analyzer::push_value_range): Likewise.
(evrp_range_analyzer::pop_value_range): Likewise.
* gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Remove
most delegators. Those remaining are exposed as public interfaces.
Make vr_values a pointer and private.
(evrp_range_analyzer::~evrp_range_analyzer): Delete the attached
vr_values.
(evrp_range_analyzer::get_vr_value): New method.
* gimple-ssa-evrp.c (class evrp_folder): Use DISABLE_COPY_AND_ASSIGN.
(evrp_folder::evrp_folder): New ctor to initialize vr_values.
(class evrp_dom_walker): Attach evrp_folder class, initialize
it in the ctor. Remove temporary delegators.
(evrp_dom_walker::before_dom_children): Call methods in attached
evrp_range_analyzer class via class instance pointer. Use
free value_range_constant_singleton to remove need for
op_with_constant_singleton_value delegator method. Do not
create a vrp_prop class instance for every call! Narrow
scope of a couple variables.
(evrp_dom_walker::cleanup): Call methods in attached
evrp_range_analyzer class via class instance pointer.
* vr-values.h (class vr_values): Privatize many methods and
data members.
From-SVN: r255074
+2017-11-22 Jeff Law <law@redhat.com>
+
+ * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer)
+ Initialize vr_values.
+ (evrp_range_analyzer::try_find_new_range): Call methods attached to
+ vr_values via vr_values class instance rather than delegators.
+ (evrp_range_analyzer::record_ranges_from_phis): Likewise.
+ (evrp_range_analyzer::record_ranges_from_stmt): Likewise.
+ (evrp_range_analyzer::push_value_range): Likewise.
+ (evrp_range_analyzer::pop_value_range): Likewise.
+ * gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Remove
+ most delegators. Those remaining are exposed as public interfaces.
+ Make vr_values a pointer and private.
+ (evrp_range_analyzer::~evrp_range_analyzer): Delete the attached
+ vr_values.
+ (evrp_range_analyzer::get_vr_value): New method.
+ * gimple-ssa-evrp.c (class evrp_folder): Use DISABLE_COPY_AND_ASSIGN.
+ (evrp_folder::evrp_folder): New ctor to initialize vr_values.
+ (class evrp_dom_walker): Attach evrp_folder class, initialize
+ it in the ctor. Remove temporary delegators.
+ (evrp_dom_walker::before_dom_children): Call methods in attached
+ evrp_range_analyzer class via class instance pointer. Use
+ free value_range_constant_singleton to remove need for
+ op_with_constant_singleton_value delegator method. Do not
+ create a vrp_prop class instance for every call! Narrow
+ scope of a couple variables.
+ (evrp_dom_walker::cleanup): Call methods in attached
+ evrp_range_analyzer class via class instance pointer.
+ * vr-values.h (class vr_values): Privatize many methods and
+ data members.
+
2017-11-22 Richard Sandiford <richard.sandiford@linaro.org>
* tree.def (REDUC_MAX_EXPR, REDUC_MIN_EXPR, REDUC_PLUS_EXPR): Delete.
FOR_EACH_EDGE (e, ei, bb->preds)
e->flags |= EDGE_EXECUTABLE;
}
+ vr_values = new class vr_values;
}
void
value_range *old_vr = get_value_range (name);
/* Discover VR when condition is true. */
- extract_range_for_var_from_comparison_expr (name, code, op,
- limit, &vr);
+ vr_values->extract_range_for_var_from_comparison_expr (name, code, op,
+ limit, &vr);
/* If we found any usable VR, set the VR to ssa_name and create a
PUSH old value in the stack with the old VR. */
if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
&& vrp_operand_equal_p (old_vr->min, vr.min)
&& vrp_operand_equal_p (old_vr->max, vr.max))
return NULL;
- value_range *new_vr = vr_values.vrp_value_range_pool.allocate ();
+ value_range *new_vr = vr_values->vrp_value_range_pool.allocate ();
*new_vr = vr;
return new_vr;
}
value_range vr_result = VR_INITIALIZER;
bool interesting = stmt_interesting_for_vrp (phi);
if (!has_unvisited_preds && interesting)
- extract_range_from_phi_node (phi, &vr_result);
+ vr_values->extract_range_from_phi_node (phi, &vr_result);
else
{
set_value_range_to_varying (&vr_result);
if (interesting
&& (l = loop_containing_stmt (phi))
&& l->header == gimple_bb (phi))
- adjust_range_with_scev (&vr_result, l, phi, lhs);
+ vr_values->adjust_range_with_scev (&vr_result, l, phi, lhs);
}
- update_value_range (lhs, &vr_result);
+ vr_values->update_value_range (lhs, &vr_result);
/* Set the SSA with the value range. */
if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
{
edge taken_edge;
value_range vr = VR_INITIALIZER;
- extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
+ vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
if (output
&& (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE))
{
- update_value_range (output, &vr);
+ vr_values->update_value_range (output, &vr);
/* Set the SSA with the value range. */
if (INTEGRAL_TYPE_P (TREE_TYPE (output)))
set_ptr_nonnull (output);
}
else
- set_defs_to_varying (stmt);
+ vr_values->set_defs_to_varying (stmt);
}
else
- set_defs_to_varying (stmt);
+ vr_values->set_defs_to_varying (stmt);
/* See if we can derive a range for any of STMT's operands. */
tree op;
fprintf (dump_file, "\n");
}
stack.safe_push (std::make_pair (var, get_value_range (var)));
- set_vr_value (var, vr);
+ vr_values->set_vr_value (var, vr);
}
/* Pop the Value Range from the vrp_stack and update VAR with it. */
dump_value_range (dump_file, vr);
fprintf (dump_file, "\n");
}
- set_vr_value (var, vr);
+ vr_values->set_vr_value (var, vr);
stack.pop ();
return vr;
}
{
public:
evrp_range_analyzer (void);
- ~evrp_range_analyzer (void) { stack.release (); }
+ ~evrp_range_analyzer (void)
+ {
+ delete vr_values;
+ stack.release ();
+ }
void enter (basic_block);
void leave (basic_block);
void record_ranges_from_stmt (gimple *);
- class vr_values vr_values;
+ /* Main interface to retrieve range information. */
+ value_range *get_value_range (const_tree op)
+ { return vr_values->get_value_range (op); }
+
+ /* Dump all the current value ranges. This is primarily
+ a debugging interface. */
+ void dump_all_value_ranges (FILE *fp)
+ { vr_values->dump_all_value_ranges (fp); }
+
+ /* A bit of a wart. This should ideally go away. */
+ void vrp_visit_cond_stmt (gcond *cond, edge *e)
+ { return vr_values->vrp_visit_cond_stmt (cond, e); }
+
+ /* Get the underlying vr_values class instance. If TRANSFER is
+ true, then we are transferring ownership. Else we keep ownership.
+
+ This should be converted to a unique_ptr. */
+ class vr_values *get_vr_values (bool transfer)
+ {
+ class vr_values *x = vr_values;
+ if (transfer)
+ vr_values = NULL;
+ return x;
+ }
private:
DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
+ class vr_values *vr_values;
+
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);
/* STACK holds the old VR. */
auto_vec<std::pair <tree, value_range*> > stack;
-
- /* Temporary delegators. */
- value_range *get_value_range (const_tree op)
- { return vr_values.get_value_range (op); }
- bool update_value_range (const_tree op, value_range *vr)
- { 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 adjust_range_with_scev (value_range *vr, struct loop *loop,
- gimple *stmt, tree var)
- { vr_values.adjust_range_with_scev (vr, loop, stmt, var); }
- 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); }
- void set_defs_to_varying (gimple *stmt)
- { 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 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); }
};
#endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */
{
public:
tree get_value (tree) FINAL OVERRIDE;
-
+ evrp_folder (class vr_values *vr_values_) : vr_values (vr_values_) { }
class vr_values *vr_values;
+
+ private:
+ DISABLE_COPY_AND_ASSIGN (evrp_folder);
};
tree
class evrp_dom_walker : public dom_walker
{
public:
- evrp_dom_walker () : dom_walker (CDI_DOMINATORS)
+ evrp_dom_walker ()
+ : dom_walker (CDI_DOMINATORS),
+ evrp_folder (evrp_range_analyzer.get_vr_values (false))
{
need_eh_cleanup = BITMAP_ALLOC (NULL);
}
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)
- { evrp_range_analyzer.vr_values.vrp_visit_cond_stmt (cond, e); }
+ class evrp_folder evrp_folder;
};
edge
if (virtual_operand_p (lhs))
continue;
+ value_range *vr = evrp_range_analyzer.get_value_range (lhs);
/* Mark PHIs whose lhs we fully propagate for removal. */
- tree val = op_with_constant_singleton_value_range (lhs);
+ tree val = value_range_constant_singleton (vr);
if (val && may_propagate_copy (lhs, val))
{
stmts_to_remove.safe_push (phi);
if (gcond *cond = dyn_cast <gcond *> (stmt))
{
- vrp_visit_cond_stmt (cond, &taken_edge);
+ evrp_range_analyzer.vrp_visit_cond_stmt (cond, &taken_edge);
if (taken_edge)
{
if (taken_edge->flags & EDGE_TRUE_VALUE)
}
else if (stmt_interesting_for_vrp (stmt))
{
- value_range vr = VR_INITIALIZER;
output = get_output_for_vrp (stmt);
if (output)
{
tree val;
- vr = *get_value_range (output);
+ value_range *vr = evrp_range_analyzer.get_value_range (output);
/* Mark stmts whose output we fully propagate for removal. */
- if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
- && (val = op_with_constant_singleton_value_range (output))
+ if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
+ && (val = value_range_constant_singleton (vr))
&& may_propagate_copy (output, val)
&& !stmt_could_throw_p (stmt)
&& !gimple_has_side_effects (stmt))
}
/* Try folding stmts with the VR discovered. */
- class evrp_folder evrp_folder;
- 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)
if (TREE_CODE (arg) != SSA_NAME
|| virtual_operand_p (arg))
continue;
- tree val = op_with_constant_singleton_value_range (arg);
+ value_range *vr = evrp_range_analyzer.get_value_range (arg);
+ tree val = value_range_constant_singleton (vr);
if (val && may_propagate_copy (arg, val))
propagate_value (use_p, val);
}
if (dump_file)
{
fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
- evrp_range_analyzer.vr_values.dump_all_value_ranges (dump_file);
+ evrp_range_analyzer.dump_all_value_ranges (dump_file);
fprintf (dump_file, "\n");
}
vr_values (void);
~vr_values (void);
- /* Value range array. After propagation, VR_VALUE[I] holds the range
- of values that SSA name N_I may take. */
- unsigned int num_vr_values;
- value_range **vr_value;
- bool values_propagated;
+ value_range *get_value_range (const_tree);
- /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
- number of executable edges we saw the last time we visited the
- node. */
- int *vr_phi_edge_counts;
+ void set_vr_value (tree, value_range *);
+ void set_defs_to_varying (gimple *);
+ bool update_value_range (const_tree, value_range *);
+ tree op_with_constant_singleton_value_range (tree);
+ void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree);
+ tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
+ void dump_all_value_ranges (FILE *);
+
+ void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
+ tree, tree, value_range *);
+ void extract_range_from_phi_node (gphi *, value_range *);
+ void extract_range_basic (value_range *, gimple *);
+ void extract_range_from_assignment (value_range *, gassign *);
+ void extract_range_from_stmt (gimple *, edge *, tree *, value_range *);
+
+ void vrp_visit_cond_stmt (gcond *, edge *);
+
+ void simplify_cond_using_ranges_2 (gcond *);
+ bool simplify_stmt_using_ranges (gimple_stmt_iterator *);
+
+ /* This probably belongs in the lattice rather than in here. */
+ bool values_propagated;
/* Allocation pools for tree-vrp allocations. */
object_allocator<value_range> vrp_value_range_pool;
- bitmap_obstack vrp_equiv_obstack;
- value_range *get_value_range (const_tree);
- void set_vr_value (tree, value_range *);
-
- void set_defs_to_varying (gimple *);
- bool update_value_range (const_tree, value_range *);
+ private:
+ bitmap_obstack vrp_equiv_obstack;
void add_equivalence (bitmap *, const_tree);
bool vrp_stmt_computes_nonzero (gimple *);
- tree op_with_constant_singleton_value_range (tree);
bool op_with_boolean_value_range_p (tree);
bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *);
- void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree);
value_range get_vr_for_comparison (int);
tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool);
tree compare_names (enum tree_code, tree, tree, bool *);
bool two_valued_val_range_p (tree, tree *, tree *);
-
tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code,
tree, tree,
bool *);
tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code,
tree, tree, bool,
bool *, bool *);
- tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
-
-
- void dump_all_value_ranges (FILE *);
-
- void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
- tree, tree, value_range *);
void extract_range_from_assert (value_range *, tree);
void extract_range_from_ssa_name (value_range *, tree);
void extract_range_from_binary_expr (value_range *, enum tree_code,
tree, tree, tree);
void extract_range_from_unary_expr (value_range *, enum tree_code,
tree, tree);
- void extract_range_from_phi_node (gphi *, value_range *);
void extract_range_from_cond_expr (value_range *, gassign *);
- void extract_range_basic (value_range *, gimple *);
- void extract_range_from_assignment (value_range *, gassign *);
- void extract_range_from_stmt (gimple *, edge *, tree *, value_range *);
void extract_range_from_comparison (value_range *, enum tree_code,
tree, tree, tree);
-
void vrp_visit_assignment_or_call (gimple*, tree *, value_range *);
void vrp_visit_switch_stmt (gswitch *, edge *);
- void vrp_visit_cond_stmt (gcond *, edge *);
-
bool simplify_truth_ops_using_ranges (gimple_stmt_iterator *, gimple *);
bool simplify_div_or_mod_using_ranges (gimple_stmt_iterator *, gimple *);
bool simplify_abs_using_ranges (gimple_stmt_iterator *, gimple *);
bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *, gimple *);
bool simplify_min_or_max_using_ranges (gimple_stmt_iterator *, gimple *);
bool simplify_cond_using_ranges_1 (gcond *);
- void simplify_cond_using_ranges_2 (gcond *);
bool simplify_switch_using_ranges (gswitch *);
bool simplify_float_conversion_using_ranges (gimple_stmt_iterator *,
gimple *);
bool simplify_internal_call_using_ranges (gimple_stmt_iterator *, gimple *);
- bool simplify_stmt_using_ranges (gimple_stmt_iterator *);
+
+ /* Value range array. After propagation, VR_VALUE[I] holds the range
+ of values that SSA name N_I may take. */
+ unsigned int num_vr_values;
+ value_range **vr_value;
+
+ /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
+ number of executable edges we saw the last time we visited the
+ node. */
+ int *vr_phi_edge_counts;
};
#define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }