aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2019-11-21 15:22:32 +0000
committerAldy Hernandez <aldyh@redhat.com>2019-11-21 15:22:32 +0000
commit0dc3990559bf01fd5c4d4f9badc297fbed163ed7 (patch)
tree2db4dde6d337ccf0a88050c0ab23a17a716f73d0
parentf3383e55409e05fc178f669e2194511a7bc1ddf1 (diff)
Convert gori to irange.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ranger@278561 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/gimple-range-gori.cc107
-rw-r--r--gcc/gimple-range-gori.h76
-rw-r--r--gcc/gimple-range.cc53
-rw-r--r--gcc/gimple-range.h30
-rw-r--r--gcc/gimple-ssa-evrp-analyze.c46
-rw-r--r--gcc/gimple-ssa-evrp-analyze.h10
-rw-r--r--gcc/value-range.cc95
-rw-r--r--gcc/vr-values.c31
-rw-r--r--gcc/vr-values.h21
9 files changed, 254 insertions, 215 deletions
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index f23a492768b..7bdd3cc758e 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -482,7 +482,7 @@ debug (gori_map &g)
// Return the legacy global known value for NAME in R.
void
-gori_compute::range_of_ssa_name (value_range &r, tree name,
+gori_compute::range_of_ssa_name (irange &r, tree name,
gimple *s ATTRIBUTE_UNUSED)
{
r = gimple_range_global (name);
@@ -495,7 +495,7 @@ gori_compute::range_of_ssa_name (value_range &r, tree name,
// the type of EXPR.
bool
-gori_compute::range_of_expr (value_range &r, tree expr, gimple *s)
+gori_compute::range_of_expr (irange &r, tree expr, gimple *s)
{
tree type;
if (TYPE_P (expr))
@@ -504,7 +504,7 @@ gori_compute::range_of_expr (value_range &r, tree expr, gimple *s)
type = TREE_TYPE (expr);
// Return false if the type isn't suported.
- if (!value_range::supports_type_p (type))
+ if (!irange::supports_type_p (type))
return false;
switch (TREE_CODE (expr))
@@ -514,7 +514,7 @@ gori_compute::range_of_expr (value_range &r, tree expr, gimple *s)
// since we have no idea how it will be used.
if (!TREE_OVERFLOW_P (expr))
{
- r = value_range (expr, expr);
+ r.set (expr, expr);
return true;
}
break;
@@ -549,8 +549,8 @@ gori_compute::range_of_expr (value_range &r, tree expr, gimple *s)
// bases.
void
-gori_compute::get_tree_range (value_range &r, tree expr, tree name,
- const value_range *range_of_name)
+gori_compute::get_tree_range (irange &r, tree expr, tree name,
+ const irange *range_of_name)
{
if (expr == name && range_of_name)
{
@@ -567,12 +567,12 @@ gori_compute::get_tree_range (value_range &r, tree expr, tree name,
// range can be calculated.
bool
-gori_compute::compute_name_range_op (value_range &r, gimple *s,
- const value_range &lhs,
+gori_compute::compute_name_range_op (irange &r, gimple *s,
+ const irange &lhs,
tree name,
- const value_range *name_range)
+ const irange *name_range)
{
- value_range op1_range, op2_range;
+ widest_irange op1_range, op2_range;
tree op1 = gimple_range_operand1 (s);
tree op2 = gimple_range_operand2 (s);
@@ -622,8 +622,8 @@ gori_compute::compute_name_range_op (value_range &r, gimple *s,
gori_compute::gori_compute ()
{
// Create a boolean_type true and false range.
- m_bool_zero = value_range (boolean_false_node, boolean_false_node);
- m_bool_one = value_range (boolean_true_node, boolean_true_node);
+ m_bool_zero = int_range<1> (boolean_false_node, boolean_false_node);
+ m_bool_one = int_range<1> (boolean_true_node, boolean_true_node);
}
// Destruct a gori_compute_object
@@ -638,10 +638,10 @@ gori_compute::~gori_compute ()
// for NAME coming into S.
bool
-gori_compute::compute_operand_range (value_range &r, gimple *s,
- const value_range &lhs,
+gori_compute::compute_operand_range (irange &r, gimple *s,
+ const irange &lhs,
tree name,
- const value_range *name_range)
+ const irange *name_range)
{
if (gimple_range_handler (s))
return compute_operand_range_op (r, s, lhs, name, name_range);
@@ -657,10 +657,10 @@ gori_compute::compute_operand_range (value_range &r, gimple *s,
// NAME coming into S.
bool
-gori_compute::compute_operand_range_switch (value_range &r, gswitch *s,
- const value_range &lhs,
+gori_compute::compute_operand_range_switch (irange &r, gswitch *s,
+ const irange &lhs,
tree name,
- const value_range *name_range)
+ const irange *name_range)
{
tree op1 = gimple_switch_index (s);
@@ -717,10 +717,10 @@ is_gimple_logical_p (const gimple *gs)
// for NAME coming into S.
bool
-gori_compute::compute_operand_range_op (value_range &r, gimple *stmt,
- const value_range &lhs,
+gori_compute::compute_operand_range_op (irange &r, gimple *stmt,
+ const irange &lhs,
tree name,
- const value_range *name_range)
+ const irange *name_range)
{
tree op1, op2;
bool op1_in_chain, op2_in_chain;
@@ -770,12 +770,12 @@ gori_compute::compute_operand_range_op (value_range &r, gimple *stmt,
// the LHS.
bool
-gori_compute::logical_combine (value_range &r, enum tree_code code,
- const value_range &lhs,
- const value_range &op1_true,
- const value_range &op1_false,
- const value_range &op2_true,
- const value_range &op2_false)
+gori_compute::logical_combine (irange &r, enum tree_code code,
+ const irange &lhs,
+ const irange &op1_true,
+ const irange &op1_false,
+ const irange &op2_true,
+ const irange &op2_false)
{
// This is not a simple fold of a logical expression, rather it
// determines ranges which flow through the logical expression.
@@ -814,7 +814,7 @@ gori_compute::logical_combine (value_range &r, enum tree_code code,
// would be lost. */
if (!lhs.singleton_p ())
{
- value_range r1;
+ int_range<1> r1;
if (logical_combine (r1, code, m_bool_zero, op1_true, op1_false,
op2_true, op2_false)
&& logical_combine (r, code, m_bool_one, op1_true, op1_false,
@@ -842,11 +842,11 @@ gori_compute::logical_combine (value_range &r, enum tree_code code,
else
{
// The FALSE side is the union of the other 3 cases.
- value_range ff (op1_false);
+ int_range<1> ff (op1_false);
ff.intersect (op2_false);
- value_range tf (op1_true);
+ int_range<1> tf (op1_true);
tf.intersect (op2_false);
- value_range ft (op1_false);
+ int_range<1> ft (op1_false);
ft.intersect (op2_true);
r = ff;
r.union_ (tf);
@@ -870,11 +870,11 @@ gori_compute::logical_combine (value_range &r, enum tree_code code,
{
// The TRUE side of an OR operation will be the union of
// the other three combinations.
- value_range tt (op1_true);
+ int_range<1> tt (op1_true);
tt.intersect (op2_true);
- value_range tf (op1_true);
+ int_range<1> tf (op1_true);
tf.intersect (op2_false);
- value_range ft (op1_false);
+ int_range<1> ft (op1_false);
ft.intersect (op2_true);
r = tt;
r.union_ (tf);
@@ -895,19 +895,18 @@ gori_compute::logical_combine (value_range &r, enum tree_code code,
// coming into S.
bool
-gori_compute::compute_logical_operands (value_range &r, gimple *s,
- const value_range &lhs,
+gori_compute::compute_logical_operands (irange &r, gimple *s,
+ const irange &lhs,
tree name,
- const value_range *name_range)
+ const irange *name_range)
{
- value_range op1_range, op2_range;
tree op1, op2;
bool op1_in_chain, op2_in_chain;
bool ret = true;
const unsigned depth_limit = 6; // Max depth of logical recursion.
static unsigned depth = 0; // Current depth of recursion.
- value_range op1_true, op1_false, op2_true, op2_false;
+ int_range<1> op1_true, op1_false, op2_true, op2_false;
// Reaching this point means NAME is not in this stmt, but one of
// the names in it ought to be derived from it. */
@@ -985,11 +984,11 @@ gori_compute::compute_logical_operands (value_range &r, gimple *s,
// NAME_RANGE is any known range for NAME coming into S.
bool
-gori_compute::compute_operand1_range (value_range &r, gimple *s,
- const value_range &lhs, tree name,
- const value_range *name_range)
+gori_compute::compute_operand1_range (irange &r, gimple *s,
+ const irange &lhs, tree name,
+ const irange *name_range)
{
- value_range op1_range, op2_range;
+ widest_irange op1_range, op2_range;
tree op1 = gimple_range_operand1 (s);
tree op2 = gimple_range_operand2 (s);
@@ -1027,11 +1026,11 @@ gori_compute::compute_operand1_range (value_range &r, gimple *s,
// NAME_RANGE is any known range for NAME coming into S.
bool
-gori_compute::compute_operand2_range (value_range &r, gimple *s,
- const value_range &lhs, tree name,
- const value_range *name_range)
+gori_compute::compute_operand2_range (irange &r, gimple *s,
+ const irange &lhs, tree name,
+ const irange *name_range)
{
- value_range op1_range, op2_range;
+ widest_irange op1_range, op2_range;
tree op1 = gimple_range_operand1 (s);
tree op2 = gimple_range_operand2 (s);
@@ -1060,13 +1059,13 @@ gori_compute::compute_operand2_range (value_range &r, gimple *s,
bool
gori_compute::compute_operand1_and_operand2_range
- (value_range &r,
+ (irange &r,
gimple *s,
- const value_range &lhs,
+ const irange &lhs,
tree name,
- const value_range *name_range)
+ const irange *name_range)
{
- value_range op_range;
+ widest_irange op_range;
// Calculate a good a range for op2. Since op1 == op2, this will
// have already included whatever the actual range of name is.
@@ -1096,10 +1095,10 @@ gori_compute::has_edge_range_p (edge e, tree name)
// control edge or NAME is not defined by this edge.
bool
-gori_compute::outgoing_edge_range_p (value_range &r, edge e, tree name,
- const value_range *name_range)
+gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name,
+ const irange *name_range)
{
- value_range lhs;
+ widest_irange lhs;
gcc_checking_assert (gimple_range_ssa_p (name));
// Determine if there is an outgoing edge.
diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h
index 0a7ea164a38..4850647d527 100644
--- a/gcc/gimple-range-gori.h
+++ b/gcc/gimple-range-gori.h
@@ -145,59 +145,59 @@ public:
which has non-virtual destructor might cause undefined
behavior. */
virtual ~gori_compute ();
- bool range_of_expr (value_range &r, tree expr, gimple *s = NULL);
+ bool range_of_expr (irange &r, tree expr, gimple *s = NULL);
virtual bool outgoing_edge_range_p
- (value_range &r, edge e, tree name,
- const value_range *name_range = NULL);
+ (irange &r, edge e, tree name,
+ const irange *name_range = NULL);
protected:
- virtual void range_of_ssa_name (value_range &, tree name,
+ virtual void range_of_ssa_name (irange &, tree name,
gimple *s = NULL);
- bool compute_operand_range (value_range &r, gimple *s,
- const value_range &lhs,
+ bool compute_operand_range (irange &r, gimple *s,
+ const irange &lhs,
tree name,
- const value_range *name_range = NULL);
+ const irange *name_range = NULL);
bool has_edge_range_p (edge e, tree name);
gori_map m_gori_map;
private:
- void get_tree_range (value_range &, tree expr, tree name,
- const value_range *range_of_name);
- bool compute_operand_range_switch (value_range &r, gswitch *s,
- const value_range &lhs,
+ void get_tree_range (irange &, tree expr, tree name,
+ const irange *range_of_name);
+ bool compute_operand_range_switch (irange &r, gswitch *s,
+ const irange &lhs,
tree name,
- const value_range *name_range);
- bool compute_name_range_op (value_range &r, gimple *s,
- const value_range &lhs,
+ const irange *name_range);
+ bool compute_name_range_op (irange &r, gimple *s,
+ const irange &lhs,
tree name,
- const value_range *name_range);
- bool compute_operand_range_op (value_range &r, gimple *stmt,
- const value_range &lhs,
+ const irange *name_range);
+ bool compute_operand_range_op (irange &r, gimple *stmt,
+ const irange &lhs,
tree name,
- const value_range *name_range);
- bool compute_operand1_range (value_range &r, gimple *s,
- const value_range &lhs,
+ const irange *name_range);
+ bool compute_operand1_range (irange &r, gimple *s,
+ const irange &lhs,
tree name,
- const value_range *name_range);
- bool compute_operand2_range (value_range &r, gimple *s,
- const value_range &lhs,
+ const irange *name_range);
+ bool compute_operand2_range (irange &r, gimple *s,
+ const irange &lhs,
tree name,
- const value_range *name_range);
+ const irange *name_range);
bool compute_operand1_and_operand2_range
- (value_range &r, gimple *s,
- const value_range &lhs,
+ (irange &r, gimple *s,
+ const irange &lhs,
tree name,
- const value_range *name_range);
- bool compute_logical_operands (value_range &r, gimple *s,
- const value_range &lhs,
+ const irange *name_range);
+ bool compute_logical_operands (irange &r, gimple *s,
+ const irange &lhs,
tree name,
- const value_range *name_range);
- bool logical_combine (value_range &r, enum tree_code code,
- const value_range &lhs,
- const value_range &op1_true,
- const value_range &op1_false,
- const value_range &op2_true,
- const value_range &op2_false);
- value_range m_bool_zero; /* Boolean zero cached. */
- value_range m_bool_one; /* Boolean true cached. */
+ const irange *name_range);
+ bool logical_combine (irange &r, enum tree_code code,
+ const irange &lhs,
+ const irange &op1_true,
+ const irange &op1_false,
+ const irange &op2_true,
+ const irange &op2_false);
+ int_range<1> m_bool_zero; /* Boolean zero cached. */
+ int_range<1> m_bool_one; /* Boolean true cached. */
};
#endif // GCC_GIMPLE_RANGE_GORI_H
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index ab0ba011d5a..408e46cba38 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -52,13 +52,12 @@ along with GCC; see the file COPYING3. If not see
// builtin function is a boolean result.
static void
-gimple_range_adjustment (const gimple *s, value_range &res)
+gimple_range_adjustment (const gimple *s, irange &res)
{
switch (gimple_expr_code (s))
{
case IMAGPART_EXPR:
{
- value_range r;
tree name;
tree type = TREE_TYPE (gimple_assign_lhs (s));
@@ -75,9 +74,12 @@ gimple_range_adjustment (const gimple *s, value_range &res)
case IFN_SUB_OVERFLOW:
case IFN_MUL_OVERFLOW:
case IFN_ATOMIC_COMPARE_EXCHANGE:
- r.set_varying (boolean_type_node);
- range_cast (r, type);
- res.intersect (r);
+ {
+ int_range<1> r;
+ r.set_varying (boolean_type_node);
+ range_cast (r, type);
+ res.intersect (r);
+ }
default:
break;
}
@@ -99,7 +101,7 @@ gimple_range_adjustment (const gimple *s, value_range &res)
// represent switches in GIMPLE does not map well to this calculation.
static gimple *
-calc_single_range (value_range &r, gswitch *sw, edge e)
+calc_single_range (irange &r, gswitch *sw, edge e)
{
unsigned x, lim;
lim = gimple_switch_num_labels (sw);
@@ -129,7 +131,7 @@ calc_single_range (value_range &r, gswitch *sw, edge e)
tree high = CASE_HIGH (gimple_switch_label (sw, x));
if (!high)
high = low;
- value_range case_range (low, high);
+ int_range<1> case_range (low, high);
r.union_ (case_range);
}
}
@@ -144,7 +146,7 @@ calc_single_range (value_range &r, gswitch *sw, edge e)
tree high = CASE_HIGH (gimple_switch_label (sw, x));
if (!high)
high = low;
- value_range case_range (low, high, VR_ANTI_RANGE);
+ int_range<1> case_range (low, high, VR_ANTI_RANGE);
r.intersect (case_range);
}
}
@@ -183,7 +185,7 @@ gimple_outgoing_range_stmt_p (basic_block bb)
// return NULL
gimple *
-gimple_outgoing_edge_range_p (value_range &r, edge e)
+gimple_outgoing_edge_range_p (irange &r, edge e)
{
// Determine if there is an outgoing edge.
gimple *s = gimple_outgoing_range_stmt_p (e->src);
@@ -193,9 +195,9 @@ gimple_outgoing_edge_range_p (value_range &r, edge e)
if (is_a<gcond *> (s))
{
if (e->flags & EDGE_TRUE_VALUE)
- r = value_range (boolean_true_node, boolean_true_node);
+ r = int_range<1> (boolean_true_node, boolean_true_node);
else if (e->flags & EDGE_FALSE_VALUE)
- r = value_range (boolean_false_node, boolean_false_node);
+ r = int_range<1> (boolean_false_node, boolean_false_node);
else
gcc_unreachable ();
return s;
@@ -205,7 +207,7 @@ gimple_outgoing_edge_range_p (value_range &r, edge e)
gswitch *sw = as_a<gswitch *> (s);
tree type = TREE_TYPE (gimple_switch_index (sw));
- if (!value_range::supports_type_p (type))
+ if (!irange::supports_type_p (type))
return NULL;
return calc_single_range (r, sw, e);
@@ -217,13 +219,12 @@ gimple_outgoing_edge_range_p (value_range &r, edge e)
// the result in RES. Return false if the operation fails.
bool
-gimple_range_fold (const gimple *s, value_range &res,
- const value_range &r1)
+gimple_range_fold (const gimple *s, irange &res, const irange &r1)
{
gcc_checking_assert (gimple_range_handler (s));
tree type = gimple_expr_type (s);;
- value_range r2 (type);
+ int_range<1> r2 (type);
// Single ssa operations require the LHS type as the second range.
return gimple_range_fold (s, res, r1, r2);
@@ -234,13 +235,11 @@ gimple_range_fold (const gimple *s, value_range &res,
// returning the result in RES. Return false if the operation fails.
bool
-gimple_range_fold (const gimple *s, value_range &res,
- const value_range &r1,
- const value_range &r2)
+gimple_range_fold (const gimple *s, irange &res,
+ const irange &r1, const irange &r2)
{
gcc_checking_assert (gimple_range_handler (s));
- value_range adj_range;
gimple_range_handler (s)->fold_range (res, gimple_expr_type (s), r1, r2);
// If there are any gimple lookups, do those now.
@@ -317,10 +316,8 @@ gimple_range_operand2 (const gimple *s)
// LHS_RANGE. Return false if nothing can be determined.
bool
-gimple_range_calc_op1 (const gimple *s, value_range &r,
- const value_range &lhs_range)
+gimple_range_calc_op1 (const gimple *s, irange &r, const irange &lhs_range)
{
- value_range type_range;
gcc_checking_assert (gimple_num_ops (s) < 3);
// An empty range is viral, so return an empty range.
@@ -332,7 +329,7 @@ gimple_range_calc_op1 (const gimple *s, value_range &r,
}
// Unary operations require the type of the first operand in the
// second range position.
- type_range.set_varying (type);
+ int_range<1> type_range (type);
return gimple_range_handler (s)->op1_range (r, type, lhs_range, type_range);
}
@@ -343,9 +340,8 @@ gimple_range_calc_op1 (const gimple *s, value_range &r,
// nothing can be determined.
bool
-gimple_range_calc_op1 (const gimple *s, value_range &r,
- const value_range &lhs_range,
- const value_range &op2_range)
+gimple_range_calc_op1 (const gimple *s, irange &r,
+ const irange &lhs_range, const irange &op2_range)
{
// Unary operation are allowed to pass a range in for second operand
// as there are often additional restrictions beyond the type which
@@ -367,9 +363,8 @@ gimple_range_calc_op1 (const gimple *s, value_range &r,
// nothing can be determined.
bool
-gimple_range_calc_op2 (const gimple *s, value_range &r,
- const value_range &lhs_range,
- const value_range &op1_range)
+gimple_range_calc_op2 (const gimple *s, irange &r,
+ const irange &lhs_range, const irange &op1_range)
{
tree type = TREE_TYPE (gimple_range_operand2 (s));
// An empty range is viral, so return an empty range.
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index b1d312b79fd..60b4482db72 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -32,24 +32,24 @@ extern gimple *gimple_outgoing_range_stmt_p (basic_block bb);
// If edge E has a constant range, return it and the range generating
// statement. for conditonals its TRUE/FALSE, for switches its the
// possible cases.
-extern gimple *gimple_outgoing_edge_range_p (value_range &r, edge e);
+extern gimple *gimple_outgoing_edge_range_p (irange &r, edge e);
// These routines provide a GIMPLE interface to the range-ops code.
extern tree gimple_range_operand1 (const gimple *s);
extern tree gimple_range_operand2 (const gimple *s);
-extern bool gimple_range_fold (const gimple *s, value_range &res,
- const value_range &r1);
-extern bool gimple_range_fold (const gimple *s, value_range &res,
- const value_range &r1,
- const value_range &r2);
-extern bool gimple_range_calc_op1 (const gimple *s, value_range &r,
- const value_range &lhs_range);
-extern bool gimple_range_calc_op1 (const gimple *s, value_range &r,
- const value_range &lhs_range,
- const value_range &op2_range);
-extern bool gimple_range_calc_op2 (const gimple *s, value_range &r,
- const value_range &lhs_range,
- const value_range &op1_range);
+extern bool gimple_range_fold (const gimple *s, irange &res,
+ const irange &r1);
+extern bool gimple_range_fold (const gimple *s, irange &res,
+ const irange &r1,
+ const irange &r2);
+extern bool gimple_range_calc_op1 (const gimple *s, irange &r,
+ const irange &lhs_range);
+extern bool gimple_range_calc_op1 (const gimple *s, irange &r,
+ const irange &lhs_range,
+ const irange &op2_range);
+extern bool gimple_range_calc_op2 (const gimple *s, irange &r,
+ const irange &lhs_range,
+ const irange &op1_range);
// Return the range_operator pointer for this statement. This routine
@@ -70,7 +70,7 @@ gimple_range_ssa_p (tree exp)
{
if (exp && TREE_CODE (exp) == SSA_NAME &&
!SSA_NAME_IS_VIRTUAL_OPERAND (exp) &&
- value_range::supports_type_p (TREE_TYPE (exp)))
+ irange::supports_type_p (TREE_TYPE (exp)))
return exp;
return NULL_TREE;
}
diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
index 80cb0a505e8..06c13ccb5c6 100644
--- a/gcc/gimple-ssa-evrp-analyze.c
+++ b/gcc/gimple-ssa-evrp-analyze.c
@@ -153,8 +153,8 @@ all_uses_feed_or_dominated_by_stmt (tree name, gimple *stmt)
}
static bool
-gori_range_is_same (const value_range *range_evrp,
- const value_range *range_gori)
+gori_range_is_same (const irange *range_evrp,
+ const irange *range_gori)
{
// FIXME: We may be able to normalize a symbolic to a [MIN,MAX] plus
// or minus the end-points. Don't count that as a win just yet.
@@ -164,11 +164,9 @@ gori_range_is_same (const value_range *range_evrp,
return true;
// Treat UNDEFINED and VARYING as interchangeable.
- value_range evrp;
+ widest_irange evrp;
if (range_evrp)
evrp = *range_evrp;
- else
- evrp = value_range ();
if (evrp.undefined_p () && range_gori->varying_p ())
return true;
if (evrp.varying_p () && range_gori->undefined_p ())
@@ -178,8 +176,8 @@ gori_range_is_same (const value_range *range_evrp,
}
static bool
-gori_range_is_better (const value_range *range_evrp,
- const value_range *range_gori)
+gori_range_is_better (const irange *range_evrp,
+ const irange *range_gori)
{
if (gori_range_is_same (range_evrp, range_gori))
return false;
@@ -193,16 +191,16 @@ gori_range_is_better (const value_range *range_evrp,
return true;
}
- value_range inter (*range_gori);
+ widest_irange inter (*range_gori);
inter.intersect (*range_evrp);
return inter == *range_gori;
}
static bool
-gori_range_is_unrepresentable (const value_range *r_evrp,
- const value_range *r_gori)
+gori_range_is_unrepresentable (const irange *r_evrp,
+ const irange *r_gori)
{
- value_range inter (*r_evrp);
+ widest_irange inter (*r_evrp);
inter.intersect (*r_gori);
bool evrp_is_better = inter == *r_evrp;
return gori_range_is_better (r_evrp, r_gori) && evrp_is_better;
@@ -211,10 +209,10 @@ gori_range_is_unrepresentable (const value_range *r_evrp,
value_range_equiv *
evrp_range_analyzer::merge_gori_and_evrp_results
(value_range_equiv *vr,
- const value_range *vr_gori)
+ const irange *vr_gori)
{
if (vr)
- static_cast <value_range *> (vr)->intersect (vr_gori);
+ static_cast <irange *> (vr)->intersect (vr_gori);
else
{
if (vr_gori->varying_p () || vr_gori->undefined_p ())
@@ -227,7 +225,7 @@ evrp_range_analyzer::merge_gori_and_evrp_results
void
evrp_range_analyzer::try_find_new_range_with_gori
- (value_range &res, tree name, edge e,
+ (irange &res, tree name, edge e,
const vec<assert_info> &asserts)
{
const value_range_equiv *known_range = get_value_range (name);
@@ -243,9 +241,11 @@ evrp_range_analyzer::try_find_new_range_with_gori
}
static void
-dump_gori_improvements (tree name,
- const value_range *r_evrp, const value_range *r_gori)
+dump_gori_improvements (tree name, const irange *r_evrp, const irange *r_gori)
{
+ bool details = dump_flags & TDF_DETAILS;
+ if (details)
+ dump_flags &= ~TDF_DETAILS;
if (gori_range_is_better (r_evrp, r_gori))
{
fprintf (dump_file, "GORI improved: ");
@@ -264,7 +264,7 @@ dump_gori_improvements (tree name,
fprintf (dump_file, "UNREPRESENTABLE");
else
{
- value_range r;
+ widest_irange r;
r = *r_evrp;
r.intersect (r_gori);
r.dump (dump_file);
@@ -272,12 +272,14 @@ dump_gori_improvements (tree name,
}
fprintf (dump_file, "\n");
}
+ if (details)
+ dump_flags |= TDF_DETAILS;
}
void
evrp_range_analyzer::debug_gori_ranges (tree name, edge e,
- const value_range *range_evrp,
- const value_range *range_gori,
+ const irange *range_evrp,
+ const irange *range_gori,
const vec<assert_info> &asserts) const
{
fprintf (stderr, "Different ranges on edge (%d -> %d) for SSA: ",
@@ -307,8 +309,8 @@ evrp_range_analyzer::debug_gori_ranges (tree name, edge e,
void
evrp_range_analyzer::assert_gori_is_as_good
(tree name, edge e,
- const value_range *range_evrp,
- const value_range *range_gori,
+ const irange *range_evrp,
+ const irange *range_gori,
const vec<assert_info> &asserts) const
{
if (gori_range_is_same (range_evrp, range_gori)
@@ -355,7 +357,7 @@ evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
auto_vec<std::pair<tree, value_range_equiv *>, 8> vrs;
for (unsigned i = 0; i < asserts.length (); ++i)
{
- value_range vr_gori;
+ widest_irange vr_gori;
try_find_new_range_with_gori (vr_gori, asserts[i].name, pred_e,
asserts);
value_range_equiv *vr
diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h
index 1a701a36d65..dbda6e586a9 100644
--- a/gcc/gimple-ssa-evrp-analyze.h
+++ b/gcc/gimple-ssa-evrp-analyze.h
@@ -70,16 +70,16 @@ class evrp_range_analyzer
void set_ssa_range_info (tree, value_range_equiv *);
/* GORI support. */
- void try_find_new_range_with_gori (value_range &, tree, edge,
+ void try_find_new_range_with_gori (irange &, tree, edge,
const vec<assert_info> &);
void assert_gori_is_as_good (tree, edge,
- const value_range *,
- const value_range *,
+ const irange *,
+ const irange *,
const vec<assert_info> &) const;
value_range_equiv *merge_gori_and_evrp_results (value_range_equiv *,
- const value_range *);
+ const irange *);
void debug_gori_ranges (tree, edge,
- const value_range *, const value_range *,
+ const irange *, const irange *,
const vec<assert_info> &) const;
/* STACK holds the old VR. */
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 679fe44cfe3..ac6854ad83d 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -588,7 +588,7 @@ irange::check ()
gcc_fallthrough ();
case VR_RANGE:
{
- gcc_assert (m_num_ranges > 0);
+ gcc_assert (m_num_ranges > 0 || !simple_ranges_p ());
for (unsigned i = 0; i < m_num_ranges; ++i)
{
@@ -1655,7 +1655,24 @@ irange::union_ (const irange *other)
fprintf (dump_file, "\n");
}
- gcc_checking_assert (other->simple_ranges_p ());
+ /* If a simple range was requested, do the entire operation in
+ simple mode, because we may have received a symbolic, and we only
+ know how to deal with those in simple mode. */
+ if (simple_ranges_p ())
+ {
+ if (other->simple_ranges_p ())
+ *this = union_helper ((value_range *) this,
+ (const value_range *) other);
+ else
+ {
+ int_range<1> small = *other;
+ *this = union_helper ((value_range *) this,
+ (const value_range *) &small);
+ }
+ }
+ else
+ union_ (*other);
+
*this = union_helper ((value_range *) this, (const value_range *) other);
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1671,11 +1688,6 @@ irange::union_ (const irange *other)
void
irange::union_ (const vrange &vr)
{
- /* Disable details for now, because it makes the ranger dump
- unnecessarily verbose. */
- bool details = dump_flags & TDF_DETAILS;
- if (details)
- dump_flags &= ~TDF_DETAILS;
const irange *other = as_a <const irange *> (&vr);
if (simple_ranges_p ())
{
@@ -1694,14 +1706,11 @@ irange::union_ (const vrange &vr)
else
multi_range_union (*other);
}
- if (details)
- dump_flags |= TDF_DETAILS;
}
void
irange::intersect (const irange *other)
{
- gcc_checking_assert (simple_ranges_p () && other->simple_ranges_p ());
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Intersecting\n ");
@@ -1711,8 +1720,23 @@ irange::intersect (const irange *other)
fprintf (dump_file, "\n");
}
- *this = intersect_helper ((value_range *) this,
- (const value_range *) other);
+ /* If a simple range was requested, do the entire operation in
+ simple mode, because we may have received a symbolic, and we only
+ know how to deal with those in simple mode. */
+ if (simple_ranges_p ())
+ {
+ if (other->simple_ranges_p ())
+ *this = intersect_helper ((value_range *) this,
+ (const value_range *) other);
+ else
+ {
+ int_range<1> small = *other;
+ *this = intersect_helper ((value_range *) this,
+ (const value_range *) &small);
+ }
+ }
+ else
+ intersect (*other);
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -1727,11 +1751,6 @@ irange::intersect (const irange *other)
void
irange::intersect (const vrange &vr)
{
- /* Disable details for now, because it makes the ranger dump
- unnecessarily verbose. */
- bool details = dump_flags & TDF_DETAILS;
- if (details)
- dump_flags &= ~TDF_DETAILS;
const irange *other = as_a <const irange *> (&vr);
if (simple_ranges_p ())
{
@@ -1750,8 +1769,6 @@ irange::intersect (const vrange &vr)
else
multi_range_intersect (*other);
}
- if (details)
- dump_flags |= TDF_DETAILS;
}
void
@@ -2101,6 +2118,22 @@ irange::simple_dump (FILE *file) const
gcc_unreachable ();
}
+static void
+dump_bound_with_infinite_markers (FILE *file, tree bound)
+{
+ tree type = TREE_TYPE (bound);
+ if (INTEGRAL_TYPE_P (type)
+ && !TYPE_UNSIGNED (type)
+ && vrp_val_is_min (bound)
+ && TYPE_PRECISION (type) != 1)
+ fprintf (file, "-INF");
+ else if (vrp_val_is_max (bound)
+ && TYPE_PRECISION (type) != 1)
+ fprintf (file, "+INF");
+ else
+ print_generic_expr (file, bound);
+}
+
void
vrange::dump (FILE *file) const
{
@@ -2119,19 +2152,33 @@ vrange::dump (FILE *file) const
fprintf (file, " ");
if (varying_p ())
fprintf (file, "VARYING");
- else
+ else if (m_kind == VR_RANGE)
{
- if (m_kind == VR_ANTI_RANGE)
- fprintf (file, "~");
for (unsigned i = 0; i < m_num_ranges; ++i)
{
+ tree lb = m_base[i * 2];
+ tree ub = m_base[i * 2 + 1];
fprintf (file, "[");
- print_generic_expr (file, m_base[i * 2]);
+ dump_bound_with_infinite_markers (file, lb);
fprintf (file, ", ");
- print_generic_expr (file, m_base[i * 2 + 1]);
+ dump_bound_with_infinite_markers (file, ub);
fprintf (file, "]");
}
}
+ else if (m_kind == VR_ANTI_RANGE)
+ {
+ gcc_checking_assert (m_num_ranges == 1);
+ gcc_checking_assert (!range_has_numeric_bounds_p (ir));
+ tree lb = m_base[0];
+ tree ub = m_base[1];
+ fprintf (file, "~[");
+ dump_bound_with_infinite_markers (file, lb);
+ fprintf (file, ", ");
+ dump_bound_with_infinite_markers (file, ub);
+ fprintf (file, "]");
+ }
+ else
+ gcc_unreachable ();
}
void
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 8bc59ce30a4..4808421a741 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -174,7 +174,7 @@ vr_values::get_value_range (const_tree var)
}
void
-vr_values::range_of_ssa_name (value_range &r, tree op,
+vr_values::range_of_ssa_name (irange &r, tree op,
gimple *stmt ATTRIBUTE_UNUSED)
{
r = *(get_value_range (op));
@@ -2001,8 +2001,8 @@ vr_values::save_equivalences (equivalence_iterator *iter)
// control edge or NAME is not defined by this edge.
bool
-vr_values::outgoing_edge_range_p (value_range &r, edge e, tree name,
- const value_range *name_range)
+vr_values::outgoing_edge_range_p (irange &r, edge e, tree name,
+ const irange *name_range)
{
if (gori_compute::outgoing_edge_range_p (r, e, name, name_range)
&& !r.varying_p ())
@@ -2013,10 +2013,9 @@ vr_values::outgoing_edge_range_p (value_range &r, edge e, tree name,
bool
vr_values::outgoing_edge_range_with_equivalences_p
- (value_range &r,
- edge e, tree name)
+ (irange &r, edge e, tree name)
{
- value_range branch_range;
+ widest_irange branch_range;
gimple *stmt = gimple_outgoing_edge_range_p (branch_range, e);
if (!stmt)
return false;
@@ -2031,7 +2030,7 @@ vr_values::outgoing_edge_range_with_equivalences_p
if (!m_gori_map.is_export_p (equiv, e->src))
continue;
- value_range equiv_range, tmp;
+ widest_irange equiv_range, tmp;
if (solve_equiv_at_statement (equiv_range, equiv, stmt, branch_range)
// Try to solve conditional again with our new knowledge.
&& (solve_equiv_at_statement (tmp, name, stmt, branch_range)
@@ -2057,27 +2056,27 @@ vr_values::outgoing_edge_range_with_equivalences_p
}
bool
-vr_values::solve_equiv_at_statement (value_range &r,
+vr_values::solve_equiv_at_statement (irange &r,
tree name, gimple *stmt,
- const value_range &lhs)
+ const irange &lhs)
{
- value_range known_range_of_name;
+ widest_irange known_range_of_name;
range_of_ssa_name (known_range_of_name, name);
return compute_operand_range (r, stmt, lhs, name, &known_range_of_name);
}
bool
-vr_values::solve_name_given_equivalence (value_range &r,
+vr_values::solve_name_given_equivalence (irange &r,
tree name,
tree equiv,
- const value_range &equiv_range)
+ const irange &equiv_range)
{
// Solve NAME in EQUIV = USE(NAME).
gimple *def = SSA_NAME_DEF_STMT (equiv);
if (gimple_range_handler (def) && gimple_range_operand1 (def) == name)
{
tree op2_type = TREE_TYPE (gimple_range_operand1 (def));
- value_range op2_range;
+ widest_irange op2_range;
range_for_op2 (op2_range, def, op2_type);
return gimple_range_calc_op1 (def, r, equiv_range, op2_range);
}
@@ -2086,7 +2085,7 @@ vr_values::solve_name_given_equivalence (value_range &r,
if (gimple_range_handler (def) && gimple_range_operand1 (def) == equiv)
{
tree op2_type = gimple_expr_type (def);
- value_range op2_range;
+ widest_irange op2_range;
range_for_op2 (op2_range, def, op2_type);
return gimple_range_fold (def, r, equiv_range, op2_range);
}
@@ -2094,7 +2093,7 @@ vr_values::solve_name_given_equivalence (value_range &r,
}
void
-vr_values::range_for_op2 (value_range &res, gimple *stmt, tree type)
+vr_values::range_for_op2 (irange &res, gimple *stmt, tree type)
{
tree op2 = gimple_assign_rhs2 (stmt);
if (op2)
@@ -2103,7 +2102,7 @@ vr_values::range_for_op2 (value_range &res, gimple *stmt, tree type)
range_of_ssa_name (res, op2);
else
{
- res = value_range (op2, op2);
+ res.set (op2, op2);
res.normalize_addresses ();
}
return;
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 54e2ebc07f9..5074c31ca2b 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -91,21 +91,18 @@ class vr_values : public gori_compute
/* */
void cleanup_edges_and_switches (void);
- bool outgoing_edge_range_p (value_range &, edge, tree name,
- const value_range *name_range = NULL);
+ bool outgoing_edge_range_p (irange &, edge, tree name,
+ const irange *name_range = NULL);
void save_equivalences (equivalence_iterator *);
private:
- void range_of_ssa_name (value_range &r, tree op, gimple * = NULL);
+ void range_of_ssa_name (irange &r, tree op, gimple * = NULL);
equivalence_iterator *m_equivalences;
- bool outgoing_edge_range_with_equivalences_p (value_range &,
- edge, tree name);
- bool solve_equiv_at_statement (value_range &,
- tree, gimple *stmt,
- const value_range &);
- bool solve_name_given_equivalence (value_range &r,
- tree name, tree equiv,
- const value_range &equiv_range);
- void range_for_op2 (value_range &, gimple *, tree type);
+ bool outgoing_edge_range_with_equivalences_p (irange &, edge, tree name);
+ bool solve_equiv_at_statement (irange &,
+ tree, gimple *stmt, const irange &);
+ bool solve_name_given_equivalence (irange &r, tree name, tree equiv,
+ const irange &equiv_range);
+ void range_for_op2 (irange &, gimple *, tree type);
value_range_equiv *get_lattice_entry (const_tree);
bool vrp_stmt_computes_nonzero (gimple *);