diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2022-05-12 12:00:39 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2022-05-13 11:04:15 -0400 |
commit | ade5531c9dde98c7be005a5c5382739d734797aa (patch) | |
tree | 10a4873e8cb4956ea7a583bc9253a2edf30aa232 /gcc | |
parent | f3204ce1ae6b97f7e79d633844d61d021da8502e (diff) | |
download | gcc-ade5531c9dde98c7be005a5c5382739d734797aa.zip gcc-ade5531c9dde98c7be005a5c5382739d734797aa.tar.gz gcc-ade5531c9dde98c7be005a5c5382739d734797aa.tar.bz2 |
Move VREL values to their own enumerated type.
Re-using some common things like EQ_EXPR and other relationals made
certain things easier, but complicated debugging and added extra overhead
when accessing lookup tables. With forthcoming additional relation types,
it makes more sense to simple have a distinct relation kind.
* gimple-range-fold.cc (fold_using_range::range_of_phi): Use new VREL_*
enumerated values.
* gimple-range-path.cc (maybe_register_phi_relation): Ditto.
* range-op.cc (*::lhs_op1_relation): Return relation_kind, and use
new VREL enumerated values.
(*::lhs_op2_relation): Ditto.
(*::op1_op2_relation): Ditto.
(*::fold_range): Use new VREL enumerated values.
(minus_op1_op2_relation_effect): Ditto.
(range_relational_tests): Ditto.
* range-op.h (fold_range, op1_range, op2_range): Use VREL_VARYING.
(lhs_op1_relation, lhs_op2_relation, op1_op2_relation): Return
relation_kind.
(*_op1_op2_relation): Return relation_kind.
(relop_early_resolve): Use VREL_UNDEFINED.
* value-query.cc (range_query::query_relation): Use VREL_VARYING.
* value-relation.cc (VREL_LAST): Change enumerated value.
(vrel_range_assert): Delete.
(print_relation): Remove range assert.
(rr_negate_table): Adjust table to use new enumerated values..
(relation_negate): Remove range assert.
(rr_swap_table): Adjust.
(relation_swap): Remove range assert.
(rr_intersect_table): Adjust.
(relation_intersect): Remove range assert.
(rr_union_table): Adjust.
(relation_union): Remove range assert.
(rr_transitive_table): Adjust.
(relation_transitive): Remove range assert.
(equiv_oracle::query_relation): Use new VREL enumerated values.
(equiv_oracle::register_relation): Ditto.
(relation_oracle::register_stmt): Ditto.
(dom_oracle::set_one_relation): Ditto.
(dom_oracle::register_transitives): Ditto.
(dom_oracle::query_relation): Ditto.
(path_oracle::register_relation): Ditto.
(path_oracle::query_relation): Ditto.
* value-relation.h (enum relation_kind_t): New relation_kind.
(*_op1_op2_relation): Adjust prototypes.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/gimple-range-fold.cc | 28 | ||||
-rw-r--r-- | gcc/gimple-range-path.cc | 6 | ||||
-rw-r--r-- | gcc/range-op.cc | 318 | ||||
-rw-r--r-- | gcc/range-op.h | 38 | ||||
-rw-r--r-- | gcc/value-query.cc | 4 | ||||
-rw-r--r-- | gcc/value-relation.cc | 278 | ||||
-rw-r--r-- | gcc/value-relation.h | 26 |
7 files changed, 350 insertions, 348 deletions
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index bc8174e..5f1b3b9 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -80,7 +80,7 @@ relation_kind fur_source::query_relation (tree op1 ATTRIBUTE_UNUSED, tree op2 ATTRIBUTE_UNUSED) { - return VREL_NONE; + return VREL_VARYING; } // Default registers nothing. @@ -613,14 +613,14 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src) src.gori ()->register_dependency (lhs, op1); relation_kind rel; rel = handler->lhs_op1_relation (r, range1, range1); - if (rel != VREL_NONE) + if (rel != VREL_VARYING) src.register_relation (s, rel, lhs, op1); } } else if (src.get_operand (range2, op2)) { relation_kind rel = src.query_relation (op1, op2); - if (dump_file && (dump_flags & TDF_DETAILS) && rel != VREL_NONE) + if (dump_file && (dump_flags & TDF_DETAILS) && rel != VREL_VARYING) { fprintf (dump_file, " folding with relation "); print_generic_expr (dump_file, op1, TDF_SLIM); @@ -641,13 +641,13 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src) if (gimple_range_ssa_p (op1)) { rel = handler->lhs_op1_relation (r, range1, range2, rel); - if (rel != VREL_NONE) + if (rel != VREL_VARYING) src.register_relation (s, rel, lhs, op1); } if (gimple_range_ssa_p (op2)) { rel= handler->lhs_op2_relation (r, range1, range2, rel); - if (rel != VREL_NONE) + if (rel != VREL_VARYING) src.register_relation (s, rel, lhs, op2); } } @@ -804,7 +804,7 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src) // Likewise, if the incoming PHI argument is equivalent to this // PHI definition, it provides no new info. Accumulate these ranges // in case all arguments are equivalences. - if (src.query ()->query_relation (e, arg, phi_def, false) == EQ_EXPR) + if (src.query ()->query_relation (e, arg, phi_def, false) == VREL_EQ) equiv_range.union_(arg_range); else r.union_ (arg_range); @@ -837,7 +837,7 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src) { // Symbolic arguments are equivalences. if (gimple_range_ssa_p (single_arg)) - src.register_relation (phi, EQ_EXPR, phi_def, single_arg); + src.register_relation (phi, VREL_EQ, phi_def, single_arg); else if (src.get_operand (arg_range, single_arg) && arg_range.singleton_p ()) { @@ -1402,18 +1402,18 @@ fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s, relation_kind relation1 = handler1->op1_op2_relation (bool_one); relation_kind relation2 = handler2->op1_op2_relation (bool_one); - if (relation1 == VREL_NONE || relation2 == VREL_NONE) + if (relation1 == VREL_VARYING || relation2 == VREL_VARYING) return; if (reverse_op2) relation2 = relation_negate (relation2); // x && y is false if the relation intersection of the true cases is NULL. - if (is_and && relation_intersect (relation1, relation2) == VREL_EMPTY) + if (is_and && relation_intersect (relation1, relation2) == VREL_UNDEFINED) lhs_range = int_range<2> (boolean_false_node, boolean_false_node); // x || y is true if the union of the true cases is NO-RELATION.. // ie, one or the other being true covers the full range of possibilties. - else if (!is_and && relation_union (relation1, relation2) == VREL_NONE) + else if (!is_and && relation_union (relation1, relation2) == VREL_VARYING) lhs_range = bool_one; else return; @@ -1477,13 +1477,13 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge if (e0) { relation_kind relation = handler->op1_op2_relation (e0_range); - if (relation != VREL_NONE) + if (relation != VREL_VARYING) register_relation (e0, relation, ssa1, ssa2); } if (e1) { relation_kind relation = handler->op1_op2_relation (e1_range); - if (relation != VREL_NONE) + if (relation != VREL_VARYING) register_relation (e1, relation, ssa1, ssa2); } } @@ -1512,14 +1512,14 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge && r.singleton_p ()) { relation_kind relation = handler->op1_op2_relation (r); - if (relation != VREL_NONE) + if (relation != VREL_VARYING) register_relation (e0, relation, ssa1, ssa2); } if (e1 && gori ()->outgoing_edge_range_p (r, e1, name, *m_query) && r.singleton_p ()) { relation_kind relation = handler->op1_op2_relation (r); - if (relation != VREL_NONE) + if (relation != VREL_VARYING) register_relation (e1, relation, ssa1, ssa2); } } diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc index 483bcd2..ff39833 100644 --- a/gcc/gimple-range-path.cc +++ b/gcc/gimple-range-path.cc @@ -740,10 +740,10 @@ relation_kind jt_fur_source::query_relation (tree op1, tree op2) { if (!m_oracle) - return VREL_NONE; + return VREL_VARYING; if (TREE_CODE (op1) != SSA_NAME || TREE_CODE (op2) != SSA_NAME) - return VREL_NONE; + return VREL_VARYING; return m_oracle->query_relation (m_entry, op1, op2); } @@ -799,7 +799,7 @@ path_range_query::maybe_register_phi_relation (gphi *phi, edge e) fprintf (dump_file, "maybe_register_phi_relation in bb%d:", bb->index); get_path_oracle ()->killing_def (result); - m_oracle->register_relation (entry_bb (), EQ_EXPR, arg, result); + m_oracle->register_relation (entry_bb (), VREL_EQ, arg, result); } // Compute relations for each PHI in BB. For example: diff --git a/gcc/range-op.cc b/gcc/range-op.cc index d015b9f..e6b32e2 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -244,30 +244,30 @@ range_operator::op2_range (irange &r ATTRIBUTE_UNUSED, return false; } -// The default relation routines return VREL_NONE. +// The default relation routines return VREL_VARYING. -enum tree_code +relation_kind range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, const irange &op1 ATTRIBUTE_UNUSED, const irange &op2 ATTRIBUTE_UNUSED, relation_kind rel ATTRIBUTE_UNUSED) const { - return VREL_NONE; + return VREL_VARYING; } -enum tree_code +relation_kind range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED, const irange &op1 ATTRIBUTE_UNUSED, const irange &op2 ATTRIBUTE_UNUSED, relation_kind rel ATTRIBUTE_UNUSED) const { - return VREL_NONE; + return VREL_VARYING; } -enum tree_code +relation_kind range_operator::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) const { - return VREL_NONE; + return VREL_VARYING; } // Default is no relation affects the LHS. @@ -450,37 +450,37 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &val, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &val, - relation_kind rel = VREL_NONE) const; - virtual enum tree_code op1_op2_relation (const irange &lhs) const; + relation_kind rel = VREL_VARYING) const; + virtual relation_kind op1_op2_relation (const irange &lhs) const; } op_equal; // Check if the LHS range indicates a relation between OP1 and OP2. -enum tree_code +relation_kind equal_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) - return VREL_EMPTY; + return VREL_UNDEFINED; // FALSE = op1 == op2 indicates NE_EXPR. if (lhs.zero_p ()) - return NE_EXPR; + return VREL_NE; // TRUE = op1 == op2 indicates EQ_EXPR. if (!lhs.contains_p (build_zero_cst (lhs.type ()))) - return EQ_EXPR; - return VREL_NONE; + return VREL_EQ; + return VREL_VARYING; } -enum tree_code +relation_kind operator_equal::op1_op2_relation (const irange &lhs) const { return equal_op1_op2_relation (lhs); @@ -493,7 +493,7 @@ operator_equal::fold_range (irange &r, tree type, const irange &op2, relation_kind rel) const { - if (relop_early_resolve (r, type, op1, op2, rel, EQ_EXPR)) + if (relop_early_resolve (r, type, op1, op2, rel, VREL_EQ)) return true; // We can be sure the values are always equal or not if both ranges @@ -566,37 +566,37 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; - virtual enum tree_code op1_op2_relation (const irange &lhs) const; + relation_kind rel = VREL_VARYING) const; + virtual relation_kind op1_op2_relation (const irange &lhs) const; } op_not_equal; // Check if the LHS range indicates a relation between OP1 and OP2. -enum tree_code +relation_kind not_equal_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) - return VREL_EMPTY; + return VREL_UNDEFINED; // FALSE = op1 != op2 indicates EQ_EXPR. if (lhs.zero_p ()) - return EQ_EXPR; + return VREL_EQ; // TRUE = op1 != op2 indicates NE_EXPR. if (!lhs.contains_p (build_zero_cst (lhs.type ()))) - return NE_EXPR; - return VREL_NONE; + return VREL_NE; + return VREL_VARYING; } -enum tree_code +relation_kind operator_not_equal::op1_op2_relation (const irange &lhs) const { return not_equal_op1_op2_relation (lhs); @@ -608,7 +608,7 @@ operator_not_equal::fold_range (irange &r, tree type, const irange &op2, relation_kind rel) const { - if (relop_early_resolve (r, type, op1, op2, rel, NE_EXPR)) + if (relop_early_resolve (r, type, op1, op2, rel, VREL_NE)) return true; // We can be sure the values are always equal or not if both ranges @@ -742,37 +742,37 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; - virtual enum tree_code op1_op2_relation (const irange &lhs) const; + relation_kind rel = VREL_VARYING) const; + virtual relation_kind op1_op2_relation (const irange &lhs) const; } op_lt; // Check if the LHS range indicates a relation between OP1 and OP2. -enum tree_code +relation_kind lt_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) - return VREL_EMPTY; + return VREL_UNDEFINED; // FALSE = op1 < op2 indicates GE_EXPR. if (lhs.zero_p ()) - return GE_EXPR; + return VREL_GE; // TRUE = op1 < op2 indicates LT_EXPR. if (!lhs.contains_p (build_zero_cst (lhs.type ()))) - return LT_EXPR; - return VREL_NONE; + return VREL_LT; + return VREL_VARYING; } -enum tree_code +relation_kind operator_lt::op1_op2_relation (const irange &lhs) const { return lt_op1_op2_relation (lhs); @@ -784,7 +784,7 @@ operator_lt::fold_range (irange &r, tree type, const irange &op2, relation_kind rel) const { - if (relop_early_resolve (r, type, op1, op2, rel, LT_EXPR)) + if (relop_early_resolve (r, type, op1, op2, rel, VREL_LT)) return true; signop sign = TYPE_SIGN (op1.type ()); @@ -850,37 +850,37 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; - virtual enum tree_code op1_op2_relation (const irange &lhs) const; + relation_kind rel = VREL_VARYING) const; + virtual relation_kind op1_op2_relation (const irange &lhs) const; } op_le; // Check if the LHS range indicates a relation between OP1 and OP2. -enum tree_code +relation_kind le_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) - return VREL_EMPTY; + return VREL_UNDEFINED; // FALSE = op1 <= op2 indicates GT_EXPR. if (lhs.zero_p ()) - return GT_EXPR; + return VREL_GT; // TRUE = op1 <= op2 indicates LE_EXPR. if (!lhs.contains_p (build_zero_cst (lhs.type ()))) - return LE_EXPR; - return VREL_NONE; + return VREL_LE; + return VREL_VARYING; } -enum tree_code +relation_kind operator_le::op1_op2_relation (const irange &lhs) const { return le_op1_op2_relation (lhs); @@ -892,7 +892,7 @@ operator_le::fold_range (irange &r, tree type, const irange &op2, relation_kind rel) const { - if (relop_early_resolve (r, type, op1, op2, rel, LE_EXPR)) + if (relop_early_resolve (r, type, op1, op2, rel, VREL_LE)) return true; signop sign = TYPE_SIGN (op1.type ()); @@ -958,37 +958,37 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; - virtual enum tree_code op1_op2_relation (const irange &lhs) const; + relation_kind rel = VREL_VARYING) const; + virtual relation_kind op1_op2_relation (const irange &lhs) const; } op_gt; // Check if the LHS range indicates a relation between OP1 and OP2. -enum tree_code +relation_kind gt_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) - return VREL_EMPTY; + return VREL_UNDEFINED; // FALSE = op1 > op2 indicates LE_EXPR. if (lhs.zero_p ()) - return LE_EXPR; + return VREL_LE; // TRUE = op1 > op2 indicates GT_EXPR. if (!lhs.contains_p (build_zero_cst (lhs.type ()))) - return GT_EXPR; - return VREL_NONE; + return VREL_GT; + return VREL_VARYING; } -enum tree_code +relation_kind operator_gt::op1_op2_relation (const irange &lhs) const { return gt_op1_op2_relation (lhs); @@ -1000,7 +1000,7 @@ operator_gt::fold_range (irange &r, tree type, const irange &op1, const irange &op2, relation_kind rel) const { - if (relop_early_resolve (r, type, op1, op2, rel, GT_EXPR)) + if (relop_early_resolve (r, type, op1, op2, rel, VREL_GT)) return true; signop sign = TYPE_SIGN (op1.type ()); @@ -1065,37 +1065,37 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; - virtual enum tree_code op1_op2_relation (const irange &lhs) const; + relation_kind rel = VREL_VARYING) const; + virtual relation_kind op1_op2_relation (const irange &lhs) const; } op_ge; // Check if the LHS range indicates a relation between OP1 and OP2. -enum tree_code +relation_kind ge_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) - return VREL_EMPTY; + return VREL_UNDEFINED; // FALSE = op1 >= op2 indicates LT_EXPR. if (lhs.zero_p ()) - return LT_EXPR; + return VREL_LT; // TRUE = op1 >= op2 indicates GE_EXPR. if (!lhs.contains_p (build_zero_cst (lhs.type ()))) - return GE_EXPR; - return VREL_NONE; + return VREL_GE; + return VREL_VARYING; } -enum tree_code +relation_kind operator_ge::op1_op2_relation (const irange &lhs) const { return ge_op1_op2_relation (lhs); @@ -1107,7 +1107,7 @@ operator_ge::fold_range (irange &r, tree type, const irange &op2, relation_kind rel) const { - if (relop_early_resolve (r, type, op1, op2, rel, GE_EXPR)) + if (relop_early_resolve (r, type, op1, op2, rel, VREL_GE)) return true; signop sign = TYPE_SIGN (op1.type ()); @@ -1183,25 +1183,25 @@ public: const wide_int &lh_ub, const wide_int &rh_lb, const wide_int &rh_ub) const; - virtual enum tree_code lhs_op1_relation (const irange &lhs, const irange &op1, - const irange &op2, - relation_kind rel) const; - virtual enum tree_code lhs_op2_relation (const irange &lhs, const irange &op1, - const irange &op2, - relation_kind rel) const; + virtual relation_kind lhs_op1_relation (const irange &lhs, const irange &op1, + const irange &op2, + relation_kind rel) const; + virtual relation_kind lhs_op2_relation (const irange &lhs, const irange &op1, + const irange &op2, + relation_kind rel) const; } op_plus; // Check to see if the range of OP2 indicates anything about the relation // between LHS and OP1. -enum tree_code +relation_kind operator_plus::lhs_op1_relation (const irange &lhs, const irange &op1, const irange &op2, relation_kind) const { if (lhs.undefined_p () || op1.undefined_p () || op2.undefined_p ()) - return VREL_NONE; + return VREL_VARYING; tree type = lhs.type (); unsigned prec = TYPE_PRECISION (type); @@ -1210,7 +1210,7 @@ operator_plus::lhs_op1_relation (const irange &lhs, // LHS = OP1 + 0 indicates LHS == OP1. if (op2.zero_p ()) - return EQ_EXPR; + return VREL_EQ; if (TYPE_OVERFLOW_WRAPS (type)) { @@ -1225,43 +1225,43 @@ operator_plus::lhs_op1_relation (const irange &lhs, { // Positive op2 means lhs > op1. if (wi::gt_p (op2.lower_bound (), wi::zero (prec), sign)) - return GT_EXPR; + return VREL_GT; if (wi::ge_p (op2.lower_bound (), wi::zero (prec), sign)) - return GE_EXPR; + return VREL_GE; // Negative op2 means lhs < op1. if (wi::lt_p (op2.upper_bound (), wi::zero (prec), sign)) - return LT_EXPR; + return VREL_LT; if (wi::le_p (op2.upper_bound (), wi::zero (prec), sign)) - return LE_EXPR; + return VREL_LE; } // Always wrapping additions. else if (ovf1 && ovf1 == ovf2) { // Positive op2 means lhs < op1. if (wi::gt_p (op2.lower_bound (), wi::zero (prec), sign)) - return LT_EXPR; + return VREL_LT; if (wi::ge_p (op2.lower_bound (), wi::zero (prec), sign)) - return LE_EXPR; + return VREL_LE; // Negative op2 means lhs > op1. if (wi::lt_p (op2.upper_bound (), wi::zero (prec), sign)) - return GT_EXPR; + return VREL_GT; if (wi::le_p (op2.upper_bound (), wi::zero (prec), sign)) - return GE_EXPR; + return VREL_GE; } // If op2 does not contain 0, then LHS and OP1 can never be equal. if (!range_includes_zero_p (&op2)) - return NE_EXPR; + return VREL_NE; - return VREL_NONE; + return VREL_VARYING; } // PLUS is symmetrical, so we can simply call lhs_op1_relation with reversed // operands. -enum tree_code +relation_kind operator_plus::lhs_op2_relation (const irange &lhs, const irange &op1, const irange &op2, relation_kind rel) const { @@ -1315,7 +1315,7 @@ public: const wide_int &lh_ub, const wide_int &rh_lb, const wide_int &rh_ub) const; - virtual enum tree_code lhs_op1_relation (const irange &lhs, + virtual relation_kind lhs_op1_relation (const irange &lhs, const irange &op1, const irange &op2, relation_kind rel) const; @@ -1342,21 +1342,21 @@ operator_minus::wi_fold (irange &r, tree type, // Return the relation between LHS and OP1 based on the relation between // OP1 and OP2. -enum tree_code +relation_kind operator_minus::lhs_op1_relation (const irange &lhs, const irange &, const irange &, relation_kind rel) const { if (TYPE_SIGN (lhs.type ()) == UNSIGNED) switch (rel) { - case GT_EXPR: - return LT_EXPR; - case GE_EXPR: - return LE_EXPR; + case VREL_GT: + return VREL_LT; + case VREL_GE: + return VREL_LE; default: break; } - return VREL_NONE; + return VREL_VARYING; } // Check to see if the relation REL between OP1 and OP2 has any effect on the @@ -1369,7 +1369,7 @@ minus_op1_op2_relation_effect (irange &lhs_range, tree type, const irange &op2_range ATTRIBUTE_UNUSED, relation_kind rel) { - if (rel == VREL_NONE) + if (rel == VREL_VARYING) return false; int_range<2> rel_range; @@ -1377,9 +1377,9 @@ minus_op1_op2_relation_effect (irange &lhs_range, tree type, signop sgn = TYPE_SIGN (type); // == and != produce [0,0] and ~[0,0] regardless of wrapping. - if (rel == EQ_EXPR) + if (rel == VREL_EQ) rel_range = int_range<2> (type, wi::zero (prec), wi::zero (prec)); - else if (rel == NE_EXPR) + else if (rel == VREL_NE) rel_range = int_range<2> (type, wi::zero (prec), wi::zero (prec), VR_ANTI_RANGE); else if (TYPE_OVERFLOW_WRAPS (type)) @@ -1388,8 +1388,8 @@ minus_op1_op2_relation_effect (irange &lhs_range, tree type, { // For wrapping signed values and unsigned, if op1 > op2 or // op1 < op2, then op1 - op2 can be restricted to ~[0, 0]. - case GT_EXPR: - case LT_EXPR: + case VREL_GT: + case VREL_LT: rel_range = int_range<2> (type, wi::zero (prec), wi::zero (prec), VR_ANTI_RANGE); break; @@ -1402,22 +1402,22 @@ minus_op1_op2_relation_effect (irange &lhs_range, tree type, switch (rel) { // op1 > op2, op1 - op2 can be restricted to [1, +INF] - case GT_EXPR: + case VREL_GT: rel_range = int_range<2> (type, wi::one (prec), wi::max_value (prec, sgn)); break; // op1 >= op2, op1 - op2 can be restricted to [0, +INF] - case GE_EXPR: + case VREL_GE: rel_range = int_range<2> (type, wi::zero (prec), wi::max_value (prec, sgn)); break; // op1 < op2, op1 - op2 can be restricted to [-INF, -1] - case LT_EXPR: + case VREL_LT: rel_range = int_range<2> (type, wi::min_value (prec, sgn), wi::minus_one (prec)); break; // op1 <= op2, op1 - op2 can be restricted to [-INF, 0] - case LE_EXPR: + case VREL_LE: rel_range = int_range<2> (type, wi::min_value (prec, sgn), wi::zero (prec)); break; @@ -1892,11 +1892,11 @@ public: virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, @@ -1913,7 +1913,7 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, @@ -1926,15 +1926,15 @@ public: virtual bool op1_range (irange &, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; - virtual enum tree_code lhs_op1_relation (const irange &lhs, + relation_kind rel = VREL_VARYING) const; + virtual relation_kind lhs_op1_relation (const irange &lhs, const irange &op1, const irange &op2, relation_kind rel) const; } op_rshift; -enum tree_code +relation_kind operator_rshift::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, const irange &op1, const irange &op2, @@ -1944,8 +1944,8 @@ operator_rshift::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, if (!op1.undefined_p () && !op2.undefined_p () && wi::ge_p (op1.lower_bound (), 0, TYPE_SIGN (op1.type ())) && wi::ge_p (op2.lower_bound (), 0, TYPE_SIGN (op2.type ()))) - return LE_EXPR; - return VREL_NONE; + return VREL_LE; + return VREL_VARYING; } bool @@ -2252,11 +2252,11 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; private: bool truncating_cast_p (const irange &inner, const irange &outer) const; bool inside_domain_p (const wide_int &min, const wide_int &max, @@ -2473,15 +2473,15 @@ public: virtual bool fold_range (irange &r, tree type, const irange &lh, const irange &rh, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; } op_logical_and; @@ -2546,15 +2546,15 @@ public: virtual bool fold_range (irange &r, tree type, const irange &lh, const irange &rh, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, @@ -2992,15 +2992,15 @@ public: virtual bool fold_range (irange &r, tree type, const irange &lh, const irange &rh, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; } op_logical_or; bool @@ -3055,11 +3055,11 @@ public: virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel= VREL_NONE) const; + relation_kind rel= VREL_VARYING) const; virtual void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, @@ -3164,11 +3164,11 @@ public: virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_op2_relation_effect (irange &lhs_range, tree type, const irange &op1_range, @@ -3229,17 +3229,17 @@ operator_bitwise_xor::op1_op2_relation_effect (irange &lhs_range, const irange &, relation_kind rel) const { - if (rel == VREL_NONE) + if (rel == VREL_VARYING) return false; int_range<2> rel_range; switch (rel) { - case EQ_EXPR: + case VREL_EQ: rel_range.set_zero (type); break; - case NE_EXPR: + case VREL_NE: rel_range.set_nonzero (type); break; default: @@ -3436,11 +3436,11 @@ public: virtual bool fold_range (irange &r, tree type, const irange &lh, const irange &rh, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; } op_logical_not; // Folding a logical NOT, oddly enough, involves doing nothing on the @@ -3491,11 +3491,11 @@ public: virtual bool fold_range (irange &r, tree type, const irange &lh, const irange &rh, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; } op_bitwise_not; bool @@ -3537,7 +3537,7 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; } op_integer_cst; bool @@ -3557,12 +3557,12 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; - virtual enum tree_code lhs_op1_relation (const irange &lhs, + relation_kind rel = VREL_VARYING) const; + virtual relation_kind lhs_op1_relation (const irange &lhs, const irange &op1, const irange &op2, relation_kind rel) const; @@ -3570,16 +3570,16 @@ public: // Determine if there is a relationship between LHS and OP1. -enum tree_code +relation_kind operator_identity::lhs_op1_relation (const irange &lhs, const irange &op1 ATTRIBUTE_UNUSED, const irange &op2 ATTRIBUTE_UNUSED, relation_kind) const { if (lhs.undefined_p ()) - return VREL_NONE; + return VREL_VARYING; // Simply a copy, so they are equivalent. - return EQ_EXPR; + return VREL_EQ; } bool @@ -3609,7 +3609,7 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; } op_unknown; bool @@ -3794,11 +3794,11 @@ class operator_negate : public range_operator virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; } op_negate; bool @@ -3832,11 +3832,11 @@ public: virtual bool fold_range (irange &r, tree type, const irange &op1, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; } op_addr; bool @@ -3982,11 +3982,11 @@ public: virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_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; @@ -4461,20 +4461,20 @@ range_relational_tests () int_range<2> op2 (UCHAR (20), UCHAR (20)); // Never wrapping additions mean LHS > OP1. - tree_code code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_NONE); - ASSERT_TRUE (code == GT_EXPR); + relation_kind code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_VARYING); + ASSERT_TRUE (code == VREL_GT); // Most wrapping additions mean nothing... op1 = int_range<2> (UCHAR (8), UCHAR (10)); op2 = int_range<2> (UCHAR (0), UCHAR (255)); - code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_NONE); - ASSERT_TRUE (code == VREL_NONE); + code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_VARYING); + ASSERT_TRUE (code == VREL_VARYING); // However, always wrapping additions mean LHS < OP1. op1 = int_range<2> (UCHAR (1), UCHAR (255)); op2 = int_range<2> (UCHAR (255), UCHAR (255)); - code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_NONE); - ASSERT_TRUE (code == LT_EXPR); + code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_VARYING); + ASSERT_TRUE (code == VREL_LT); } void diff --git a/gcc/range-op.h b/gcc/range-op.h index a1f98cd..5fdda32 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -53,7 +53,7 @@ public: virtual bool fold_range (irange &r, tree type, const irange &lh, const irange &rh, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_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,25 +69,25 @@ public: virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel = VREL_NONE) const; + relation_kind rel = VREL_VARYING) const; // The following routines are used to represent relations between the // various operations. If the caller knows where the symbolics are, // it can query for relationships between them given known ranges. // the optional relation passed in is the relation between op1 and op2. - virtual enum tree_code lhs_op1_relation (const irange &lhs, - const irange &op1, - const irange &op2, - relation_kind rel = VREL_NONE) const; - virtual enum tree_code lhs_op2_relation (const irange &lhs, - const irange &op1, - const irange &op2, - relation_kind rel = VREL_NONE) const; - virtual enum tree_code op1_op2_relation (const irange &lhs) const; + virtual relation_kind lhs_op1_relation (const irange &lhs, + const irange &op1, + const irange &op2, + relation_kind = VREL_VARYING) const; + virtual relation_kind lhs_op2_relation (const irange &lhs, + const irange &op1, + const irange &op2, + relation_kind = VREL_VARYING) const; + virtual relation_kind op1_op2_relation (const irange &lhs) const; protected: // Perform an integral operation between 2 sub-ranges and return it. virtual void wi_fold (irange &r, tree type, @@ -116,12 +116,12 @@ extern void wi_set_zero_nonzero_bits (tree type, wide_int &mustbe_nonzero); // op1_op2_relation methods that are the same across irange and frange. -enum tree_code equal_op1_op2_relation (const irange &lhs); -enum tree_code not_equal_op1_op2_relation (const irange &lhs); -enum tree_code lt_op1_op2_relation (const irange &lhs); -enum tree_code le_op1_op2_relation (const irange &lhs); -enum tree_code gt_op1_op2_relation (const irange &lhs); -enum tree_code ge_op1_op2_relation (const irange &lhs); +relation_kind equal_op1_op2_relation (const irange &lhs); +relation_kind not_equal_op1_op2_relation (const irange &lhs); +relation_kind lt_op1_op2_relation (const irange &lhs); +relation_kind le_op1_op2_relation (const irange &lhs); +relation_kind gt_op1_op2_relation (const irange &lhs); +relation_kind ge_op1_op2_relation (const irange &lhs); enum bool_range_state { BRS_FALSE, BRS_TRUE, BRS_EMPTY, BRS_FULL }; bool_range_state get_bool_state (irange &r, const irange &lhs, tree val_type); @@ -162,7 +162,7 @@ relop_early_resolve (irange &r, tree type, const irange &op1, } // If known relation has no subset of this relation, always false. - if (relation_intersect (rel, my_rel) == VREL_EMPTY) + if (relation_intersect (rel, my_rel) == VREL_UNDEFINED) { r = range_false (type); return true; diff --git a/gcc/value-query.cc b/gcc/value-query.cc index 844070a..9ccd802 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -457,7 +457,7 @@ range_query::query_relation (gimple *s, tree ssa1, tree ssa2, bool get_range) { int_range_max tmp; if (!m_oracle || TREE_CODE (ssa1) != SSA_NAME || TREE_CODE (ssa2) != SSA_NAME) - return VREL_NONE; + return VREL_VARYING; // Ensure ssa1 and ssa2 have both been evaluated. if (get_range) @@ -478,7 +478,7 @@ range_query::query_relation (edge e, tree ssa1, tree ssa2, bool get_range) basic_block bb; int_range_max tmp; if (!m_oracle || TREE_CODE (ssa1) != SSA_NAME || TREE_CODE (ssa2) != SSA_NAME) - return VREL_NONE; + return VREL_VARYING; // Use destination block if it has a single predecessor, and this picks // up any relation on the edge. diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc index db2db33..a935651 100644 --- a/gcc/value-relation.cc +++ b/gcc/value-relation.cc @@ -32,84 +32,72 @@ along with GCC; see the file COPYING3. If not see #include "alloc-pool.h" #include "dominance.h" -// These VREL codes are arranged such that VREL_NONE is the first -// code, and all the rest are contiguous up to and including VREL_LAST. - -#define VREL_FIRST VREL_NONE -#define VREL_LAST NE_EXPR -#define VREL_COUNT (VREL_LAST - VREL_FIRST + 1) - -// vrel_range_assert will either assert that the tree code passed is valid, -// or mark invalid codes as unreachable to help with table optimation. -#if CHECKING_P - #define vrel_range_assert(c) \ - gcc_checking_assert ((c) >= VREL_FIRST && (c) <= VREL_LAST) -#else - #define vrel_range_assert(c) \ - if ((c) < VREL_FIRST || (c) > VREL_LAST) \ - gcc_unreachable (); -#endif - -static const char *kind_string[VREL_COUNT] = -{ "none", "<", "<=", ">", ">=", "empty", "==", "!=" }; +#define VREL_LAST VREL_NE + +static const char *kind_string[VREL_LAST + 1] = +{ "varying", "undefined", "<", "<=", ">", ">=", "==", "!=" }; // Print a relation_kind REL to file F. void print_relation (FILE *f, relation_kind rel) { - vrel_range_assert (rel); - fprintf (f, " %s ", kind_string[rel - VREL_FIRST]); + fprintf (f, " %s ", kind_string[rel]); } // This table is used to negate the operands. op1 REL op2 -> !(op1 REL op2). -relation_kind rr_negate_table[VREL_COUNT] = { -// NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EMPTY, EQ_EXPR, NE_EXPR - VREL_NONE, GE_EXPR, GT_EXPR, LE_EXPR, LT_EXPR, VREL_EMPTY, NE_EXPR, EQ_EXPR }; +relation_kind rr_negate_table[VREL_LAST + 1] = { + VREL_VARYING, VREL_UNDEFINED, VREL_GE, VREL_GT, VREL_LE, VREL_LT, VREL_NE, + VREL_EQ }; // Negate the relation, as in logical negation. relation_kind relation_negate (relation_kind r) { - vrel_range_assert (r); - return rr_negate_table [r - VREL_FIRST]; + return rr_negate_table [r]; } // This table is used to swap the operands. op1 REL op2 -> op2 REL op1. -relation_kind rr_swap_table[VREL_COUNT] = { -// NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EMPTY, EQ_EXPR, NE_EXPR - VREL_NONE, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR, VREL_EMPTY, EQ_EXPR, NE_EXPR }; +relation_kind rr_swap_table[VREL_LAST + 1] = { + VREL_VARYING, VREL_UNDEFINED, VREL_GT, VREL_GE, VREL_LT, VREL_LE, VREL_EQ, + VREL_NE }; // Return the relation as if the operands were swapped. relation_kind relation_swap (relation_kind r) { - vrel_range_assert (r); - return rr_swap_table [r - VREL_FIRST]; + return rr_swap_table [r]; } // This table is used to perform an intersection between 2 relations. -relation_kind rr_intersect_table[VREL_COUNT][VREL_COUNT] = { -// NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EMPTY, EQ_EXPR, NE_EXPR -// VREL_NONE - { VREL_NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, VREL_EMPTY, EQ_EXPR, NE_EXPR }, -// LT_EXPR - { LT_EXPR, LT_EXPR, LT_EXPR, VREL_EMPTY, VREL_EMPTY, VREL_EMPTY, VREL_EMPTY, LT_EXPR }, -// LE_EXPR - { LE_EXPR, LT_EXPR, LE_EXPR, VREL_EMPTY, EQ_EXPR, VREL_EMPTY, EQ_EXPR, LT_EXPR }, -// GT_EXPR - { GT_EXPR, VREL_EMPTY, VREL_EMPTY, GT_EXPR, GT_EXPR, VREL_EMPTY, VREL_EMPTY, GT_EXPR }, -// GE_EXPR - { GE_EXPR, VREL_EMPTY, EQ_EXPR, GT_EXPR, GE_EXPR, VREL_EMPTY, EQ_EXPR, GT_EXPR }, -// VREL_EMPTY - { VREL_EMPTY, VREL_EMPTY, VREL_EMPTY, VREL_EMPTY, VREL_EMPTY, VREL_EMPTY, VREL_EMPTY, VREL_EMPTY }, -// EQ_EXPR - { EQ_EXPR, VREL_EMPTY, EQ_EXPR, VREL_EMPTY, EQ_EXPR, VREL_EMPTY, EQ_EXPR, VREL_EMPTY }, -// NE_EXPR - { NE_EXPR, LT_EXPR, LT_EXPR, GT_EXPR, GT_EXPR, VREL_EMPTY, VREL_EMPTY, NE_EXPR } }; +relation_kind rr_intersect_table[VREL_LAST + 1][VREL_LAST + 1] = { +// VREL_VARYING + { VREL_VARYING, VREL_UNDEFINED, VREL_LT, VREL_LE, VREL_GT, VREL_GE, VREL_EQ, + VREL_NE }, +// VREL_UNDEFINED + { VREL_UNDEFINED, VREL_UNDEFINED, VREL_UNDEFINED, VREL_UNDEFINED, + VREL_UNDEFINED, VREL_UNDEFINED, VREL_UNDEFINED, VREL_UNDEFINED }, +// VREL_LT + { VREL_LT, VREL_UNDEFINED, VREL_LT, VREL_LT, VREL_UNDEFINED, VREL_UNDEFINED, + VREL_UNDEFINED, VREL_LT }, +// VREL_LE + { VREL_LE, VREL_UNDEFINED, VREL_LT, VREL_LE, VREL_UNDEFINED, VREL_EQ, + VREL_EQ, VREL_LT }, +// VREL_GT + { VREL_GT, VREL_UNDEFINED, VREL_UNDEFINED, VREL_UNDEFINED, VREL_GT, VREL_GT, + VREL_UNDEFINED, VREL_GT }, +// VREL_GE + { VREL_GE, VREL_UNDEFINED, VREL_UNDEFINED, VREL_EQ, VREL_GT, VREL_GE, + VREL_EQ, VREL_GT }, +// VREL_EQ + { VREL_EQ, VREL_UNDEFINED, VREL_UNDEFINED, VREL_EQ, VREL_UNDEFINED, VREL_EQ, + VREL_EQ, VREL_UNDEFINED }, +// VREL_NE + { VREL_NE, VREL_UNDEFINED, VREL_LT, VREL_LT, VREL_GT, VREL_GT, + VREL_UNDEFINED, VREL_NE } }; // Intersect relation R1 with relation R2 and return the resulting relation. @@ -117,65 +105,75 @@ relation_kind rr_intersect_table[VREL_COUNT][VREL_COUNT] = { relation_kind relation_intersect (relation_kind r1, relation_kind r2) { - vrel_range_assert (r1); - vrel_range_assert (r2); - return rr_intersect_table[r1 - VREL_FIRST][r2 - VREL_FIRST]; + return rr_intersect_table[r1][r2]; } // This table is used to perform a union between 2 relations. -relation_kind rr_union_table[VREL_COUNT][VREL_COUNT] = { -// NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EMPTY, EQ_EXPR, NE_EXPR -// VREL_NONE - { VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE }, -// LT_EXPR - { VREL_NONE, LT_EXPR, LE_EXPR, NE_EXPR, VREL_NONE, LT_EXPR, LE_EXPR, NE_EXPR }, -// LE_EXPR - { VREL_NONE, LE_EXPR, LE_EXPR, VREL_NONE, VREL_NONE, LE_EXPR, LE_EXPR, VREL_NONE }, -// GT_EXPR - { VREL_NONE, NE_EXPR, VREL_NONE, GT_EXPR, GE_EXPR, GT_EXPR, GE_EXPR, NE_EXPR }, -// GE_EXPR - { VREL_NONE, VREL_NONE, VREL_NONE, GE_EXPR, GE_EXPR, GE_EXPR, GE_EXPR, VREL_NONE }, -// VREL_EMPTY - { VREL_NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, VREL_EMPTY, EQ_EXPR, NE_EXPR }, -// EQ_EXPR - { VREL_NONE, LE_EXPR, LE_EXPR, GE_EXPR, GE_EXPR, EQ_EXPR, EQ_EXPR, VREL_NONE }, -// NE_EXPR - { VREL_NONE, NE_EXPR, VREL_NONE, NE_EXPR, VREL_NONE, NE_EXPR, VREL_NONE, NE_EXPR } }; +relation_kind rr_union_table[VREL_LAST + 1][VREL_LAST + 1] = { +// VREL_VARYING + { VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, + VREL_VARYING, VREL_VARYING, VREL_VARYING }, +// VREL_UNDEFINED + { VREL_VARYING, VREL_LT, VREL_LE, VREL_GT, VREL_GE, VREL_UNDEFINED, + VREL_EQ, VREL_NE }, +// VREL_LT + { VREL_VARYING, VREL_LT, VREL_LT, VREL_LE, VREL_NE, VREL_VARYING, VREL_LE, + VREL_NE }, +// VREL_LE + { VREL_VARYING, VREL_LE, VREL_LE, VREL_LE, VREL_VARYING, VREL_VARYING, + VREL_LE, VREL_VARYING }, +// VREL_GT + { VREL_VARYING, VREL_GT, VREL_NE, VREL_VARYING, VREL_GT, VREL_GE, VREL_GE, + VREL_NE }, +// VREL_GE + { VREL_VARYING, VREL_GE, VREL_VARYING, VREL_VARYING, VREL_GE, VREL_GE, + VREL_GE, VREL_VARYING }, +// VREL_EQ + { VREL_VARYING, VREL_EQ, VREL_LE, VREL_LE, VREL_GE, VREL_GE, VREL_EQ, + VREL_VARYING }, +// VREL_NE + { VREL_VARYING, VREL_NE, VREL_NE, VREL_VARYING, VREL_NE, VREL_VARYING, + VREL_VARYING, VREL_NE } }; // Union relation R1 with relation R2 and return the result. relation_kind relation_union (relation_kind r1, relation_kind r2) { - vrel_range_assert (r1); - vrel_range_assert (r2); - return rr_union_table[r1 - VREL_FIRST][r2 - VREL_FIRST]; + return rr_union_table[r1][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_COUNT][VREL_COUNT] = { -// NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EMPTY, EQ_EXPR, NE_EXPR -// VREL_NONE - { VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE }, -// LT_EXPR - { VREL_NONE, LT_EXPR, LT_EXPR, VREL_NONE, VREL_NONE, VREL_NONE, LT_EXPR, VREL_NONE }, -// LE_EXPR - { VREL_NONE, LT_EXPR, LE_EXPR, VREL_NONE, VREL_NONE, VREL_NONE, LE_EXPR, VREL_NONE }, -// GT_EXPR - { VREL_NONE, VREL_NONE, VREL_NONE, GT_EXPR, GT_EXPR, VREL_NONE, GT_EXPR, VREL_NONE }, -// GE_EXPR - { VREL_NONE, VREL_NONE, VREL_NONE, GT_EXPR, GE_EXPR, VREL_NONE, GE_EXPR, VREL_NONE }, -// VREL_EMPTY - { VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE }, -// EQ_EXPR - { VREL_NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, VREL_NONE, EQ_EXPR, VREL_NONE }, -// NE_EXPR - { VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE, VREL_NONE } }; +relation_kind rr_transitive_table[VREL_LAST + 1][VREL_LAST + 1] = { +// VREL_VARYING + { VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, + VREL_VARYING, VREL_VARYING, VREL_VARYING }, +// VREL_UNDEFINED + { VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, + VREL_VARYING, VREL_VARYING, VREL_VARYING }, +// VREL_LT + { VREL_VARYING, VREL_VARYING, VREL_LT, VREL_LT, VREL_VARYING, VREL_VARYING, + VREL_LT, VREL_VARYING }, +// VREL_LE + { VREL_VARYING, VREL_VARYING, VREL_LT, VREL_LE, VREL_VARYING, VREL_VARYING, + VREL_LE, VREL_VARYING }, +// VREL_GT + { VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_GT, VREL_GT, + VREL_GT, VREL_VARYING }, +// VREL_GE + { VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_GT, VREL_GE, + VREL_GE, VREL_VARYING }, +// VREL_EQ + { VREL_VARYING, VREL_VARYING, VREL_LT, VREL_LE, VREL_GT, VREL_GE, VREL_EQ, + VREL_VARYING }, +// VREL_NE + { VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, + VREL_VARYING, VREL_VARYING, VREL_VARYING } }; // Apply transitive operation between relation R1 and relation R2, and // return the resulting relation, if any. @@ -183,9 +181,7 @@ relation_kind rr_transitive_table[VREL_COUNT][VREL_COUNT] = { relation_kind relation_transitive (relation_kind r1, relation_kind r2) { - vrel_range_assert (r1); - vrel_range_assert (r2); - return rr_transitive_table[r1 - VREL_FIRST][r2 - VREL_FIRST]; + return rr_transitive_table[r1][r2]; } // Given an equivalence set EQUIV, set all the bits in B that are still valid @@ -311,8 +307,8 @@ equiv_oracle::query_relation (basic_block bb, tree ssa1, tree ssa2) { // If the 2 ssa names share the same equiv set, they are equal. if (equiv_set (ssa1, bb) == equiv_set (ssa2, bb)) - return EQ_EXPR; - return VREL_NONE; + return VREL_EQ; + return VREL_VARYING; } // Query if thre is a relation (equivalence) between 2 SSA_NAMEs. @@ -323,8 +319,8 @@ equiv_oracle::query_relation (basic_block bb ATTRIBUTE_UNUSED, const_bitmap e1, { // If the 2 ssa names share the same equiv set, they are equal. if (bitmap_equal_p (e1, e2)) - return EQ_EXPR; - return VREL_NONE; + return VREL_EQ; + return VREL_VARYING; } // If SSA has an equivalence in block BB, find and return it. @@ -455,7 +451,7 @@ equiv_oracle::register_relation (basic_block bb, relation_kind k, tree ssa1, tree ssa2) { // Only handle equality relations. - if (k != EQ_EXPR) + if (k != VREL_EQ) return; unsigned v1 = SSA_NAME_VERSION (ssa1); @@ -617,7 +613,7 @@ value_relation::set_relation (relation_kind r, tree n1, tree n2) inline value_relation::value_relation () { - related = VREL_NONE; + related = VREL_VARYING; name1 = NULL_TREE; name2 = NULL_TREE; } @@ -680,7 +676,7 @@ value_relation::union_ (value_relation &p) bool value_relation::apply_transitive (const value_relation &rel) { - relation_kind k = VREL_NONE; + relation_kind k = VREL_VARYING; // Idenity any common operand, and notrmalize the relations to // the form : A < B B < C produces A < C @@ -690,7 +686,7 @@ value_relation::apply_transitive (const value_relation &rel) if (rel.op2 () == name1) return false; k = relation_transitive (kind (), rel.kind ()); - if (k != VREL_NONE) + if (k != VREL_VARYING) { related = k; name2 = rel.op2 (); @@ -703,7 +699,7 @@ value_relation::apply_transitive (const value_relation &rel) if (rel.op2 () == name2) return false; k = relation_transitive (relation_swap (kind ()), rel.kind ()); - if (k != VREL_NONE) + if (k != VREL_VARYING) { related = k; name1 = name2; @@ -717,7 +713,7 @@ value_relation::apply_transitive (const value_relation &rel) if (rel.op1 () == name1) return false; k = relation_transitive (kind (), relation_swap (rel.kind ())); - if (k != VREL_NONE) + if (k != VREL_VARYING) { related = k; name2 = rel.op1 (); @@ -731,7 +727,7 @@ value_relation::apply_transitive (const value_relation &rel) return false; k = relation_transitive (relation_swap (kind ()), relation_swap (rel.kind ())); - if (k != VREL_NONE) + if (k != VREL_VARYING) { related = k; name1 = name2; @@ -776,11 +772,11 @@ relation_kind relation_chain_head::find_relation (const_bitmap b1, const_bitmap b2) const { if (!m_names) - return VREL_NONE; + return VREL_VARYING; // If both b1 and b2 aren't referenced in thie block, cant be a relation if (!bitmap_intersect_p (m_names, b1) || !bitmap_intersect_p (m_names, b2)) - return VREL_NONE; + return VREL_VARYING; // Search for the fiorst relation that contains BOTH an element from B1 // and B2, and return that relation. @@ -794,7 +790,7 @@ relation_chain_head::find_relation (const_bitmap b1, const_bitmap b2) const return relation_swap (ptr->kind ()); } - return VREL_NONE; + return VREL_VARYING; } // Instantiate a relation oracle. @@ -826,7 +822,7 @@ relation_oracle::register_stmt (gimple *stmt, relation_kind k, tree op1, gcc_checking_assert (stmt && gimple_bb (stmt)); // Don't register lack of a relation. - if (k == VREL_NONE) + if (k == VREL_VARYING) return; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -842,7 +838,7 @@ relation_oracle::register_stmt (gimple *stmt, relation_kind k, tree op1, // make sure that that argument is not defined in the same block. // This can happen along back edges and the equivalence will not be // applicable as it would require a use before def. - if (k == EQ_EXPR && is_a<gphi *> (stmt)) + if (k == VREL_EQ && is_a<gphi *> (stmt)) { tree phi_def = gimple_phi_result (stmt); gcc_checking_assert (phi_def == op1 || phi_def == op2); @@ -873,7 +869,7 @@ relation_oracle::register_edge (edge e, relation_kind k, tree op1, tree op2) // Do not register lack of relation, or blocks which have more than // edge E for a predecessor. - if (k == VREL_NONE || !single_pred_p (e->dest)) + if (k == VREL_VARYING || !single_pred_p (e->dest)) return; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -901,7 +897,7 @@ dom_oracle::register_relation (basic_block bb, relation_kind k, tree op1, return; // Equivalencies are handled by the equivalence oracle. - if (k == EQ_EXPR) + if (k == VREL_EQ) equiv_oracle::register_relation (bb, k, op1, op2); else { @@ -919,7 +915,7 @@ relation_chain * dom_oracle::set_one_relation (basic_block bb, relation_kind k, tree op1, tree op2) { - gcc_checking_assert (k != VREL_NONE && k != EQ_EXPR); + gcc_checking_assert (k != VREL_VARYING && k != VREL_EQ); value_relation vr(k, op1, op2); int bbi = bb->index; @@ -938,7 +934,7 @@ dom_oracle::set_one_relation (basic_block bb, relation_kind k, tree op1, relation_chain *ptr; curr = find_relation_block (bbi, v1, v2, &ptr); // There is an existing relation in this block, just intersect with it. - if (curr != VREL_NONE) + if (curr != VREL_VARYING) { if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -969,7 +965,7 @@ dom_oracle::set_one_relation (basic_block bb, relation_kind k, tree op1, // By including dominating relations, The first one found in any search // will be the aggregate of all the previous ones. curr = find_relation_dom (bb, v1, v2); - if (curr != VREL_NONE) + if (curr != VREL_VARYING) k = relation_intersect (curr, k); bitmap_set_bit (bm, v1); @@ -999,10 +995,10 @@ dom_oracle::register_transitives (basic_block root_bb, // Only apply transitives to certain kinds of operations. switch (relation.kind ()) { - case LE_EXPR: - case LT_EXPR: - case GT_EXPR: - case GE_EXPR: + case VREL_LE: + case VREL_LT: + case VREL_GT: + case VREL_GE: break; default: return; @@ -1087,7 +1083,7 @@ dom_oracle::find_relation_block (unsigned bb, const_bitmap b1, const_bitmap b2) const { if (bb >= m_relations.length()) - return VREL_NONE; + return VREL_VARYING; return m_relations[bb].find_relation (b1, b2); } @@ -1101,21 +1097,21 @@ dom_oracle::query_relation (basic_block bb, const_bitmap b1, { relation_kind r; if (bitmap_equal_p (b1, b2)) - return EQ_EXPR; + return VREL_EQ; // If either name does not occur in a relation anywhere, there isnt one. if (!bitmap_intersect_p (m_relation_set, b1) || !bitmap_intersect_p (m_relation_set, b2)) - return VREL_NONE; + return VREL_VARYING; // Search each block in the DOM tree checking. for ( ; bb; bb = get_immediate_dominator (CDI_DOMINATORS, bb)) { r = find_relation_block (bb->index, b1, b2); - if (r != VREL_NONE) + if (r != VREL_VARYING) return r; } - return VREL_NONE; + return VREL_VARYING; } @@ -1127,15 +1123,15 @@ dom_oracle::find_relation_block (int bb, unsigned v1, unsigned v2, relation_chain **obj) const { if (bb >= (int)m_relations.length()) - return VREL_NONE; + return VREL_VARYING; const_bitmap bm = m_relations[bb].m_names; if (!bm) - return VREL_NONE; + return VREL_VARYING; // If both b1 and b2 aren't referenced in thie block, cant be a relation if (!bitmap_bit_p (bm, v1) || !bitmap_bit_p (bm, v2)) - return VREL_NONE; + return VREL_VARYING; relation_chain *ptr; for (ptr = m_relations[bb].m_head; ptr ; ptr = ptr->m_next) @@ -1156,7 +1152,7 @@ dom_oracle::find_relation_block (int bb, unsigned v1, unsigned v2, } } - return VREL_NONE; + return VREL_VARYING; } // Find a relation between SSA version V1 and V2 in the dominator tree @@ -1168,15 +1164,15 @@ dom_oracle::find_relation_dom (basic_block bb, unsigned v1, unsigned v2) const relation_kind r; // IF either name does not occur in a relation anywhere, there isnt one. if (!bitmap_bit_p (m_relation_set, v1) || !bitmap_bit_p (m_relation_set, v2)) - return VREL_NONE; + return VREL_VARYING; for ( ; bb; bb = get_immediate_dominator (CDI_DOMINATORS, bb)) { r = find_relation_block (bb->index, v1, v2); - if (r != VREL_NONE) + if (r != VREL_VARYING) return r; } - return VREL_NONE; + return VREL_VARYING; } @@ -1190,17 +1186,17 @@ dom_oracle::query_relation (basic_block bb, tree ssa1, tree ssa2) unsigned v1 = SSA_NAME_VERSION (ssa1); unsigned v2 = SSA_NAME_VERSION (ssa2); if (v1 == v2) - return EQ_EXPR; + return VREL_EQ; // Check for equivalence first. They must be in each equivalency set. const_bitmap equiv1 = equiv_set (ssa1, bb); const_bitmap equiv2 = equiv_set (ssa2, bb); if (bitmap_bit_p (equiv1, v2) && bitmap_bit_p (equiv2, v1)) - return EQ_EXPR; + return VREL_EQ; // Initially look for a direct relationship and just return that. kind = find_relation_dom (bb, v1, v2); - if (kind != VREL_NONE) + if (kind != VREL_VARYING) return kind; // Query using the equiovalence sets. @@ -1388,14 +1384,14 @@ path_oracle::register_relation (basic_block bb, relation_kind k, tree ssa1, fprintf (dump_file, " (root: bb%d)\n", bb->index); } - if (k == EQ_EXPR) + if (k == VREL_EQ) { register_equiv (bb, ssa1, ssa2); return; } relation_kind curr = query_relation (bb, ssa1, ssa2); - if (curr != VREL_NONE) + if (curr != VREL_VARYING) k = relation_intersect (curr, k); bitmap_set_bit (m_relations.m_names, SSA_NAME_VERSION (ssa1)); @@ -1414,7 +1410,7 @@ relation_kind path_oracle::query_relation (basic_block bb, const_bitmap b1, const_bitmap b2) { if (bitmap_equal_p (b1, b2)) - return EQ_EXPR; + return VREL_EQ; relation_kind k = m_relations.find_relation (b1, b2); @@ -1424,7 +1420,7 @@ path_oracle::query_relation (basic_block bb, const_bitmap b1, const_bitmap b2) || bitmap_intersect_p (m_killed_defs, b2)) return k; - if (k == VREL_NONE && m_root) + if (k == VREL_VARYING && m_root) k = m_root->query_relation (bb, b1, b2); return k; @@ -1440,12 +1436,12 @@ path_oracle::query_relation (basic_block bb, tree ssa1, tree ssa2) unsigned v2 = SSA_NAME_VERSION (ssa2); if (v1 == v2) - return EQ_EXPR; + return VREL_EQ; const_bitmap equiv_1 = equiv_set (ssa1, bb); const_bitmap equiv_2 = equiv_set (ssa2, bb); if (bitmap_bit_p (equiv_1, v2) && bitmap_bit_p (equiv_2, v1)) - return EQ_EXPR; + return VREL_EQ; return query_relation (bb, equiv_1, equiv_2); } diff --git a/gcc/value-relation.h b/gcc/value-relation.h index 36e4cf9..19762d8 100644 --- a/gcc/value-relation.h +++ b/gcc/value-relation.h @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see // The general range_query object provided in value-query.h provides // access to an oracle, if one is available, via the oracle() method. // Thre are also a couple of access routines provided, which even if there is -// no oracle, will return the default VREL_NONE no relation. +// no oracle, will return the default VREL_VARYING no relation. // // Typically, when a ranger object is active, there will be an oracle, and // any information available can be directly queried. Ranger also sets and @@ -43,8 +43,8 @@ along with GCC; see the file COPYING3. If not see // 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_NONE : No relation between the 2 names. -// VREL_EMPTY : Impossible relation (ie, A < B && A > B produces VREL_EMPTY. +// 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 @@ -58,13 +58,20 @@ along with GCC; see the file COPYING3. If not see // 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_NONE is the first -// code, and all the rest are contiguous. +// the other cases. These codes are arranged such that VREL_VARYING is the +// first code, and all the rest are contiguous. -typedef enum tree_code relation_kind; - -#define VREL_NONE TRUTH_NOT_EXPR -#define VREL_EMPTY LTGT_EXPR +typedef enum relation_kind_t +{ + VREL_VARYING = 0, // No known relation, AKA varying. + VREL_UNDEFINED, // Impossible relation, ie (r1 < r2) && (r2 > r1) + VREL_LT, // r1 < r2 + VREL_LE, // r1 <= r2 + VREL_GT, // r1 > r2 + VREL_GE, // r1 >= r2 + VREL_EQ, // r1 == r2 + VREL_NE // r1 != r2 +} relation_kind; // General relation kind transformations. relation_kind relation_union (relation_kind r1, relation_kind r2); @@ -73,7 +80,6 @@ relation_kind relation_negate (relation_kind r); relation_kind relation_swap (relation_kind r); void print_relation (FILE *f, relation_kind rel); - class relation_oracle { public: |