gcc/ChangeLog: * value-range.cc (get_bound_with_infinite_markers): New static helper. (irange::as_string): New definition. * value-range.h: New declaration.
--- Provide means to print a value range to a newly allocated buffer. The caller is responsible to free() the allocated memory. Bootstrapped and regtested on x86_86-unknown-linux with no regressions. Ok for trunk? Cc: Andrew MacLeod <amacl...@redhat.com> Cc: Aldy Hernandez <al...@redhat.com> --- gcc/value-range.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++ gcc/value-range.h | 3 +++ 2 files changed, 59 insertions(+) diff --git a/gcc/value-range.cc b/gcc/value-range.cc index a855aaf626c..51cd9a38d90 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -3099,6 +3099,62 @@ debug (const value_range &vr) fprintf (stderr, "\n"); } +/* Helper for irange::as_string(). Print a bound to an allocated buffer. */ +static char * +get_bound_with_infinite_markers (tree bound) +{ + tree type = TREE_TYPE (bound); + wide_int type_min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type)); + wide_int type_max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type)); + + if (INTEGRAL_TYPE_P (type) + && !TYPE_UNSIGNED (type) + && TREE_CODE (bound) == INTEGER_CST + && wi::to_wide (bound) == type_min + && TYPE_PRECISION (type) != 1) + return xstrdup ("-INF"); + else if (TREE_CODE (bound) == INTEGER_CST + && wi::to_wide (bound) == type_max + && TYPE_PRECISION (type) != 1) + return xstrdup ("+INF"); + else + return print_generic_expr_to_str (bound); +} + + +/* Return an irange as string. Return NULL on failure, an allocated + string on success. */ +char * +irange::as_string () +{ + char *ret = NULL; + if (undefined_p() || varying_p () || m_num_ranges == 0) + return ret; + + for (unsigned i = 0; i < m_num_ranges; ++i) + { + tree lb = m_base[i * 2]; + tree ub = m_base[i * 2 + 1]; + /* Construct [lower_bound,upper_bound]. */ + char *lbs = get_bound_with_infinite_markers (lb); + char *ubs = get_bound_with_infinite_markers (ub); + /* Paranoia mode */ + if (!lbs) + lbs = xstrdup (""); + if (!ubs) + ubs = xstrdup (""); + + if (ret) + ret = reconcat (ret, ret, "[", lbs, ",", ubs, "]", NULL); + else + ret = concat ("[", lbs, ",", ubs, "]", NULL); + + free (lbs); + free (ubs); + } + return ret; +} + /* Create two value-ranges in *VR0 and *VR1 from the anti-range *AR so that *VR0 U *VR1 == *AR. Returns true if that is possible, false otherwise. If *AR can be represented with a single range diff --git a/gcc/value-range.h b/gcc/value-range.h index c87734dd8cd..76242e4bf45 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -160,6 +160,9 @@ public: wide_int get_nonzero_bits () const; void set_nonzero_bits (const wide_int_ref &bits); + // For diagnostics. + char *as_string (); + // Deprecated legacy public methods. tree min () const; // DEPRECATED tree max () const; // DEPRECATED -- 2.38.1