diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2019-08-16 06:54:23 +0000 |
---|---|---|
committer | Aldy Hernandez <aldyh@gcc.gnu.org> | 2019-08-16 06:54:23 +0000 |
commit | 97ecc8d5769e947e8659d32be51846d40c90f50c (patch) | |
tree | 7451af2bf9f9c04582fba7f75cfc275b2619ddbb /gcc/tree-vrp.c | |
parent | e3cfbeaf6b655b9c00d77efb8220a8a16341cb2e (diff) | |
download | gcc-97ecc8d5769e947e8659d32be51846d40c90f50c.zip gcc-97ecc8d5769e947e8659d32be51846d40c90f50c.tar.gz gcc-97ecc8d5769e947e8659d32be51846d40c90f50c.tar.bz2 |
Add type to VR_VARYING.
From-SVN: r274561
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 142 |
1 files changed, 93 insertions, 49 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 77e7594..8067f85 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -186,9 +186,11 @@ value_range_base::check () break; } case VR_UNDEFINED: - case VR_VARYING: gcc_assert (!min () && !max ()); break; + case VR_VARYING: + gcc_assert (m_min && m_max); + break; default: gcc_unreachable (); } @@ -214,6 +216,10 @@ value_range::check () bool value_range_base::equal_p (const value_range_base &other) const { + /* Ignore types for undefined. All undefines are equal. */ + if (undefined_p ()) + return m_kind == other.m_kind; + return (m_kind == other.m_kind && vrp_operand_equal_p (m_min, other.m_min) && vrp_operand_equal_p (m_max, other.m_max)); @@ -269,16 +275,24 @@ value_range::set_undefined () } void -value_range_base::set_varying () +value_range_base::set_varying (tree type) { m_kind = VR_VARYING; - m_min = m_max = NULL; + if (supports_type_p (type)) + { + m_min = vrp_val_min (type, true); + m_max = vrp_val_max (type, true); + } + else + /* We can't do anything range-wise with these types. */ + m_min = m_max = error_mark_node; } void -value_range::set_varying () +value_range::set_varying (tree type) { - set (VR_VARYING, NULL, NULL, NULL); + value_range_base::set_varying (type); + equiv_clear (); } /* Return TRUE if it is possible that range contains VAL. */ @@ -355,9 +369,7 @@ value_range_base::singleton_p (tree *result) const tree value_range_base::type () const { - /* Types are only valid for VR_RANGE and VR_ANTI_RANGE, which are - known to have non-zero min/max. */ - gcc_assert (min ()); + gcc_assert (m_min || undefined_p ()); return TREE_TYPE (min ()); } @@ -395,12 +407,21 @@ value_range_base::dump (FILE *file) const fprintf (file, "]"); } else if (varying_p ()) - fprintf (file, "VARYING"); + { + print_generic_expr (file, type ()); + fprintf (file, " VARYING"); + } else gcc_unreachable (); } void +value_range_base::dump () const +{ + dump (stderr); +} + +void value_range::dump (FILE *file) const { value_range_base::dump (file); @@ -424,6 +445,12 @@ value_range::dump (FILE *file) const } void +value_range::dump () const +{ + dump (stderr); +} + +void dump_value_range (FILE *file, const value_range *vr) { if (!vr) @@ -658,7 +685,14 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max) } else if (kind == VR_VARYING) { - set_varying (); + gcc_assert (TREE_TYPE (min) == TREE_TYPE (max)); + tree typ = TREE_TYPE (min); + if (supports_type_p (typ)) + { + gcc_assert (vrp_val_min (typ, true)); + gcc_assert (vrp_val_max (typ, true)); + } + set_varying (typ); return; } @@ -683,7 +717,7 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max) for VR_ANTI_RANGE empty range, so drop to varying as well. */ if (TYPE_PRECISION (TREE_TYPE (min)) == 1) { - set_varying (); + set_varying (TREE_TYPE (min)); return; } @@ -697,7 +731,7 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max) to varying in this case. */ if (tree_int_cst_lt (max, min)) { - set_varying (); + set_varying (TREE_TYPE (min)); return; } @@ -720,7 +754,7 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max) { /* We cannot deal with empty ranges, drop to varying. ??? This could be VR_UNDEFINED instead. */ - set_varying (); + set_varying (type); return; } else if (TYPE_PRECISION (TREE_TYPE (min)) == 1 @@ -767,7 +801,7 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max) && wi::eq_p (wi::to_wide (max), wi::max_value (prec, sign))) { if (kind == VR_RANGE) - set_varying (); + set_varying (type); else if (kind == VR_ANTI_RANGE) set_undefined (); else @@ -1297,7 +1331,7 @@ extract_range_from_multiplicative_op (value_range_base *vr, || code == LSHIFT_EXPR); if (!range_int_cst_p (vr1)) { - vr->set_varying (); + vr->set_varying (type); return; } @@ -1332,7 +1366,7 @@ extract_range_from_multiplicative_op (value_range_base *vr, vr->set (VR_RANGE, wide_int_to_tree (type, res_lb), wide_int_to_tree (type, res_ub)); else - vr->set_varying (); + vr->set_varying (type); } /* If BOUND will include a symbolic bound, adjust it accordingly, @@ -1541,7 +1575,7 @@ extract_range_from_binary_expr (value_range_base *vr, if (!INTEGRAL_TYPE_P (expr_type) && !POINTER_TYPE_P (expr_type)) { - vr->set_varying (); + vr->set_varying (expr_type); return; } @@ -1565,7 +1599,7 @@ extract_range_from_binary_expr (value_range_base *vr, && code != BIT_IOR_EXPR && code != BIT_XOR_EXPR) { - vr->set_varying (); + vr->set_varying (expr_type); return; } @@ -1580,9 +1614,9 @@ extract_range_from_binary_expr (value_range_base *vr, have UNDEFINED result for all or some value-ranges of the not UNDEFINED operand. */ else if (vr0.undefined_p ()) - vr0.set_varying (); + vr0.set_varying (expr_type); else if (vr1.undefined_p ()) - vr1.set_varying (); + vr1.set_varying (expr_type); /* We get imprecise results from ranges_from_anti_range when code is EXACT_DIV_EXPR. We could mask out bits in the resulting @@ -1654,7 +1688,7 @@ extract_range_from_binary_expr (value_range_base *vr, || vr0.symbolic_p () || vr1.symbolic_p ())) { - vr->set_varying (); + vr->set_varying (expr_type); return; } @@ -1672,7 +1706,7 @@ extract_range_from_binary_expr (value_range_base *vr, else if (vr0.zero_p () && vr1.zero_p ()) vr->set_zero (expr_type); else - vr->set_varying (); + vr->set_varying (expr_type); } else if (code == POINTER_PLUS_EXPR) { @@ -1701,7 +1735,7 @@ extract_range_from_binary_expr (value_range_base *vr, else if (vr0.zero_p () && vr1.zero_p ()) vr->set_zero (expr_type); else - vr->set_varying (); + vr->set_varying (expr_type); } else if (code == BIT_AND_EXPR) { @@ -1712,10 +1746,10 @@ extract_range_from_binary_expr (value_range_base *vr, else if (vr0.zero_p () || vr1.zero_p ()) vr->set_zero (expr_type); else - vr->set_varying (); + vr->set_varying (expr_type); } else - vr->set_varying (); + vr->set_varying (expr_type); return; } @@ -1793,7 +1827,7 @@ extract_range_from_binary_expr (value_range_base *vr, if (((bool)min_ovf && sym_min_op0 != sym_min_op1) || ((bool)max_ovf && sym_max_op0 != sym_max_op1)) { - vr->set_varying (); + vr->set_varying (expr_type); return; } @@ -1804,7 +1838,7 @@ extract_range_from_binary_expr (value_range_base *vr, wmin, wmax, min_ovf, max_ovf); if (type == VR_VARYING) { - vr->set_varying (); + vr->set_varying (expr_type); return; } @@ -1830,7 +1864,7 @@ extract_range_from_binary_expr (value_range_base *vr, a single range or anti-range as the above is [-INF+1, +INF(OVF)] intersected with ~[5, 5] but one could use a scheme similar to equivalences for this. */ - vr->set_varying (); + vr->set_varying (expr_type); return; } } @@ -1847,7 +1881,7 @@ extract_range_from_binary_expr (value_range_base *vr, vr->set (VR_RANGE, wide_int_to_tree (expr_type, wmin), wide_int_to_tree (expr_type, wmax)); else - vr->set_varying (); + vr->set_varying (expr_type); return; } else if (code == MULT_EXPR) @@ -1855,7 +1889,7 @@ extract_range_from_binary_expr (value_range_base *vr, if (!range_int_cst_p (&vr0) || !range_int_cst_p (&vr1)) { - vr->set_varying (); + vr->set_varying (expr_type); return; } extract_range_from_multiplicative_op (vr, code, expr_type, &vr0, &vr1); @@ -1895,7 +1929,7 @@ extract_range_from_binary_expr (value_range_base *vr, } } } - vr->set_varying (); + vr->set_varying (expr_type); return; } else if (code == TRUNC_DIV_EXPR @@ -1932,7 +1966,7 @@ extract_range_from_binary_expr (value_range_base *vr, TYPE_OVERFLOW_UNDEFINED (expr_type), extra_range_p, extra_min, extra_max)) { - vr->set_varying (); + vr->set_varying (expr_type); return; } vr->set (VR_RANGE, wide_int_to_tree (expr_type, wmin), @@ -1991,7 +2025,7 @@ extract_range_from_binary_expr (value_range_base *vr, vr->set (VR_RANGE, min, max); } else - vr->set_varying (); + vr->set_varying (expr_type); return; } else if (code == BIT_IOR_EXPR) @@ -2009,7 +2043,7 @@ extract_range_from_binary_expr (value_range_base *vr, vr->set (VR_RANGE, min, max); } else - vr->set_varying (); + vr->set_varying (expr_type); return; } else if (code == BIT_XOR_EXPR) @@ -2025,7 +2059,7 @@ extract_range_from_binary_expr (value_range_base *vr, vr->set (VR_RANGE, min, max); } else - vr->set_varying (); + vr->set_varying (expr_type); return; } } @@ -2039,7 +2073,7 @@ extract_range_from_binary_expr (value_range_base *vr, || max == NULL_TREE || TREE_OVERFLOW_P (max)) { - vr->set_varying (); + vr->set_varying (expr_type); return; } @@ -2048,7 +2082,7 @@ extract_range_from_binary_expr (value_range_base *vr, Note that we do accept [-INF, -INF] and [+INF, +INF]. */ if (vrp_val_is_min (min) && vrp_val_is_max (max)) { - vr->set_varying (); + vr->set_varying (expr_type); return; } @@ -2058,7 +2092,7 @@ extract_range_from_binary_expr (value_range_base *vr, /* If the new range has its limits swapped around (MIN > MAX), then the operation caused one of them to wrap around, mark the new range VARYING. */ - vr->set_varying (); + vr->set_varying (expr_type); } else vr->set (type, min, max); @@ -2084,7 +2118,7 @@ extract_range_from_unary_expr (value_range_base *vr, || !(INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))) { - vr->set_varying (); + vr->set_varying (type); return; } @@ -2156,7 +2190,7 @@ extract_range_from_unary_expr (value_range_base *vr, else if (vr0.zero_p ()) vr->set_zero (type); else - vr->set_varying (); + vr->set_varying (type); return; } @@ -2190,7 +2224,7 @@ extract_range_from_unary_expr (value_range_base *vr, vr->set (VR_RANGE, min, max); } else - vr->set_varying (); + vr->set_varying (outer_type); return; } else if (code == ABS_EXPR) @@ -2203,7 +2237,7 @@ extract_range_from_unary_expr (value_range_base *vr, vr->set (VR_RANGE, wide_int_to_tree (type, wmin), wide_int_to_tree (type, wmax)); else - vr->set_varying (); + vr->set_varying (type); return; } else if (code == ABSU_EXPR) @@ -2219,7 +2253,7 @@ extract_range_from_unary_expr (value_range_base *vr, } /* For unhandled operations fall back to varying. */ - vr->set_varying (); + vr->set_varying (type); return; } @@ -6100,7 +6134,12 @@ value_range_base::intersect_helper (const value_range_base *vr0, VR_RANGE can still be a VR_RANGE. Work on a temporary so we can fall back to vr0 when this turns things to varying. */ value_range_base tem; - tem.set (vr0type, vr0min, vr0max); + if (vr0type == VR_UNDEFINED) + tem.set_undefined (); + else if (vr0type == VR_VARYING) + tem.set_varying (vr0->type ()); + else + tem.set (vr0type, vr0min, vr0max); /* If that failed, use the saved original VR0. */ if (tem.varying_p ()) return *vr0; @@ -6205,7 +6244,12 @@ value_range_base::union_helper (const value_range_base *vr0, /* Work on a temporary so we can still use vr0 when union returns varying. */ value_range_base tem; - tem.set (vr0type, vr0min, vr0max); + if (vr0type == VR_UNDEFINED) + tem.set_undefined (); + else if (vr0type == VR_VARYING) + tem.set_varying (vr0->type ()); + else + tem.set (vr0type, vr0min, vr0max); /* Failed to find an efficient meet. Before giving up and setting the result to VARYING, see if we can at least derive a useful @@ -6302,7 +6346,7 @@ value_range_base::normalize_symbolics () const if (min_symbolic && max_symbolic) { value_range_base var; - var.set_varying (); + var.set_varying (ttype); return var; } if (kind () == VR_RANGE) @@ -6323,7 +6367,7 @@ value_range_base::normalize_symbolics () const return value_range_base (VR_RANGE, n, vrp_val_max (ttype)); } value_range_base var; - var.set_varying (); + var.set_varying (ttype); return var; } // ~[NUM, SYM] -> [-MIN, NUM - 1] @@ -6333,7 +6377,7 @@ value_range_base::normalize_symbolics () const return value_range_base (VR_RANGE, vrp_val_min (ttype), n); } value_range_base var; - var.set_varying (); + var.set_varying (ttype); return var; } @@ -7010,7 +7054,7 @@ determine_value_range_1 (value_range_base *vr, tree expr) vr->set (kind, wide_int_to_tree (TREE_TYPE (expr), min), wide_int_to_tree (TREE_TYPE (expr), max)); else - vr->set_varying (); + vr->set_varying (TREE_TYPE (expr)); } } |