[4/5] value-range: Add as_string diagnostics helper
Checks
Commit Message
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 <amacleod@redhat.com>
Cc: Aldy Hernandez <aldyh@redhat.com>
---
gcc/value-range.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++
gcc/value-range.h | 3 +++
2 files changed, 59 insertions(+)
Comments
On Sat, Nov 12, 2022 at 3:47 PM Bernhard Reutner-Fischer via
Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>
> 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 <amacleod@redhat.com>
> Cc: Aldy Hernandez <aldyh@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 *
Can we start using std::string instead of char* here?
> +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);
No reason to do xstrdup any more either.
> +}
> +
> +
> +/* Return an irange as string. Return NULL on failure, an allocated
> + string on success. */
> +char *
Likewise.
Thanks,
Andrew Pinski
> +irange::as_string ()
> +{
> + char *ret = NULL;
This becomes std::string ret;
> + 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
>
On 11/12/22 16:55, Andrew Pinski via Gcc-patches wrote:
> On Sat, Nov 12, 2022 at 3:47 PM Bernhard Reutner-Fischer via
> Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>> 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 <amacleod@redhat.com>
>> Cc: Aldy Hernandez <aldyh@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 *
> Can we start using std::string instead of char* here?
If it makes the code easier to read/maintain, sure. std::string isn't
used heavily, but has crept into a few places, mostly in target files.
std::string isn't something we've pushed at all in terms of preferred
practices.
Jeff
@@ -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
@@ -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