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