From b565ac19264a5827162d28537bccc8531c25e817 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Thu, 13 Oct 2022 18:03:58 -0400
Subject: [PATCH 3/4] Add relation_trio class for range-ops.
There are 3 possible relations range-ops might care about, but only the one
most likely to be needed is supplied. This patch provides a new class
relation_trio which allows 3 relations to be passed in a single word.
fold_range (), op1_range (), and op2_range () are adjusted to take a
relation_trio class instead of a relation_kind, then the routine can
extract which relation it wants to work with.
* gimple-range-fold.cc (fold_using_range::range_of_range_op):
Provide relation_trio class.
* gimple-range-gori.cc (gori_compute::refine_using_relation):
Provide relation_trio class.
(gori_compute::refine_using_relation): Ditto.
(gori_compute::compute_operand1_range): Provide lhs_op2 and
op1_op2 relations via relation_trio class.
(gori_compute::compute_operand2_range): Ditto.
* gimple-range-op.cc (gimple_range_op_handler::calc_op1): Use
relation_trio instead of relation_kind.
(gimple_range_op_handler::calc_op2): Ditto.
(*::fold_range): Ditto.
* gimple-range-op.h (gimple_range_op::calc_op1): Adjust prototypes.
(gimple_range_op::calc_op2): Adjust prototypes.
* range-op-float.cc (*::fold_range): Use relation_trio instead of
relation_kind.
(*::op1_range): Ditto.
(*::op2_range): Ditto.
* range-op.cc (*::fold_range): Use relation_trio instead of
relation_kind.
(*::op1_range): Ditto.
(*::op2_range): Ditto.
* range-op.h (class range_operator): Adjust prototypes.
(class range_operator_float): Ditto.
(class range_op_handler): Adjust prototypes.
(relop_early_resolve): Pickup op1_op2 relation from relation_trio.
* value-relation.cc (VREL_LAST): Adjust use to be one past the end of
the enum.
(relation_oracle::validate_relation): Use relation_trio in call
to fold_range.
* value-relation.h (enum relation_kind_t): Add VREL_LAST as
final element.
(class relation_trio): New.
(TRIO_VARYING, TRIO_SHIFT, TRIO_MASK): New.
---
gcc/gimple-range-fold.cc | 5 +-
gcc/gimple-range-gori.cc | 43 ++++---
gcc/gimple-range-op.cc | 40 +++---
gcc/gimple-range-op.h | 4 +-
gcc/range-op-float.cc | 170 +++++++++++++------------
gcc/range-op.cc | 267 ++++++++++++++++++++-------------------
gcc/range-op.h | 29 +++--
gcc/value-relation.cc | 19 ++-
gcc/value-relation.h | 119 +++++++++++++++--
9 files changed, 405 insertions(+), 291 deletions(-)
@@ -578,7 +578,8 @@ fold_using_range::range_of_range_op (vrange &r,
fputc ('\n', dump_file);
}
// Fold range, and register any dependency if available.
- if (!handler.fold_range (r, type, range1, range2, rel))
+ if (!handler.fold_range (r, type, range1, range2,
+ relation_trio::op1_op2 (rel)))
r.set_varying (type);
if (irange::supports_p (type))
relation_fold_and_or (as_a <irange> (r), s, src);
@@ -597,7 +598,7 @@ fold_using_range::range_of_range_op (vrange &r,
}
if (gimple_range_ssa_p (op2))
{
- rel= handler.lhs_op2_relation (r, range1, range2, rel);
+ rel = handler.lhs_op2_relation (r, range1, range2, rel);
if (rel != VREL_VARYING)
src.register_relation (s, rel, lhs, op2);
}
@@ -991,7 +991,7 @@ gori_compute::refine_using_relation (tree op1, vrange &op1_range,
Value_Range new_result (type);
if (!op_handler.op1_range (new_result, type,
op1_def_p ? op1_range : op2_range,
- other_op, k))
+ other_op, relation_trio::lhs_op2 (k)))
return false;
if (op1_def_p)
{
@@ -1023,7 +1023,7 @@ gori_compute::refine_using_relation (tree op1, vrange &op1_range,
Value_Range new_result (type);
if (!op_handler.op2_range (new_result, type,
op1_def_p ? op1_range : op2_range,
- other_op, k))
+ other_op, relation_trio::lhs_op1 (k)))
return false;
if (op1_def_p)
{
@@ -1074,6 +1074,7 @@ gori_compute::compute_operand1_range (vrange &r,
{
src.get_operand (op2_range, op2);
relation_kind k = VREL_VARYING;
+ relation_kind op_op = (op1 == op2) ? VREL_EQ : VREL_VARYING;
if (rel)
{
if (lhs_name == rel->op1 () && op1 == rel->op2 ())
@@ -1081,13 +1082,18 @@ gori_compute::compute_operand1_range (vrange &r,
else if (lhs_name == rel->op2 () && op1 == rel->op1 ())
k = relation_swap (rel->kind ());
else if (op1 == rel->op1 () && op2 == rel->op2 ())
- refine_using_relation (op1, op1_range, op2, op2_range, src,
- rel->kind ());
+ {
+ op_op = rel->kind ();
+ refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
+ }
else if (op1 == rel->op2 () && op2 == rel->op1 ())
- refine_using_relation (op1, op1_range, op2, op2_range, src,
- relation_swap (rel->kind ()));
+ {
+ op_op = relation_swap (rel->kind ());
+ refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
+ }
}
- if (!handler.calc_op1 (tmp, lhs, op2_range, k))
+ if (!handler.calc_op1 (tmp, lhs, op2_range, relation_trio (VREL_VARYING,
+ k, op_op)))
return false;
}
else
@@ -1095,7 +1101,7 @@ gori_compute::compute_operand1_range (vrange &r,
// We pass op1_range to the unary operation. Nomally it's a
// hidden range_for_type parameter, but sometimes having the
// actual range can result in better information.
- if (!handler.calc_op1 (tmp, lhs, op1_range, VREL_VARYING))
+ if (!handler.calc_op1 (tmp, lhs, op1_range, TRIO_VARYING))
return false;
}
@@ -1167,23 +1173,28 @@ gori_compute::compute_operand2_range (vrange &r,
src.get_operand (op1_range, op1);
src.get_operand (op2_range, op2);
relation_kind k = VREL_VARYING;
+ relation_kind op_op = (op1 == op2) ? VREL_EQ : VREL_VARYING;
if (rel)
{
if (lhs_name == rel->op1 () && op2 == rel->op2 ())
- k = rel->kind ();
+ k = rel->kind ();
else if (lhs_name == rel->op2 () && op2 == rel->op1 ())
- k = relation_swap (rel->kind ());
+ k = relation_swap (rel->kind ());
else if (op1 == rel->op1 () && op2 == rel->op2 ())
- refine_using_relation (op1, op1_range, op2, op2_range, src,
- rel->kind ());
+ {
+ op_op = rel->kind ();
+ refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
+ }
else if (op1 == rel->op2 () && op2 == rel->op1 ())
- refine_using_relation (op1, op1_range, op2, op2_range, src,
- relation_swap (rel->kind ()));
+ {
+ op_op = relation_swap (rel->kind ());
+ refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
+ }
}
-
// Intersect with range for op2 based on lhs and op1.
- if (!handler.calc_op2 (tmp, lhs, op1_range, k))
+ if (!handler.calc_op2 (tmp, lhs, op1_range, relation_trio (k, VREL_VARYING,
+ op_op)))
return false;
unsigned idx;
@@ -202,7 +202,7 @@ gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range)
bool
gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range,
- const vrange &op2_range, relation_kind k)
+ const vrange &op2_range, relation_trio k)
{
// Give up on empty ranges.
if (lhs_range.undefined_p ())
@@ -237,7 +237,7 @@ gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range,
bool
gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range,
- const vrange &op1_range, relation_kind k)
+ const vrange &op1_range, relation_trio k)
{
// Give up on empty ranges.
if (lhs_range.undefined_p ())
@@ -263,7 +263,7 @@ class cfn_constant_float_p : public range_operator_float
public:
using range_operator_float::fold_range;
virtual bool fold_range (irange &r, tree type, const frange &lh,
- const irange &, relation_kind) const
+ const irange &, relation_trio) const
{
if (lh.singleton_p ())
{
@@ -285,7 +285,7 @@ class cfn_constant_p : public range_operator
public:
using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const irange &lh,
- const irange &, relation_kind) const
+ const irange &, relation_trio) const
{
if (lh.singleton_p ())
{
@@ -308,7 +308,7 @@ public:
using range_operator_float::fold_range;
using range_operator_float::op1_range;
virtual bool fold_range (irange &r, tree type, const frange &lh,
- const irange &, relation_kind) const override
+ const irange &, relation_trio) const override
{
bool signbit;
if (lh.signbit_p (signbit))
@@ -322,7 +322,7 @@ public:
return false;
}
virtual bool op1_range (frange &r, tree type, const irange &lhs,
- const frange &, relation_kind) const override
+ const frange &, relation_trio) const override
{
if (lhs.zero_p ())
{
@@ -348,7 +348,7 @@ class cfn_copysign : public range_operator_float
public:
using range_operator_float::fold_range;
virtual bool fold_range (frange &r, tree type, const frange &lh,
- const frange &rh, relation_kind) const override
+ const frange &rh, relation_trio) const override
{
frange neg;
range_op_handler abs_op (ABS_EXPR, type);
@@ -381,7 +381,7 @@ public:
using range_operator::fold_range;
cfn_toupper_tolower (bool toupper) { m_toupper = toupper; }
virtual bool fold_range (irange &r, tree type, const irange &lh,
- const irange &, relation_kind) const;
+ const irange &, relation_trio) const;
private:
bool get_letter_range (tree type, irange &lowers, irange &uppers) const;
bool m_toupper;
@@ -412,7 +412,7 @@ cfn_toupper_tolower::get_letter_range (tree type, irange &lowers,
bool
cfn_toupper_tolower::fold_range (irange &r, tree type, const irange &lh,
- const irange &, relation_kind) const
+ const irange &, relation_trio) const
{
int_range<3> lowers;
int_range<3> uppers;
@@ -445,7 +445,7 @@ class cfn_ffs : public range_operator
public:
using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const irange &lh,
- const irange &, relation_kind) const
+ const irange &, relation_trio) const
{
if (lh.undefined_p ())
return false;
@@ -472,7 +472,7 @@ class cfn_popcount : public cfn_ffs
public:
using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const irange &lh,
- const irange &rh, relation_kind rel) const
+ const irange &rh, relation_trio rel) const
{
if (lh.undefined_p ())
return false;
@@ -502,14 +502,14 @@ public:
cfn_clz (bool internal) { m_gimple_call_internal_p = internal; }
using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const irange &lh,
- const irange &, relation_kind) const;
+ const irange &, relation_trio) const;
private:
bool m_gimple_call_internal_p;
} op_cfn_clz (false), op_cfn_clz_internal (true);
bool
cfn_clz::fold_range (irange &r, tree type, const irange &lh,
- const irange &, relation_kind) const
+ const irange &, relation_trio) const
{
// __builtin_c[lt]z* return [0, prec-1], except when the
// argument is 0, but that is undefined behavior.
@@ -577,14 +577,14 @@ public:
cfn_ctz (bool internal) { m_gimple_call_internal_p = internal; }
using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const irange &lh,
- const irange &, relation_kind) const;
+ const irange &, relation_trio) const;
private:
bool m_gimple_call_internal_p;
} op_cfn_ctz (false), op_cfn_ctz_internal (true);
bool
cfn_ctz::fold_range (irange &r, tree type, const irange &lh,
- const irange &, relation_kind) const
+ const irange &, relation_trio) const
{
if (lh.undefined_p ())
return false;
@@ -647,7 +647,7 @@ class cfn_clrsb : public range_operator
public:
using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const irange &lh,
- const irange &, relation_kind) const
+ const irange &, relation_trio) const
{
if (lh.undefined_p ())
return false;
@@ -665,7 +665,7 @@ public:
cfn_ubsan (enum tree_code code) { m_code = code; }
using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const irange &lh,
- const irange &rh, relation_kind rel) const
+ const irange &rh, relation_trio rel) const
{
range_op_handler handler (m_code, type);
gcc_checking_assert (handler);
@@ -699,7 +699,7 @@ class cfn_strlen : public range_operator
public:
using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const irange &,
- const irange &, relation_kind) const
+ const irange &, relation_trio) const
{
tree max = vrp_val_max (ptrdiff_type_node);
wide_int wmax
@@ -724,7 +724,7 @@ public:
cfn_goacc_dim (bool is_pos) { m_is_pos = is_pos; }
using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const irange &lh,
- const irange &, relation_kind) const
+ const irange &, relation_trio) const
{
tree axis_tree;
if (!lh.singleton_p (&axis_tree))
@@ -751,7 +751,7 @@ class cfn_parity : public range_operator
public:
using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const irange &,
- const irange &, relation_kind) const
+ const irange &, relation_trio) const
{
r.set (build_zero_cst (type), build_one_cst (type));
return true;
@@ -36,9 +36,9 @@ public:
tree operand2 () const { gcc_checking_assert (m_valid); return m_op2; }
bool calc_op1 (vrange &r, const vrange &lhs_range);
bool calc_op1 (vrange &r, const vrange &lhs_range, const vrange &op2_range,
- relation_kind k = VREL_VARYING);
+ relation_trio = TRIO_VARYING);
bool calc_op2 (vrange &r, const vrange &lhs_range, const vrange &op1_range,
- relation_kind k = VREL_VARYING);
+ relation_trio = TRIO_VARYING);
private:
void maybe_builtin_call ();
gimple *m_stmt;
@@ -53,7 +53,7 @@ range_operator_float::fold_range (frange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const frange &lh ATTRIBUTE_UNUSED,
const frange &rh ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return false;
}
@@ -63,7 +63,7 @@ range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const frange &lh ATTRIBUTE_UNUSED,
const irange &rh ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return false;
}
@@ -73,7 +73,7 @@ range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const frange &lh ATTRIBUTE_UNUSED,
const frange &rh ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return false;
}
@@ -83,7 +83,7 @@ range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const frange &lhs ATTRIBUTE_UNUSED,
const frange &op2 ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return false;
}
@@ -93,7 +93,7 @@ range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const irange &lhs ATTRIBUTE_UNUSED,
const frange &op2 ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return false;
}
@@ -103,7 +103,7 @@ range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const frange &lhs ATTRIBUTE_UNUSED,
const frange &op1 ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return false;
}
@@ -113,7 +113,7 @@ range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const irange &lhs ATTRIBUTE_UNUSED,
const frange &op1 ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return false;
}
@@ -188,7 +188,7 @@ finite_operands_p (const frange &op1, const frange &op2)
inline bool
frelop_early_resolve (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel, relation_kind my_rel)
+ relation_trio rel, relation_kind my_rel)
{
// If either operand is undefined, return VARYING.
if (empty_range_varying (r, type, op1, op2))
@@ -324,14 +324,14 @@ class foperator_identity : public range_operator_float
public:
bool fold_range (frange &r, tree type ATTRIBUTE_UNUSED,
const frange &op1, const frange &op2 ATTRIBUTE_UNUSED,
- relation_kind = VREL_VARYING) const final override
+ relation_trio = TRIO_VARYING) const final override
{
r = op1;
return true;
}
bool op1_range (frange &r, tree type ATTRIBUTE_UNUSED,
const frange &lhs, const frange &op2 ATTRIBUTE_UNUSED,
- relation_kind = VREL_VARYING) const final override
+ relation_trio = TRIO_VARYING) const final override
{
r = lhs;
return true;
@@ -348,26 +348,26 @@ class foperator_equal : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
relation_kind op1_op2_relation (const irange &lhs) const final override
{
return equal_op1_op2_relation (lhs);
}
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind rel = VREL_VARYING) const final override
+ relation_trio rel = TRIO_VARYING) const final override
{
- return op1_range (r, type, lhs, op1, rel);
+ return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
}
} fop_equal;
bool
foperator_equal::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
return true;
@@ -403,8 +403,9 @@ bool
foperator_equal::op1_range (frange &r, tree type,
const irange &lhs,
const frange &op2,
- relation_kind rel) const
+ relation_trio trio) const
{
+ relation_kind rel = trio.op1_op2 ();
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
@@ -455,20 +456,20 @@ class foperator_not_equal : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel = VREL_VARYING) const final override;
+ relation_trio rel = TRIO_VARYING) const final override;
relation_kind op1_op2_relation (const irange &lhs) const final override
{
return not_equal_op1_op2_relation (lhs);
}
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
} fop_not_equal;
bool
foperator_not_equal::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_NE))
return true;
@@ -505,8 +506,9 @@ bool
foperator_not_equal::op1_range (frange &r, tree type,
const irange &lhs,
const frange &op2,
- relation_kind rel) const
+ relation_trio trio) const
{
+ relation_kind rel = trio.op1_op2 ();
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
@@ -557,23 +559,23 @@ class foperator_lt : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
relation_kind op1_op2_relation (const irange &lhs) const final override
{
return lt_op1_op2_relation (lhs);
}
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
} fop_lt;
bool
foperator_lt::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LT))
return true;
@@ -599,7 +601,7 @@ foperator_lt::op1_range (frange &r,
tree type,
const irange &lhs,
const frange &op2,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -634,7 +636,7 @@ foperator_lt::op2_range (frange &r,
tree type,
const irange &lhs,
const frange &op1,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -673,23 +675,23 @@ class foperator_le : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel = VREL_VARYING) const final override;
+ relation_trio rel = TRIO_VARYING) const final override;
relation_kind op1_op2_relation (const irange &lhs) const final override
{
return le_op1_op2_relation (lhs);
}
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind rel = VREL_VARYING) const final override;
+ relation_trio rel = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind rel = VREL_VARYING) const final override;
+ relation_trio rel = TRIO_VARYING) const final override;
} fop_le;
bool
foperator_le::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LE))
return true;
@@ -715,7 +717,7 @@ foperator_le::op1_range (frange &r,
tree type,
const irange &lhs,
const frange &op2,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -746,7 +748,7 @@ foperator_le::op2_range (frange &r,
tree type,
const irange &lhs,
const frange &op1,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -781,23 +783,23 @@ class foperator_gt : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
relation_kind op1_op2_relation (const irange &lhs) const final override
{
return gt_op1_op2_relation (lhs);
}
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
} fop_gt;
bool
foperator_gt::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GT))
return true;
@@ -823,7 +825,7 @@ foperator_gt::op1_range (frange &r,
tree type,
const irange &lhs,
const frange &op2,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -858,7 +860,7 @@ foperator_gt::op2_range (frange &r,
tree type,
const irange &lhs,
const frange &op1,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -897,23 +899,23 @@ class foperator_ge : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
relation_kind op1_op2_relation (const irange &lhs) const final override
{
return ge_op1_op2_relation (lhs);
}
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
} fop_ge;
bool
foperator_ge::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GE))
return true;
@@ -939,7 +941,7 @@ foperator_ge::op1_range (frange &r,
tree type,
const irange &lhs,
const frange &op2,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -969,7 +971,7 @@ bool
foperator_ge::op2_range (frange &r, tree type,
const irange &lhs,
const frange &op1,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1008,22 +1010,22 @@ class foperator_unordered : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind rel = VREL_VARYING) const final override
+ relation_trio rel = TRIO_VARYING) const final override
{
- return op1_range (r, type, lhs, op1, rel);
+ return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
}
} fop_unordered;
bool
foperator_unordered::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind) const
+ relation_trio) const
{
// UNORDERED is TRUE if either operand is a NAN.
if (op1.known_isnan () || op2.known_isnan ())
@@ -1040,8 +1042,9 @@ bool
foperator_unordered::op1_range (frange &r, tree type,
const irange &lhs,
const frange &op2,
- relation_kind rel) const
+ relation_trio trio) const
{
+ relation_kind rel = trio.op1_op2 ();
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
@@ -1081,22 +1084,22 @@ class foperator_ordered : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind rel = VREL_VARYING) const final override
+ relation_trio rel = TRIO_VARYING) const final override
{
- return op1_range (r, type, lhs, op1, rel);
+ return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
}
} fop_ordered;
bool
foperator_ordered::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind) const
+ relation_trio) const
{
if (op1.known_isnan () || op2.known_isnan ())
r = range_false (type);
@@ -1111,8 +1114,9 @@ bool
foperator_ordered::op1_range (frange &r, tree type,
const irange &lhs,
const frange &op2,
- relation_kind rel) const
+ relation_trio trio) const
{
+ relation_kind rel = trio.op1_op2 ();
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
@@ -1148,7 +1152,7 @@ class foperator_negate : public range_operator_float
public:
bool fold_range (frange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind = VREL_VARYING) const final override
+ relation_trio = TRIO_VARYING) const final override
{
if (empty_range_varying (r, type, op1, op2))
return true;
@@ -1181,7 +1185,7 @@ public:
}
bool op1_range (frange &r, tree type,
const frange &lhs, const frange &op2,
- relation_kind rel = VREL_VARYING) const final override
+ relation_trio rel = TRIO_VARYING) const final override
{
return fold_range (r, type, lhs, op2, rel);
}
@@ -1194,16 +1198,16 @@ class foperator_abs : public range_operator_float
public:
bool fold_range (frange &r, tree type,
const frange &op1, const frange &,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op1_range (frange &r, tree type,
const frange &lhs, const frange &op2,
- relation_kind rel = VREL_VARYING) const final override;
+ relation_trio rel = TRIO_VARYING) const final override;
} fop_abs;
bool
foperator_abs::fold_range (frange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind) const
+ relation_trio) const
{
if (empty_range_varying (r, type, op1, op2))
return true;
@@ -1253,7 +1257,7 @@ foperator_abs::fold_range (frange &r, tree type,
bool
foperator_abs::op1_range (frange &r, tree type,
const frange &lhs, const frange &op2,
- relation_kind) const
+ relation_trio) const
{
if (empty_range_varying (r, type, lhs, op2))
return true;
@@ -1282,7 +1286,7 @@ class foperator_unordered_lt : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel = VREL_VARYING) const final override
+ relation_trio rel = TRIO_VARYING) const final override
{
if (op1.known_isnan () || op2.known_isnan ())
{
@@ -1311,7 +1315,7 @@ class foperator_unordered_le : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel = VREL_VARYING) const final override
+ relation_trio rel = TRIO_VARYING) const final override
{
if (op1.known_isnan () || op2.known_isnan ())
{
@@ -1332,16 +1336,16 @@ public:
}
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
} fop_unordered_le;
bool
foperator_unordered_le::op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1365,7 +1369,7 @@ foperator_unordered_le::op2_range (frange &r,
tree type,
const irange &lhs,
const frange &op1,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1392,7 +1396,7 @@ class foperator_unordered_gt : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel = VREL_VARYING) const final override
+ relation_trio rel = TRIO_VARYING) const final override
{
if (op1.known_isnan () || op2.known_isnan ())
{
@@ -1413,10 +1417,10 @@ public:
}
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
} fop_unordered_gt;
bool
@@ -1424,7 +1428,7 @@ foperator_unordered_gt::op1_range (frange &r,
tree type,
const irange &lhs,
const frange &op2,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1448,7 +1452,7 @@ foperator_unordered_gt::op2_range (frange &r,
tree type,
const irange &lhs,
const frange &op1,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1475,7 +1479,7 @@ class foperator_unordered_ge : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel = VREL_VARYING) const final override
+ relation_trio rel = TRIO_VARYING) const final override
{
if (op1.known_isnan () || op2.known_isnan ())
{
@@ -1496,10 +1500,10 @@ public:
}
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
} fop_unordered_ge;
bool
@@ -1507,7 +1511,7 @@ foperator_unordered_ge::op1_range (frange &r,
tree type,
const irange &lhs,
const frange &op2,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1530,7 +1534,7 @@ bool
foperator_unordered_ge::op2_range (frange &r, tree type,
const irange &lhs,
const frange &op1,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1557,7 +1561,7 @@ class foperator_unordered_equal : public range_operator_float
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
- relation_kind rel = VREL_VARYING) const final override
+ relation_trio rel = TRIO_VARYING) const final override
{
if (op1.known_isnan () || op2.known_isnan ())
{
@@ -1578,12 +1582,12 @@ public:
}
bool op1_range (frange &r, tree type,
const irange &lhs, const frange &op2,
- relation_kind = VREL_VARYING) const final override;
+ relation_trio = TRIO_VARYING) const final override;
bool op2_range (frange &r, tree type,
const irange &lhs, const frange &op1,
- relation_kind rel = VREL_VARYING) const final override
+ relation_trio rel = TRIO_VARYING) const final override
{
- return op1_range (r, type, lhs, op1, rel);
+ return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
}
} fop_unordered_equal;
@@ -1591,7 +1595,7 @@ bool
foperator_unordered_equal::op1_range (frange &r, tree type,
const irange &lhs,
const frange &op2,
- relation_kind) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -179,12 +179,13 @@ bool
range_operator::fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel) const
+ relation_trio trio) const
{
gcc_checking_assert (r.supports_type_p (type));
if (empty_range_varying (r, type, lh, rh))
return true;
+ relation_kind rel = trio.op1_op2 ();
unsigned num_lh = lh.num_pairs ();
unsigned num_rh = rh.num_pairs ();
@@ -227,7 +228,7 @@ range_operator::op1_range (irange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const irange &lhs ATTRIBUTE_UNUSED,
const irange &op2 ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return false;
}
@@ -239,7 +240,7 @@ range_operator::op2_range (irange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const irange &lhs ATTRIBUTE_UNUSED,
const irange &op1 ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return false;
}
@@ -453,15 +454,15 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &val,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &val,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual relation_kind op1_op2_relation (const irange &lhs) const;
} op_equal;
@@ -494,7 +495,7 @@ bool
operator_equal::fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (relop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
return true;
@@ -527,7 +528,7 @@ bool
operator_equal::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -558,9 +559,9 @@ bool
operator_equal::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel) const
+ relation_trio rel) const
{
- return operator_equal::op1_range (r, type, lhs, op1, rel);
+ return operator_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
}
class operator_not_equal : public range_operator
@@ -572,15 +573,15 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual relation_kind op1_op2_relation (const irange &lhs) const;
} op_not_equal;
@@ -612,7 +613,7 @@ bool
operator_not_equal::fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (relop_early_resolve (r, type, op1, op2, rel, VREL_NE))
return true;
@@ -645,7 +646,7 @@ bool
operator_not_equal::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -677,9 +678,9 @@ bool
operator_not_equal::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel) const
+ relation_trio rel) const
{
- return operator_not_equal::op1_range (r, type, lhs, op1, rel);
+ return operator_not_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
}
// (X < VAL) produces the range of [MIN, VAL - 1].
@@ -751,15 +752,15 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual relation_kind op1_op2_relation (const irange &lhs) const;
} op_lt;
@@ -791,7 +792,7 @@ bool
operator_lt::fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (relop_early_resolve (r, type, op1, op2, rel, VREL_LT))
return true;
@@ -815,7 +816,7 @@ bool
operator_lt::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -837,7 +838,7 @@ bool
operator_lt::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -865,15 +866,15 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual relation_kind op1_op2_relation (const irange &lhs) const;
} op_le;
@@ -905,7 +906,7 @@ bool
operator_le::fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (relop_early_resolve (r, type, op1, op2, rel, VREL_LE))
return true;
@@ -926,7 +927,7 @@ bool
operator_le::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -948,7 +949,7 @@ bool
operator_le::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -976,15 +977,15 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual relation_kind op1_op2_relation (const irange &lhs) const;
} op_gt;
@@ -1016,7 +1017,7 @@ operator_gt::op1_op2_relation (const irange &lhs) const
bool
operator_gt::fold_range (irange &r, tree type,
const irange &op1, const irange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (relop_early_resolve (r, type, op1, op2, rel, VREL_GT))
return true;
@@ -1036,7 +1037,7 @@ operator_gt::fold_range (irange &r, tree type,
bool
operator_gt::op1_range (irange &r, tree type,
const irange &lhs, const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1058,7 +1059,7 @@ bool
operator_gt::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1086,15 +1087,15 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual relation_kind op1_op2_relation (const irange &lhs) const;
} op_ge;
@@ -1126,7 +1127,7 @@ bool
operator_ge::fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
if (relop_early_resolve (r, type, op1, op2, rel, VREL_GE))
return true;
@@ -1147,7 +1148,7 @@ bool
operator_ge::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1169,7 +1170,7 @@ bool
operator_ge::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -1198,11 +1199,11 @@ public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const;
+ relation_trio) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const;
+ relation_trio) const;
virtual void wi_fold (irange &r, tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
@@ -1402,7 +1403,7 @@ bool
operator_plus::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel) const
+ relation_trio trio) const
{
if (lhs.undefined_p ())
return false;
@@ -1411,6 +1412,7 @@ operator_plus::op1_range (irange &r, tree type,
if (!minus)
return false;
bool res = minus.fold_range (r, type, lhs, op2);
+ relation_kind rel = trio.lhs_op2 ();
// Check for a relation refinement.
if (res)
adjust_op1_for_overflow (r, op2, rel, true /* PLUS_EXPR */);
@@ -1421,9 +1423,9 @@ bool
operator_plus::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel) const
+ relation_trio rel) const
{
- return op1_range (r, type, lhs, op1, rel);
+ return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
}
@@ -1436,11 +1438,11 @@ public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const;
+ relation_trio) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const;
+ relation_trio) const;
virtual void wi_fold (irange &r, tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
@@ -1573,7 +1575,7 @@ bool
operator_minus::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio trio) const
{
if (lhs.undefined_p ())
return false;
@@ -1582,6 +1584,7 @@ operator_minus::op1_range (irange &r, tree type,
if (!minus)
return false;
bool res = minus.fold_range (r, type, lhs, op2);
+ relation_kind rel = trio.lhs_op2 ();
if (res)
adjust_op1_for_overflow (r, op2, rel, false /* PLUS_EXPR */);
return res;
@@ -1592,7 +1595,7 @@ bool
operator_minus::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p ())
return false;
@@ -1752,17 +1755,17 @@ public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const;
+ relation_trio) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const;
+ relation_trio) const;
} op_mult;
bool
operator_mult::op1_range (irange &r, tree type,
const irange &lhs, const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
tree offset;
if (lhs.undefined_p ())
@@ -1783,9 +1786,9 @@ operator_mult::op1_range (irange &r, tree type,
bool
operator_mult::op2_range (irange &r, tree type,
const irange &lhs, const irange &op1,
- relation_kind rel) const
+ relation_trio rel) const
{
- return operator_mult::op1_range (r, type, lhs, op1, rel);
+ return operator_mult::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
}
bool
@@ -2009,7 +2012,7 @@ public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const;
+ relation_trio) const;
} op_exact_div;
@@ -2017,7 +2020,7 @@ bool
operator_exact_divide::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p ())
return false;
@@ -2043,11 +2046,11 @@ public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual void wi_fold (irange &r, tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
@@ -2067,7 +2070,7 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual void wi_fold (irange &r, tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
@@ -2080,7 +2083,7 @@ public:
virtual bool op1_range (irange &, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual relation_kind lhs_op1_relation (const irange &lhs,
const irange &op1,
const irange &op2,
@@ -2106,7 +2109,7 @@ bool
operator_lshift::fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
int_range_max shift_range;
if (!get_shift_range (shift_range, type, op2))
@@ -2228,7 +2231,7 @@ operator_lshift::op1_range (irange &r,
tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p ())
return false;
@@ -2301,7 +2304,7 @@ operator_rshift::op1_range (irange &r,
tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
tree shift;
if (lhs.undefined_p ())
@@ -2380,7 +2383,7 @@ bool
operator_rshift::fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
int_range_max shift;
if (!get_shift_range (shift, type, op2))
@@ -2412,11 +2415,11 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual relation_kind lhs_op1_relation (const irange &lhs,
const irange &op1,
const irange &op2,
@@ -2528,7 +2531,7 @@ bool
operator_cast::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
const irange &inner,
const irange &outer,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (empty_range_varying (r, type, inner, outer))
return true;
@@ -2567,7 +2570,7 @@ bool
operator_cast::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p ())
return false;
@@ -2682,15 +2685,15 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
} op_logical_and;
@@ -2698,7 +2701,7 @@ bool
operator_logical_and::fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (empty_range_varying (r, type, lh, rh))
return true;
@@ -2721,7 +2724,7 @@ bool
operator_logical_and::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2 ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -2743,7 +2746,7 @@ bool
operator_logical_and::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return operator_logical_and::op1_range (r, type, lhs, op1);
}
@@ -2758,15 +2761,15 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual void wi_fold (irange &r, tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
@@ -2786,7 +2789,7 @@ bool
operator_bitwise_and::fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (range_operator::fold_range (r, type, lh, rh))
{
@@ -3136,7 +3139,7 @@ bool
operator_bitwise_and::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p ())
return false;
@@ -3171,7 +3174,7 @@ bool
operator_bitwise_and::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return operator_bitwise_and::op1_range (r, type, lhs, op1);
}
@@ -3186,22 +3189,22 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
} op_logical_or;
bool
operator_logical_or::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
const irange &lh,
const irange &rh,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (empty_range_varying (r, type, lh, rh))
return true;
@@ -3215,7 +3218,7 @@ bool
operator_logical_or::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2 ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
switch (get_bool_state (r, lhs, type))
{
@@ -3237,7 +3240,7 @@ bool
operator_logical_or::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return operator_logical_or::op1_range (r, type, lhs, op1);
}
@@ -3251,11 +3254,11 @@ public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel= VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual void wi_fold (irange &r, tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
@@ -3323,7 +3326,7 @@ bool
operator_bitwise_or::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p ())
return false;
@@ -3345,7 +3348,7 @@ bool
operator_bitwise_or::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return operator_bitwise_or::op1_range (r, type, lhs, op1);
}
@@ -3364,11 +3367,11 @@ public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op1_op2_relation_effect (irange &lhs_range,
tree type,
const irange &op1_range,
@@ -3454,7 +3457,7 @@ bool
operator_bitwise_xor::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p () || lhs.varying_p ())
{
@@ -3489,7 +3492,7 @@ bool
operator_bitwise_xor::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return operator_bitwise_xor::op1_range (r, type, lhs, op1);
}
@@ -3507,11 +3510,11 @@ public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const;
+ relation_trio) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const;
+ relation_trio) const;
} op_trunc_mod;
void
@@ -3574,7 +3577,7 @@ bool
operator_trunc_mod::op1_range (irange &r, tree type,
const irange &lhs,
const irange &,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p ())
return false;
@@ -3600,7 +3603,7 @@ bool
operator_trunc_mod::op2_range (irange &r, tree type,
const irange &lhs,
const irange &,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p ())
return false;
@@ -3644,11 +3647,11 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
} op_logical_not;
// Folding a logical NOT, oddly enough, involves doing nothing on the
@@ -3669,7 +3672,7 @@ bool
operator_logical_not::fold_range (irange &r, tree type,
const irange &lh,
const irange &rh ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (empty_range_varying (r, type, lh, rh))
return true;
@@ -3686,7 +3689,7 @@ operator_logical_not::op1_range (irange &r,
tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
// Logical NOT is involutary...do it again.
return fold_range (r, type, lhs, op2);
@@ -3701,18 +3704,18 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
} op_bitwise_not;
bool
operator_bitwise_not::fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (empty_range_varying (r, type, lh, rh))
return true;
@@ -3730,7 +3733,7 @@ bool
operator_bitwise_not::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p ())
return false;
@@ -3749,14 +3752,14 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
} op_integer_cst;
bool
operator_cst::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
const irange &lh,
const irange &rh ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
r = lh;
return true;
@@ -3772,11 +3775,11 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual relation_kind lhs_op1_relation (const irange &lhs,
const irange &op1,
const irange &op2,
@@ -3801,7 +3804,7 @@ bool
operator_identity::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
const irange &lh,
const irange &rh ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
r = lh;
return true;
@@ -3811,7 +3814,7 @@ bool
operator_identity::op1_range (irange &r, tree type ATTRIBUTE_UNUSED,
const irange &lhs,
const irange &op2 ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
r = lhs;
return true;
@@ -3825,14 +3828,14 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
} op_unknown;
bool
operator_unknown::fold_range (irange &r, tree type,
const irange &lh ATTRIBUTE_UNUSED,
const irange &rh ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
r.set_varying (type);
return true;
@@ -3851,7 +3854,7 @@ class operator_abs : public range_operator
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const;
+ relation_trio) const;
} op_abs;
void
@@ -3932,7 +3935,7 @@ bool
operator_abs::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (empty_range_varying (r, type, lhs, op2))
return true;
@@ -4013,18 +4016,18 @@ class operator_negate : public range_operator
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
} op_negate;
bool
operator_negate::fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (empty_range_varying (r, type, lh, rh))
return true;
@@ -4037,7 +4040,7 @@ bool
operator_negate::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
// NEGATE is involutory.
return fold_range (r, type, lhs, op2);
@@ -4052,18 +4055,18 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
} op_addr;
bool
operator_addr_expr::fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (empty_range_varying (r, type, lh, rh))
return true;
@@ -4082,7 +4085,7 @@ bool
operator_addr_expr::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return operator_addr_expr::fold_range (r, type, lhs, op2);
}
@@ -4204,11 +4207,11 @@ public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio rel = TRIO_VARYING) const;
virtual void wi_fold (irange &r, tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const;
@@ -4218,7 +4221,7 @@ bool
pointer_or_operator::op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2 ATTRIBUTE_UNUSED,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
if (lhs.undefined_p ())
return false;
@@ -4236,7 +4239,7 @@ bool
pointer_or_operator::op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel ATTRIBUTE_UNUSED) const
+ relation_trio) const
{
return pointer_or_operator::op1_range (r, type, lhs, op1);
}
@@ -4422,7 +4425,7 @@ bool
range_op_handler::fold_range (vrange &r, tree type,
const vrange &lh,
const vrange &rh,
- relation_kind rel) const
+ relation_trio rel) const
{
gcc_checking_assert (m_valid);
if (m_int)
@@ -4450,7 +4453,7 @@ bool
range_op_handler::op1_range (vrange &r, tree type,
const vrange &lhs,
const vrange &op2,
- relation_kind rel) const
+ relation_trio rel) const
{
gcc_checking_assert (m_valid);
@@ -4474,7 +4477,7 @@ bool
range_op_handler::op2_range (vrange &r, tree type,
const vrange &lhs,
const vrange &op1,
- relation_kind rel) const
+ relation_trio rel) const
{
gcc_checking_assert (m_valid);
if (lhs.undefined_p ())
@@ -53,7 +53,7 @@ public:
virtual bool fold_range (irange &r, tree type,
const irange &lh,
const irange &rh,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
// Return the range for op[12] in the general case. LHS is the range for
// the LHS of the expression, OP[12]is the range for the other
@@ -69,11 +69,11 @@ public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
// The following routines are used to represent relations between the
// various operations. If the caller knows where the symbolics are,
@@ -116,32 +116,32 @@ public:
virtual bool fold_range (frange &r, tree type,
const frange &lh,
const frange &rh,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
// Unary operations have the range of the LHS as op2.
virtual bool fold_range (irange &r, tree type,
const frange &lh,
const irange &rh,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool fold_range (irange &r, tree type,
const frange &lh,
const frange &rh,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op1_range (frange &r, tree type,
const frange &lhs,
const frange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op1_range (frange &r, tree type,
const irange &lhs,
const frange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op2_range (frange &r, tree type,
const frange &lhs,
const frange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual bool op2_range (frange &r, tree type,
const irange &lhs,
const frange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
virtual relation_kind lhs_op1_relation (const frange &lhs,
const frange &op1,
@@ -173,15 +173,15 @@ public:
bool fold_range (vrange &r, tree type,
const vrange &lh,
const vrange &rh,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
bool op1_range (vrange &r, tree type,
const vrange &lhs,
const vrange &op2,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
bool op2_range (vrange &r, tree type,
const vrange &lhs,
const vrange &op1,
- relation_kind rel = VREL_VARYING) const;
+ relation_trio = TRIO_VARYING) const;
relation_kind lhs_op1_relation (const vrange &lhs,
const vrange &op1,
const vrange &op2,
@@ -240,9 +240,10 @@ empty_range_varying (vrange &r, tree type,
inline bool
relop_early_resolve (irange &r, tree type, const vrange &op1,
- const vrange &op2, relation_kind rel,
+ const vrange &op2, relation_trio trio,
relation_kind my_rel)
{
+ relation_kind rel = trio.op1_op2 ();
// If known relation is a complete subset of this relation, always true.
if (relation_union (rel, my_rel) == my_rel)
{
@@ -32,9 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "alloc-pool.h"
#include "dominance.h"
-#define VREL_LAST VREL_PE64
-
-static const char *kind_string[VREL_LAST + 1] =
+static const char *kind_string[VREL_LAST] =
{ "varying", "undefined", "<", "<=", ">", ">=", "==", "!=", "pe8", "pe16",
"pe32", "pe64" };
@@ -47,7 +45,7 @@ print_relation (FILE *f, relation_kind rel)
}
// This table is used to negate the operands. op1 REL op2 -> !(op1 REL op2).
-relation_kind rr_negate_table[VREL_LAST + 1] = {
+relation_kind rr_negate_table[VREL_LAST] = {
VREL_VARYING, VREL_UNDEFINED, VREL_GE, VREL_GT, VREL_LE, VREL_LT, VREL_NE,
VREL_EQ };
@@ -60,7 +58,7 @@ relation_negate (relation_kind r)
}
// This table is used to swap the operands. op1 REL op2 -> op2 REL op1.
-relation_kind rr_swap_table[VREL_LAST + 1] = {
+relation_kind rr_swap_table[VREL_LAST] = {
VREL_VARYING, VREL_UNDEFINED, VREL_GT, VREL_GE, VREL_LT, VREL_LE, VREL_EQ,
VREL_NE };
@@ -74,7 +72,7 @@ relation_swap (relation_kind r)
// This table is used to perform an intersection between 2 relations.
-relation_kind rr_intersect_table[VREL_LAST + 1][VREL_LAST + 1] = {
+relation_kind rr_intersect_table[VREL_LAST][VREL_LAST] = {
// VREL_VARYING
{ VREL_VARYING, VREL_UNDEFINED, VREL_LT, VREL_LE, VREL_GT, VREL_GE, VREL_EQ,
VREL_NE },
@@ -112,7 +110,7 @@ relation_intersect (relation_kind r1, relation_kind r2)
// This table is used to perform a union between 2 relations.
-relation_kind rr_union_table[VREL_LAST + 1][VREL_LAST + 1] = {
+relation_kind rr_union_table[VREL_LAST][VREL_LAST] = {
// VREL_VARYING
{ VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING,
VREL_VARYING, VREL_VARYING, VREL_VARYING },
@@ -150,7 +148,7 @@ relation_union (relation_kind r1, relation_kind r2)
// This table is used to determine transitivity between 2 relations.
// (A relation0 B) and (B relation1 C) implies (A result C)
-relation_kind rr_transitive_table[VREL_LAST + 1][VREL_LAST + 1] = {
+relation_kind rr_transitive_table[VREL_LAST][VREL_LAST] = {
// VREL_VARYING
{ VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING,
VREL_VARYING, VREL_VARYING, VREL_VARYING },
@@ -187,7 +185,7 @@ relation_transitive (relation_kind r1, relation_kind r2)
// This vector maps a relation to the equivalent tree code.
-tree_code relation_to_code [VREL_LAST + 1] = {
+tree_code relation_to_code [VREL_LAST] = {
ERROR_MARK, ERROR_MARK, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EQ_EXPR,
NE_EXPR };
@@ -226,7 +224,8 @@ relation_oracle::validate_relation (relation_kind rel, vrange &op1, vrange &op2)
// If the relation cannot be folded for any reason, leave as is.
Value_Range result (boolean_type_node);
- if (!handler.fold_range (result, boolean_type_node, op1, op2, rel))
+ if (!handler.fold_range (result, boolean_type_node, op1, op2,
+ relation_trio::op1_op2 (rel)))
return rel;
// The expression op1 REL op2 using REL should fold to [1,1].
@@ -35,20 +35,21 @@ along with GCC; see the file COPYING3. If not see
// utilizes the relation information to enhance it's range calculations, this
// is totally transparent to the client, and they are free to make queries.
//
-//
-// relation_kind is a typedef of enum tree_code, but has restricted range
-// and a couple of extra values.
+// relation_kind is a new enum which represents the different relations,
+// often with a direct mapping to treee codes. ie VREL_EQ is equivalent to
+// EQ_EXPR.
//
// A query is made requesting the relation between SSA1 and SSA@ in a basic
// block, or on an edge, the possible return values are:
//
-// EQ_EXPR, NE_EXPR, LT_EXPR, LE_EXPR, GT_EXPR, and GE_EXPR mean the same.
+// VREL_EQ, VREL_NE, VREL_LT, VREL_LE, VREL_GT, and VREL_GE mean the same.
// VREL_VARYING : No relation between the 2 names.
// VREL_UNDEFINED : Impossible relation (ie, A < B && A > B)
//
-// The oracle maintains EQ_EXPR relations with equivalency sets, so if a
-// relation comes back EQ_EXPR, it is also possible to query the set of
-// equivlaencies. These are basically bitmaps over ssa_names.
+// The oracle maintains VREL_EQ relations with equivalency sets, so if a
+// relation comes back VREL_EQ, it is also possible to query the set of
+// equivlaencies. These are basically bitmaps over ssa_names. An iterator is
+// provided later for this activity.
//
// Relations are maintained via the dominace trees and are optimized assuming
// they are registered in dominance order. When a new relation is added, it
@@ -56,10 +57,8 @@ along with GCC; see the file COPYING3. If not see
// and registered at the specified block.
-// Rather than introduce a new enumerated type for relations, we can use the
-// existing tree_codes for relations, plus add a couple of #defines for
-// the other cases. These codes are arranged such that VREL_VARYING is the
-// first code, and all the rest are contiguous.
+// These codes are arranged such that VREL_VARYING is the first code, and all
+// the rest are contiguous.
typedef enum relation_kind_t
{
@@ -74,7 +73,8 @@ typedef enum relation_kind_t
VREL_PE8, // 8 bit partial equivalency
VREL_PE16, // 16 bit partial equivalency
VREL_PE32, // 32 bit partial equivalency
- VREL_PE64 // 64 bit partial equivalency
+ VREL_PE64, // 64 bit partial equivalency
+ VREL_LAST // terminate, not a real relation.
} relation_kind;
// General relation kind transformations.
@@ -315,6 +315,101 @@ protected:
((equiv_name) = iter.get_name (&equiv_rel)); \
iter.next ())
+// -----------------------------------------------------------------------
+
+// Range-ops deals with a LHS and 2 operands. A relation trio is a set of
+// 3 potential relations packed into a single unsigned value.
+// 1 - LHS relation OP1
+// 2 - LHS relation OP2
+// 3 - OP1 relation OP2
+// VREL_VARYING is a value of 0, and is the default for each position.
+class relation_trio
+{
+public:
+ relation_trio ();
+ relation_trio (relation_kind lhs_op1, relation_kind lhs_op2,
+ relation_kind op1_op2);
+ relation_kind lhs_op1 ();
+ relation_kind lhs_op2 ();
+ relation_kind op1_op2 ();
+ relation_trio swap_op1_op2 ();
+
+ static relation_trio lhs_op1 (relation_kind k);
+ static relation_trio lhs_op2 (relation_kind k);
+ static relation_trio op1_op2 (relation_kind k);
+
+protected:
+ unsigned m_val;
+};
+
+// Default VREL_VARYING for all 3 relations.
+#define TRIO_VARYING relation_trio ()
+
+#define TRIO_SHIFT 4
+#define TRIO_MASK 0x000F
+
+// These 3 classes are shortcuts for when a caller has a single relation to
+// pass as a trio, it can simply construct the appropriate one. The other
+// unspecified realtions will be VREL_VARYING.
+
+inline relation_trio::relation_trio ()
+{
+ STATIC_ASSERT (VREL_LAST <= (1 << TRIO_SHIFT));
+ m_val = 0;
+}
+
+inline relation_trio::relation_trio (relation_kind lhs_op1,
+ relation_kind lhs_op2,
+ relation_kind op1_op2)
+{
+ STATIC_ASSERT (VREL_LAST <= (1 << TRIO_SHIFT));
+ unsigned i1 = (unsigned) lhs_op1;
+ unsigned i2 = ((unsigned) lhs_op2) << TRIO_SHIFT;
+ unsigned i3 = ((unsigned) op1_op2) << (TRIO_SHIFT * 2);
+ m_val = i1 | i2 | i3;
+}
+
+inline relation_trio
+relation_trio::lhs_op1 (relation_kind k)
+{
+ return relation_trio (k, VREL_VARYING, VREL_VARYING);
+}
+inline relation_trio
+relation_trio::lhs_op2 (relation_kind k)
+{
+ return relation_trio (VREL_VARYING, k, VREL_VARYING);
+}
+inline relation_trio
+relation_trio::op1_op2 (relation_kind k)
+{
+ return relation_trio (VREL_VARYING, VREL_VARYING, k);
+}
+
+inline relation_kind
+relation_trio::lhs_op1 ()
+{
+ return (relation_kind) (m_val & TRIO_MASK);
+}
+
+inline relation_kind
+relation_trio::lhs_op2 ()
+{
+ return (relation_kind) ((m_val >> TRIO_SHIFT) & TRIO_MASK);
+}
+
+inline relation_kind
+relation_trio::op1_op2 ()
+{
+ return (relation_kind) ((m_val >> (TRIO_SHIFT * 2)) & TRIO_MASK);
+}
+
+inline relation_trio
+relation_trio::swap_op1_op2 ()
+{
+ return relation_trio (lhs_op2 (), lhs_op1 (), relation_swap (op1_op2 ()));
+}
+
+// -----------------------------------------------------------------------
// The value-relation class is used to encapsulate the represention of an
// individual relation between 2 ssa-names, and to facilitate operating on
--
2.37.3