{
public:
name_prop (loop_info &li) : m_li (li) {}
- tree get_value (tree, gimple *) FINAL OVERRIDE;
+ tree value_of_expr (tree name, gimple *) FINAL OVERRIDE;
private:
/* Information about the versioning we've performed on the loop. */
m_range_analyzer.enter (bb);
if (bb == bb->loop_father->header)
- m_lv.prune_loop_conditions (bb->loop_father,
- m_range_analyzer.get_vr_values ());
+ m_lv.prune_loop_conditions (bb->loop_father, &m_range_analyzer);
for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
gsi_next (&si))
Return the new value if so, otherwise return null. */
tree
-loop_versioning::name_prop::get_value (tree val,
- gimple *stmt ATTRIBUTE_UNUSED)
+loop_versioning::name_prop::value_of_expr (tree val, gimple *)
{
if (TREE_CODE (val) == SSA_NAME
&& bitmap_bit_p (&m_li.unity_names, SSA_NAME_VERSION (val)))
FOR_EACH_EDGE (e, ei, bb->preds)
e->flags |= EDGE_EXECUTABLE;
}
- vr_values = new class vr_values;
}
/* Push an unwinding marker onto the unwinding stack. */
const value_range_equiv *old_vr = get_value_range (name);
/* Discover VR when condition is true. */
- vr_values->extract_range_for_var_from_comparison_expr (name, code, op,
- limit, &vr);
+ 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.undefined_p () && !vr.varying_p ())
{
if (old_vr->equal_p (vr, /*ignore_equivs=*/true))
return NULL;
- value_range_equiv *new_vr = vr_values->allocate_value_range_equiv ();
+ value_range_equiv *new_vr = allocate_value_range_equiv ();
new_vr->move (&vr);
return new_vr;
}
tem.intersect (vrs[i].second);
if (tem.equal_p (*old_vr))
{
- vr_values->free_value_range (vrs[i].second);
+ free_value_range (vrs[i].second);
continue;
}
push_value_range (vrs[i].first, vrs[i].second);
value_range_equiv vr_result;
bool interesting = stmt_interesting_for_vrp (phi);
if (!has_unvisited_preds && interesting)
- vr_values->extract_range_from_phi_node (phi, &vr_result);
+ extract_range_from_phi_node (phi, &vr_result);
else
{
vr_result.set_varying (TREE_TYPE (lhs));
&& interesting
&& (l = loop_containing_stmt (phi))
&& l->header == gimple_bb (phi))
- vr_values->adjust_range_with_scev (&vr_result, l, phi, lhs);
+ adjust_range_with_scev (&vr_result, l, phi, lhs);
}
- vr_values->update_value_range (lhs, &vr_result);
+ update_value_range (lhs, &vr_result);
/* Set the SSA with the value range. */
if (m_update_global_ranges)
{
edge taken_edge;
value_range_equiv vr;
- vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
+ extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
if (output)
{
/* Set the SSA with the value range. There are two cases to
{
/* Case one. We can just update the underlying range
information as well as the global information. */
- vr_values->update_value_range (output, &vr);
+ update_value_range (output, &vr);
if (m_update_global_ranges)
set_ssa_range_info (output, &vr);
}
a new range and push the old range onto the stack. We
also have to be very careful about sharing the underlying
bitmaps. Ugh. */
- value_range_equiv *new_vr
- = vr_values->allocate_value_range_equiv ();
+ value_range_equiv *new_vr = allocate_value_range_equiv ();
new_vr->set (vr.min (), vr.max (), NULL, vr.kind ());
vr.equiv_clear ();
push_value_range (output, new_vr);
}
}
else
- vr_values->set_defs_to_varying (stmt);
+ set_defs_to_varying (stmt);
}
else
- vr_values->set_defs_to_varying (stmt);
+ set_defs_to_varying (stmt);
/* See if we can derive a range for any of STMT's operands. */
tree op;
dump_value_range (dump_file, vr);
fprintf (dump_file, "\n");
}
- value_range_equiv *old_vr = vr_values->swap_vr_value (var, vr);
+ value_range_equiv *old_vr = swap_vr_value (var, vr);
stack.safe_push (std::make_pair (var, old_vr));
}
}
/* We saved off a lattice entry, now give it back and release
the one we popped. */
- value_range_equiv *popped_vr = vr_values->swap_vr_value (var, vr);
+ value_range_equiv *popped_vr = swap_vr_value (var, vr);
if (popped_vr)
- vr_values->free_value_range (popped_vr);
+ free_value_range (popped_vr);
}
#ifndef GCC_GIMPLE_SSA_EVRP_ANALYZE_H
#define GCC_GIMPLE_SSA_EVRP_ANALYZE_H
-class evrp_range_analyzer
+class evrp_range_analyzer : public vr_values
{
public:
evrp_range_analyzer (bool update_global_ranges);
~evrp_range_analyzer (void)
{
- delete vr_values;
stack.release ();
}
void leave (basic_block);
void record_ranges_from_stmt (gimple *, bool);
- /* Main interface to retrieve range information. */
- const value_range_equiv *get_value_range (const_tree op)
- { return vr_values->get_value_range (op); }
-
/* Record a new unwindable range. */
void push_value_range (tree var, value_range_equiv *vr);
- /* 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)
{
- simplify_using_ranges simpl (vr_values);
+ simplify_using_ranges simpl (this);
simpl.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 (void) { return vr_values; }
-
private:
DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
- class vr_values *vr_values;
void pop_value_range ();
value_range_equiv *try_find_new_range (tree, tree op, tree_code code,
class evrp_folder : public substitute_and_fold_engine
{
public:
- evrp_folder () : m_range_analyzer (/*update_global_ranges=*/true),
- m_vr_values (m_range_analyzer.get_vr_values ()),
- simplifier (m_vr_values)
- {
- }
+ evrp_folder () :
+ substitute_and_fold_engine (),
+ m_range_analyzer (/*update_global_ranges=*/true),
+ simplifier (&m_range_analyzer)
+ { }
~evrp_folder ()
{
}
}
- tree get_value (tree op, gimple *stmt ATTRIBUTE_UNUSED) OVERRIDE
+ tree value_of_expr (tree name, gimple *stmt) OVERRIDE
{
- return m_vr_values->op_with_constant_singleton_value_range (op);
+ return m_range_analyzer.value_of_expr (name, stmt);
}
void pre_fold_bb (basic_block bb) OVERRIDE
void post_new_stmt (gimple *stmt) OVERRIDE
{
- m_range_analyzer.get_vr_values ()->set_defs_to_varying (stmt);
+ m_range_analyzer.set_defs_to_varying (stmt);
}
private:
DISABLE_COPY_AND_ASSIGN (evrp_folder);
- class evrp_range_analyzer m_range_analyzer;
- class vr_values *m_vr_values;
-
+ evrp_range_analyzer m_range_analyzer;
simplify_using_ranges simplifier;
};
class ccp_folder : public substitute_and_fold_engine
{
public:
- tree get_value (tree, gimple *) FINAL OVERRIDE;
+ tree value_of_expr (tree, gimple *) FINAL OVERRIDE;
bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE;
};
of calling member functions. */
tree
-ccp_folder::get_value (tree op, gimple *stmt ATTRIBUTE_UNUSED)
+ccp_folder::value_of_expr (tree op, gimple *)
{
return get_constant_value (op);
}
class copy_folder : public substitute_and_fold_engine
{
public:
- tree get_value (tree, gimple *) FINAL OVERRIDE;
+ tree value_of_expr (tree name, gimple *) FINAL OVERRIDE;
};
/* Callback for substitute_and_fold to get at the final copy-of values. */
tree
-copy_folder::get_value (tree name, gimple *stmt ATTRIBUTE_UNUSED)
+copy_folder::value_of_expr (tree name, gimple *)
{
tree val;
if (SSA_NAME_VERSION (name) >= n_copy_of)
void
dom_opt_dom_walker::after_dom_children (basic_block bb)
{
- x_vr_values = evrp_range_analyzer.get_vr_values ();
+ x_vr_values = &evrp_range_analyzer;
thread_outgoing_edges (bb, m_dummy_cond, m_const_and_copies,
m_avail_exprs_stack,
&evrp_range_analyzer,
opt_stats.num_stmts++;
/* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */
- cprop_into_stmt (stmt, evrp_range_analyzer.get_vr_values ());
+ cprop_into_stmt (stmt, &evrp_range_analyzer);
/* If the statement has been modified with constant replacements,
fold its RHS before checking for redundant computations. */
FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE)
{
tree tuse = USE_FROM_PTR (use);
- tree val = get_value (tuse, stmt);
+ tree val = value_of_expr (tuse, stmt);
if (val == tuse || val == NULL_TREE)
continue;
if (TREE_CODE (arg) == SSA_NAME)
{
- tree val = get_value (arg, phi);
+ edge e = gimple_phi_arg_edge (phi, i);
+ tree val = value_on_edge (e, arg);
if (val && val != arg && may_propagate_copy (arg, val))
{
- edge e = gimple_phi_arg_edge (phi, i);
-
if (TREE_CODE (val) != SSA_NAME)
prop_stats.num_const_prop++;
else
if (TREE_CODE (arg) != SSA_NAME
|| virtual_operand_p (arg))
continue;
- tree val = get_value (arg, phi);
+ tree val = value_on_edge (e, arg);
if (val
&& is_gimple_min_invariant (val)
&& may_propagate_copy (arg, val))
}
if (res && TREE_CODE (res) == SSA_NAME)
{
- tree sprime = substitute_and_fold_engine->get_value (res, phi);
+ tree sprime = substitute_and_fold_engine->value_of_expr (res, phi);
if (sprime
&& sprime != res
&& may_propagate_copy (res, sprime))
tree lhs = gimple_get_lhs (stmt);
if (lhs && TREE_CODE (lhs) == SSA_NAME)
{
- tree sprime = substitute_and_fold_engine->get_value (lhs, stmt);
+ tree sprime = substitute_and_fold_engine->value_of_expr (lhs, stmt);
if (sprime
&& sprime != lhs
&& may_propagate_copy (lhs, sprime)
#ifndef _TREE_SSA_PROPAGATE_H
#define _TREE_SSA_PROPAGATE_H 1
+#include "value-query.h"
+
/* If SIM_P is true, statement S will be simulated again. */
static inline void
void simulate_block (basic_block);
};
-class substitute_and_fold_engine
+class substitute_and_fold_engine : public value_query
{
public:
substitute_and_fold_engine (bool fold_all_stmts = false)
: fold_all_stmts (fold_all_stmts) { }
virtual ~substitute_and_fold_engine (void) { }
virtual bool fold_stmt (gimple_stmt_iterator *) { return false; }
- virtual tree get_value (tree, gimple *) { return NULL_TREE; }
bool substitute_and_fold (basic_block = NULL);
bool replace_uses_in (gimple *);
can be used by printf argument processing. */
evrp.record_ranges_from_stmt (stmt, false);
- if (check_and_optimize_stmt (&gsi, &cleanup_eh, evrp.get_vr_values ()))
+ if (check_and_optimize_stmt (&gsi, &cleanup_eh, &evrp))
gsi_next (&gsi);
}
{
/* Get an empty new VR we can pass to update_value_range and save
away in the VR stack. */
- vr_values *vr_values = evrp_range_analyzer->get_vr_values ();
- value_range_equiv *new_vr = vr_values->allocate_value_range_equiv ();
+ value_range_equiv *new_vr
+ = evrp_range_analyzer->allocate_value_range_equiv ();
new (new_vr) value_range_equiv ();
/* There are three cases to consider:
Otherwise set NEW_VR to varying. This may be overly
conservative. */
if (TREE_CODE (src) == SSA_NAME)
- new_vr->deep_copy (vr_values->get_value_range (src));
+ new_vr->deep_copy (evrp_range_analyzer->get_value_range (src));
else if (TREE_CODE (src) == INTEGER_CST)
new_vr->set (src);
else
: substitute_and_fold_engine (/* Fold all stmts. */ true),
m_vr_values (v), simplifier (v)
{ }
- tree get_value (tree, gimple *stmt) FINAL OVERRIDE;
bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE;
+ tree value_of_expr (tree name, gimple *stmt) OVERRIDE
+ {
+ return m_vr_values->value_of_expr (name, stmt);
+ }
class vr_values *m_vr_values;
private:
{ return simplifier.vrp_evaluate_conditional (code, op0, op1, stmt); }
bool simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
{ return simplifier.simplify (gsi); }
- tree op_with_constant_singleton_value_range (tree op)
- { return m_vr_values->op_with_constant_singleton_value_range (op); }
simplify_using_ranges simplifier;
};
return simplify_stmt_using_ranges (si);
}
-/* If OP has a value range with a single constant value return that,
- otherwise return NULL_TREE. This returns OP itself if OP is a
- constant.
-
- Implemented as a pure wrapper right now, but this will change. */
-
-tree
-vrp_folder::get_value (tree op, gimple *stmt ATTRIBUTE_UNUSED)
-{
- return op_with_constant_singleton_value_range (op);
-}
-
/* Return the LHS of any ASSERT_EXPR where OP appears as the first
argument to the ASSERT_EXPR and in which the ASSERT_EXPR dominates
BB. If no such ASSERT_EXPR is found, return OP. */
return vr;
/* Create a default value range. */
- vr = new (vrp_value_range_pool.allocate ()) value_range_equiv;
+ vr = allocate_value_range_equiv ();
vr_value[ver] = vr;
/* After propagation finished return varying. */
return vr;
}
+bool
+vr_values::range_of_expr (irange &r, tree name, gimple *stmt)
+{
+ if (const value_range *vr = get_value_range (name, stmt))
+ {
+ if (vr->undefined_p () || vr->varying_p () || vr->constant_p ())
+ r = *vr;
+ else
+ {
+ value_range tmp = *vr;
+ tmp.normalize_symbolics ();
+ r = tmp;
+ }
+ return true;
+ }
+ return false;
+}
+
+tree
+vr_values::value_of_expr (tree op, gimple *)
+{
+ return op_with_constant_singleton_value_range (op);
+}
+
+tree
+vr_values::value_on_edge (edge, tree op)
+{
+ return op_with_constant_singleton_value_range (op);
+}
+
+tree
+vr_values::value_of_stmt (gimple *stmt, tree op)
+{
+ if (!op)
+ op = gimple_get_lhs (stmt);
+
+ gcc_checking_assert (!op|| op == gimple_get_lhs (stmt));
+
+ if (op)
+ return op_with_constant_singleton_value_range (op);
+ return NULL_TREE;
+}
+
/* Set the lattice entry for DEF to VARYING. */
void
/* ?? Errr, this should probably check for [0,0] and [1,1] as well
as [0,1]. */
- const value_range *vr = get_value_range (op);
+ const value_range *vr = query->get_value_range (op);
return *vr == value_range (build_zero_cst (TREE_TYPE (op)),
build_one_cst (TREE_TYPE (op)));
}
overflow. */
static bool
-check_for_binary_op_overflow (range_query *store,
+check_for_binary_op_overflow (range_query *query,
enum tree_code subcode, tree type,
tree op0, tree op1, bool *ovf)
{
value_range vr0, vr1;
if (TREE_CODE (op0) == SSA_NAME)
- vr0 = *store->get_value_range (op0);
+ vr0 = *query->get_value_range (op0);
else if (TREE_CODE (op0) == INTEGER_CST)
vr0.set (op0);
else
vr0.set_varying (TREE_TYPE (op0));
if (TREE_CODE (op1) == SSA_NAME)
- vr1 = *store->get_value_range (op1);
+ vr1 = *query->get_value_range (op1);
else if (TREE_CODE (op1) == INTEGER_CST)
vr1.set (op1);
else
/* Initialize VRP lattice. */
-vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges"),
- simplifier (this)
+vr_values::vr_values () : simplifier (this)
{
values_propagated = false;
num_vr_values = num_ssa_names * 2;
free (vr_value);
free (vr_phi_edge_counts);
bitmap_obstack_release (&vrp_equiv_obstack);
- vrp_value_range_pool.release ();
/* So that we can distinguish between VRP data being available
and not available. */
simplify_using_ranges::get_vr_for_comparison (int i, value_range_equiv *tem)
{
/* Shallow-copy equiv bitmap. */
- const value_range_equiv *vr = get_value_range (ssa_name (i));
+ const value_range_equiv *vr = query->get_value_range (ssa_name (i));
/* If name N_i does not have a valid range, use N_i as its own
range. This allows us to compare against names that may
bool *strict_overflow_p, bool use_equiv_p)
{
/* Get the set of equivalences for VAR. */
- bitmap e = get_value_range (var)->equiv ();
+ bitmap e = query->get_value_range (var)->equiv ();
/* Start at -1. Set it to 0 if we do a comparison without relying
on overflow, or 1 if all comparisons rely on overflow. */
{
/* Compare the ranges of every name equivalent to N1 against the
ranges of every name equivalent to N2. */
- bitmap e1 = get_value_range (n1)->equiv ();
- bitmap e2 = get_value_range (n2)->equiv ();
+ bitmap e1 = query->get_value_range (n1)->equiv ();
+ bitmap e2 = query->get_value_range (n2)->equiv ();
/* Use the fake bitmaps if e1 or e2 are not available. */
static bitmap s_e1 = NULL, s_e2 = NULL;
(enum tree_code code, tree op0, tree op1, bool * strict_overflow_p)
{
const value_range_equiv *vr0, *vr1;
- vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
- vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
+ vr0 = (TREE_CODE (op0) == SSA_NAME) ? query->get_value_range (op0) : NULL;
+ vr1 = (TREE_CODE (op1) == SSA_NAME) ? query->get_value_range (op1) : NULL;
tree res = NULL_TREE;
if (vr0 && vr1)
}
else
gcc_unreachable ();
- const value_range_equiv *vr0 = get_value_range (op0, stmt);
+ const value_range_equiv *vr0 = query->get_value_range (op0, stmt);
/* If vro, the range for OP0 to pass the overflow test, has
no intersection with *vr0, OP0's known range, then the
overflow test can't pass, so return the node for false.
always fold regardless of the value of OP0. If -Wtype-limits
was specified, emit a warning. */
tree type = TREE_TYPE (op0);
- const value_range_equiv *vr0 = get_value_range (op0, stmt);
+ const value_range_equiv *vr0 = query->get_value_range (op0, stmt);
if (vr0->varying_p ()
&& INTEGRAL_TYPE_P (type)
fprintf (dump_file, "\t");
print_generic_expr (dump_file, use);
fprintf (dump_file, ": ");
- dump_value_range (dump_file, get_value_range (use, stmt));
+ dump_value_range (dump_file, query->get_value_range (use, stmt));
}
fprintf (dump_file, "\n");
}
else
{
- vr = get_value_range (op0, stmt);
+ vr = query->get_value_range (op0, stmt);
if (range_int_cst_p (vr))
{
op0min = vr->min ();
if (rhs_code == TRUNC_MOD_EXPR
&& TREE_CODE (op1) == SSA_NAME)
{
- const value_range_equiv *vr1 = get_value_range (op1, stmt);
+ const value_range_equiv *vr1 = query->get_value_range (op1, stmt);
if (range_int_cst_p (vr1))
op1min = vr1->min ();
}
gimple *stmt)
{
tree op = gimple_assign_rhs1 (stmt);
- const value_range *vr = get_value_range (op, stmt);
+ const value_range *vr = query->get_value_range (op, stmt);
if (vr)
{
wide_int mask;
if (TREE_CODE (op0) == SSA_NAME)
- vr0 = *(get_value_range (op0, stmt));
+ vr0 = *(query->get_value_range (op0, stmt));
else if (is_gimple_min_invariant (op0))
vr0.set (op0);
else
return false;
if (TREE_CODE (op1) == SSA_NAME)
- vr1 = *(get_value_range (op1, stmt));
+ vr1 = *(query->get_value_range (op1, stmt));
else if (is_gimple_min_invariant (op1))
vr1.set (op1);
else
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
&& is_gimple_min_invariant (op1))
{
- const value_range *vr = get_value_range (op0, stmt);
+ const value_range *vr = query->get_value_range (op0, stmt);
/* If we have range information for OP0, then we might be
able to simplify this conditional. */
subsequent passes. */
void
-simplify_cond_using_ranges_2 (vr_values *store, gcond *stmt)
+simplify_cond_using_ranges_2 (vr_values *query, gcond *stmt)
{
tree op0 = gimple_cond_lhs (stmt);
tree op1 = gimple_cond_rhs (stmt);
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
&& desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
{
- const value_range *vr = store->get_value_range (innerop);
+ const value_range *vr = query->get_value_range (innerop);
if (range_int_cst_p (vr)
&& range_fits_type_p (vr,
if (TREE_CODE (op) == SSA_NAME)
{
- vr = get_value_range (op, stmt);
+ vr = query->get_value_range (op, stmt);
/* We can only handle integer ranges. */
if (vr->varying_p ()
gimple *stmt)
{
tree rhs1 = gimple_assign_rhs1 (stmt);
- const value_range *vr = get_value_range (rhs1, stmt);
+ const value_range *vr = query->get_value_range (rhs1, stmt);
scalar_float_mode fltmode
= SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
scalar_int_mode mode;
return false;
else
type = TREE_TYPE (TREE_TYPE (gimple_call_lhs (stmt)));
- if (!check_for_binary_op_overflow (store, subcode, type, op0, op1, &ovf)
+ if (!check_for_binary_op_overflow (query, subcode, type, op0, op1, &ovf)
|| (is_ubsan && ovf))
return false;
bool
simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b)
{
- value_range vr = *get_value_range (var);
+ value_range vr = *query->get_value_range (var);
vr.normalize_symbolics ();
if (vr.varying_p () || vr.undefined_p ())
return false;
return false;
}
-simplify_using_ranges::simplify_using_ranges (range_query *store)
- : store (store)
+simplify_using_ranges::simplify_using_ranges (range_query *query)
+ : query (query)
{
to_remove_edges = vNULL;
to_update_switch_stmts = vNULL;
bool
simplify_using_ranges::simplify (gimple_stmt_iterator *gsi)
{
+ gcc_checking_assert (query);
+
gimple *stmt = gsi_stmt (*gsi);
if (is_gimple_assign (stmt))
{
#define GCC_VR_VALUES_H
#include "value-range-equiv.h"
+#include "value-query.h"
// Abstract class to return a range for a given SSA.
-class range_query
-{
-public:
- virtual const value_range_equiv *get_value_range (const_tree,
- gimple * = NULL) = 0;
- virtual ~range_query () { }
-};
-
// Class to simplify a statement using range information.
-//
-// The constructor takes a full vr_values, but all it needs is
-// get_value_range() from it. This class could be made to work with
-// any range repository.
-class simplify_using_ranges : public range_query
+class simplify_using_ranges
{
public:
- simplify_using_ranges (class range_query *);
+ simplify_using_ranges (class range_query *query = NULL);
~simplify_using_ranges ();
+ void set_range_query (class range_query *q) { query = q; }
+
bool simplify (gimple_stmt_iterator *);
// ?? These should be cleaned, merged, and made private.
bool *, bool *);
private:
- const value_range_equiv *get_value_range (const_tree op,
- gimple *stmt = NULL) OVERRIDE;
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 *);
vec<edge> to_remove_edges;
vec<switch_update> to_update_switch_stmts;
- class range_query *store;
+ class range_query *query;
};
/* The VR_VALUES class holds the current view of range information
vr_values (void);
~vr_values (void);
- const value_range_equiv *get_value_range (const_tree, gimple * = NULL);
+ virtual bool range_of_expr (irange &r, tree name, gimple *stmt) OVERRIDE;
+ virtual tree value_of_expr (tree, gimple * = NULL) OVERRIDE;
+ virtual tree value_on_edge (edge, tree) OVERRIDE;
+ virtual tree value_of_stmt (gimple *, tree = NULL_TREE) OVERRIDE;
+ virtual const value_range_equiv *get_value_range (const_tree,
+ gimple * = NULL) OVERRIDE;
void set_vr_value (tree, value_range_equiv *);
value_range_equiv *swap_vr_value (tree, value_range_equiv *);
/* Allocate a new value_range object. */
value_range_equiv *allocate_value_range_equiv (void)
- { return vrp_value_range_pool.allocate (); }
+ { return range_query::allocate_value_range_equiv (); }
void free_value_range (value_range_equiv *vr)
- { vrp_value_range_pool.remove (vr); }
+ { free_value_range_equiv (vr); }
private:
value_range_equiv *get_lattice_entry (const_tree);
void vrp_visit_assignment_or_call (gimple*, tree *, value_range_equiv *);
void vrp_visit_switch_stmt (gswitch *, edge *);
- /* Allocation pools for value_range objects. */
- object_allocator<value_range_equiv> vrp_value_range_pool;
-
/* This probably belongs in the lattice rather than in here. */
bool values_propagated;
simplify_using_ranges simplifier;
};
-inline const value_range_equiv *
-simplify_using_ranges::get_value_range (const_tree op, gimple *stmt)
-{
- return store->get_value_range (op, stmt);
-}
-
extern tree get_output_for_vrp (gimple *);
// FIXME: Move this to tree-vrp.c.