cleanups and unification of value_range dumping code
Aldy Hernandez
aldyh@redhat.com
Fri Nov 9 12:32:00 GMT 2018
On 11/9/18 6:37 AM, Richard Biener wrote:
> On Thu, Nov 8, 2018 at 5:03 PM Aldy Hernandez <aldyh@redhat.com> wrote:
>>
>>
>>
>> On 11/8/18 9:39 AM, Richard Biener wrote:
>>> On Thu, Nov 8, 2018 at 2:32 PM Aldy Hernandez <aldyh@redhat.com> wrote:
>>>>
>>>> [Richard, you're right. An overloaded debug() is better than
>>>> this->dump(). Anyone who thinks different is wrong. End of discussion.]
>>>>
>>>> There's no reason to have multiple ways of dumping a value range. And
>>>> I'm not even talking about ipa-prop.* which decided that they should
>>>> implement their own version of value_ranges basically to annoy me.
>>>> Attached is a patch to remedy this.
>>>>
>>>> I have made three small user-visible changes to the dumping code--
>>>> cause, well... you know me... I can't leave things alone.
>>>>
>>>> 1. It *REALLY* irks me that bools are dumped with -INF/+INF. Everyone
>>>> knows that bools should be 0/1. It's in the Bible. Look it up.
>>>>
>>>> 2. Analogous to #1, what's up with signed 1-bit fields? Who understands
>>>> [0, +INF] as [0, 0]? No one; that's right. (It's still beyond me the
>>>> necessity of signed bit fields in the standard period, but I'll pick my
>>>> battles.)
>>>>
>>>> 3. I find it quite convenient to display the tree type along with the
>>>> range as:
>>>>
>>>> [1, 1] int EQUIVALENCES { me, myself, I }
>>>
>>> the type inbetween the range and equivalences? seriously? If so then
>>> _please_ dump the type before the range:
>>>
>>> int [1, 1] EQUIV { ... }
>>
>> Done in attached patch.
>>
>>>
>>>> Finally.. As mentioned, I've implement an overloaded debug() because
>>>> it's *so* nice to use gdb and an alias of:
>>>>
>>>> define dd
>>>> call debug($arg0)
>>>> end
>>>>
>>>> ...and have stuff just work.
>>>>
>>>> I do realize that we still have dump() lying around. At some point, we
>>>> should start dropping external access to the dump methods for objects
>>>> that are never dumped by the compiler (but by the user at debug time).
>>>
>>> +DEBUG_FUNCTION void
>>> +debug (const value_range *vr)
>>> +{
>>> + dump_value_range (stderr, vr);
>>> +}
>>> +
>>> +DEBUG_FUNCTION void
>>> +debug (const value_range vr)
>>>
>>> ^^^ missing a & (const reference?)
>>>
>>> +{
>>> + dump_value_range (stderr, &vr);
>>> +}
>>
>> Fixed.
>>
>>>
>>> also
>>>
>>> @@ -2122,21 +2122,11 @@ dump_ssaname_info (pretty_printer *buffer,
>>> tree node, int spc)
>>> if (!POINTER_TYPE_P (TREE_TYPE (node))
>>> && SSA_NAME_RANGE_INFO (node))
>>> {
>>> - wide_int min, max, nonzero_bits;
>>> - value_range_kind range_type = get_range_info (node, &min, &max);
>>> + value_range vr;
>>>
>>> - if (range_type == VR_VARYING)
>>> - pp_printf (buffer, "# RANGE VR_VARYING");
>>> - else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
>>> - {
>>> - pp_printf (buffer, "# RANGE ");
>>> - pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
>>> - pp_wide_int (buffer, min, TYPE_SIGN (TREE_TYPE (node)));
>>> - pp_printf (buffer, ", ");
>>> - pp_wide_int (buffer, max, TYPE_SIGN (TREE_TYPE (node)));
>>> - pp_printf (buffer, "]");
>>> - }
>>> - nonzero_bits = get_nonzero_bits (node);
>>> + get_range_info (node, vr);
>>>
>>> this is again allocating INTEGER_CSTs for no good reason. dumping really
>>> shuld avoid possibly messing with the GC state.
>>
>> Hmmmm, I'd really hate to have two distinct places that dump value
>> ranges. Is this really a problem? Cause the times I've run into GC
>> problems I'd had to resort to printf() anyhow...
>
> Well, if you can avoid GC avoid it. If you are in the midst of debugging
> you certainly do not want your inferior calls mess with the GC state.
I personally haven't had to deal with this in 20 years, and I believe
the convenience of having one dumping routine makes up for the
theoretical possibility that we'd run into this in the future.
>
>> And while we're on the subject of multiple implementations, I'm thinking
>> of rewriting ipa-prop to actually use value_range's, not this:
>>
>> struct GTY(()) ipa_vr
>> {
>> /* The data fields below are valid only if known is true. */
>> bool known;
>> enum value_range_kind type;
>> wide_int min;
>> wide_int max;
>> };
>>
>> so perhaps:
>>
>> struct { bool known; value_range vr; }
>
> Size is of great matter here so m_equiv stands in the way here. Also that
> would exchange wide-ints for trees. Were trees not bad? Andrew?!?!
>
>> Remember that trees are cached, whereas wide_int's are not, and folks
>> (not me :)) like to complain that wide_int's take a lot of space.
>
> There's trailing-wide-ints for this issue.
Had we been using trailing wide ints, it would've been a great argument,
but alas we aren't. As it stands, we'd use 44% less memory by using
value_range's-- even with the m_equiv waste:
struct GTY(()) ipa_with_value_range
{
bool known;
value_range vr;
};
sizeof(ipa_vr) => 72 bytes
sizeof(ipa_with_value_range) => 40 bytes
Also, won't your upcoming value_range_without_equivs work further reduce
these 40 bytes?
Aldy
More information about the Gcc-patches
mailing list