diff options
Diffstat (limited to 'gcc/value-range.h')
-rw-r--r-- | gcc/value-range.h | 79 |
1 files changed, 49 insertions, 30 deletions
diff --git a/gcc/value-range.h b/gcc/value-range.h index d166362..484f911 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -215,7 +215,7 @@ private: bool intersect (const wide_int& lb, const wide_int& ub); unsigned char m_num_ranges; unsigned char m_max_ranges; - wide_int m_nonzero_mask; + tree m_nonzero_mask; tree *m_base; }; @@ -683,11 +683,11 @@ irange::varying_compatible_p () const if (INTEGRAL_TYPE_P (t)) return (wi::to_wide (l) == wi::min_value (prec, sign) && wi::to_wide (u) == wi::max_value (prec, sign) - && m_nonzero_mask == -1); + && (!m_nonzero_mask || wi::to_wide (m_nonzero_mask) == -1)); if (POINTER_TYPE_P (t)) return (wi::to_wide (l) == 0 && wi::to_wide (u) == wi::max_value (prec, sign) - && m_nonzero_mask == -1); + && (!m_nonzero_mask || wi::to_wide (m_nonzero_mask) == -1)); return true; } @@ -754,6 +754,8 @@ gt_ggc_mx (irange *x) gt_ggc_mx (x->m_base[i * 2]); gt_ggc_mx (x->m_base[i * 2 + 1]); } + if (x->m_nonzero_mask) + gt_ggc_mx (x->m_nonzero_mask); } inline void @@ -764,6 +766,8 @@ gt_pch_nx (irange *x) gt_pch_nx (x->m_base[i * 2]); gt_pch_nx (x->m_base[i * 2 + 1]); } + if (x->m_nonzero_mask) + gt_pch_nx (x->m_nonzero_mask); } inline void @@ -774,6 +778,8 @@ gt_pch_nx (irange *x, gt_pointer_operator op, void *cookie) op (&x->m_base[i * 2], NULL, cookie); op (&x->m_base[i * 2 + 1], NULL, cookie); } + if (x->m_nonzero_mask) + op (&x->m_nonzero_mask, NULL, cookie); } template<unsigned N> @@ -868,6 +874,7 @@ irange::set_undefined () { m_kind = VR_UNDEFINED; m_num_ranges = 0; + m_nonzero_mask = NULL; } inline void @@ -875,11 +882,7 @@ irange::set_varying (tree type) { m_kind = VR_VARYING; m_num_ranges = 1; - - if (type == error_mark_node) - m_nonzero_mask = wi::shwi (-1, 1); - else - m_nonzero_mask = wi::shwi (-1, TYPE_PRECISION (type)); + m_nonzero_mask = NULL; if (INTEGRAL_TYPE_P (type)) { @@ -1111,11 +1114,14 @@ inline void frange::update_nan () { gcc_checking_assert (!undefined_p ()); - m_pos_nan = true; - m_neg_nan = true; - normalize_kind (); - if (flag_checking) - verify_range (); + if (HONOR_NANS (m_type)) + { + m_pos_nan = true; + m_neg_nan = true; + normalize_kind (); + if (flag_checking) + verify_range (); + } } // Like above, but set the sign of the NAN. @@ -1124,11 +1130,14 @@ inline void frange::update_nan (bool sign) { gcc_checking_assert (!undefined_p ()); - m_pos_nan = !sign; - m_neg_nan = sign; - normalize_kind (); - if (flag_checking) - verify_range (); + if (HONOR_NANS (m_type)) + { + m_pos_nan = !sign; + m_neg_nan = sign; + normalize_kind (); + if (flag_checking) + verify_range (); + } } // Clear the NAN bit and adjust the range. @@ -1213,12 +1222,17 @@ frange_val_is_max (const REAL_VALUE_TYPE &r, const_tree type) inline void frange::set_nan (tree type) { - m_kind = VR_NAN; - m_type = type; - m_pos_nan = true; - m_neg_nan = true; - if (flag_checking) - verify_range (); + if (HONOR_NANS (type)) + { + m_kind = VR_NAN; + m_type = type; + m_pos_nan = true; + m_neg_nan = true; + if (flag_checking) + verify_range (); + } + else + set_undefined (); } // Build a NAN of type TYPE with SIGN. @@ -1226,12 +1240,17 @@ frange::set_nan (tree type) inline void frange::set_nan (tree type, bool sign) { - m_kind = VR_NAN; - m_type = type; - m_neg_nan = sign; - m_pos_nan = !sign; - if (flag_checking) - verify_range (); + if (HONOR_NANS (type)) + { + m_kind = VR_NAN; + m_type = type; + m_neg_nan = sign; + m_pos_nan = !sign; + if (flag_checking) + verify_range (); + } + else + set_undefined (); } // Return TRUE if range is known to be finite. |