[RFA][PR tree-optimization/79095] [PATCH 1/4] Improve ranges for MINUS_EXPR and EXACT_DIV_EXPR
Richard Biener
richard.guenther@gmail.com
Wed Feb 8 12:53:00 GMT 2017
On Tue, Feb 7, 2017 at 7:34 PM, Jeff Law <law@redhat.com> wrote:
> On 02/07/2017 01:39 AM, Richard Biener wrote:
>>
>> On Mon, Feb 6, 2017 at 10:57 PM, Jeff Law <law@redhat.com> wrote:
>>>
>>> On 02/06/2017 08:33 AM, Richard Biener wrote:
>>>
>>>> ah, indeed vr0type is VR_ANTI_RANGE and yes we have the case of a
>>>> range with an anti-range "inside". This also covers [-1,1] v
>>>> ~[0,0] where you choose the much larger anti-range now. So at
>>>> least we want to have some idea about the sizes of the ranges
>>>> (ideally we'd choose the smaller though for most further
>>>> propagations anti-ranges often degenerate to varying...)
>>>
>>>
>>> vr0 as an anti-singleton range like ~[0,0] is the only one likely
>>> of any interest right now and that's always going to have a range
>>> that is all but one value :-)
>>>
>>> vr1 is the tricky case. We could do v1.max - vr1.min and if that
>>> overflows or is some "large" value (say > 65536 just to throw out a
>>> value), then we conclude creating the singleton anti-range like
>>> ~[0,0] is more useful.
>>
>>
>> Yes, but it's hard to tell. As said, anti-ranges quickly degrade in
>> further propagation and I fear that without a better range
>> representation it's hard to do better in all cases here.
>
> All very true. What I threw into testing overnight was the >65536
> heuristic. While I don't expect we're going to see any testing failures, I
> also suspect we don't have a lot of cases where wide ranges are all that
> useful and even less testsuite coverage of those cases.
>
> One more targeted approach would be to *wipe* the old range when it is wide
> and we discover ~[0,0] as a new range. We could do this just for
> EXACT_DIV_EXPR. We'd do this much earlier than vrp_intersect so that we'd
> still have enough context to know we're dealing with EXACT_DIV_EXPR. It's
> obviously much less likely to have side effects, but feels even more like a
> hack to me.
>
> *If* we come up with something useful, it might suggest a different approach
> to even discovering the ~[0,0] case for EXACT_DIV_EXPR. Part of the problem
> is we have a numerator of ~[0,0]. We covert that into [MININT,-1] U
> [1,MAXINT] Then apply the denominator's range to both generating
> [MININT/4,0] U [0, MAXINT/4], which we convert to [MININT/4,MAXINT/4]
>
> But the initial conversion of the numerator's range is imprecise for
> EXACT_DIV_EXPR. If we mask out the low order bits at conversion time we end
> up generating the (reasonable) [MININT/4,-1] U [1,MAXINT/4]. Then we union
> those together into [MININT/4,MAXINT/4], but if we had a good heuristic we
> might be able to realize ~[0,0] is better.
>
>
>
> The fact is
>>
>> we can't represent the result of the intersection and thus we have to
>> conservatively choose an approximation.
>
> Right. There's no way apriori to absolutely know which range representation
> is better. Though we have some sense that a wide range is not generally
> useful (for some definition of wide) and a singleton anti-range sometimes
> has value (because it can be used to propagate simple equivalences). We
> could approximate the latter by looking at uses of the SSA_NAME and guess
> which of those would benefit from the propagation enabled by a singleton
> anti-range. That sounds painful though.
>
>
> Sometimes we have the other
>>
>> range on an SSA name and thus can use equivalences (when coming from
>> assert processing), but most of the time not and thus we can't use
>> equivalences (which use SSA name versions rather than an index into
>> a ranges array - one possible improvement to the range
>> representation).
>
> Right.
>
> Iff ~[0,0] is useful information querying sth for
>>
>> non-null should also look at equivalences btw.
>
> ~[0,0] is primarily useful in pointer contexts -- null pointer check
> elimination and pointer arithmetic. Outside those contexts I doubt it has
> all that much value.
>
> Sadly, I don't think we can rely on types either -- IIRC everything is
> casted to a generic integer type, so we can't key on ptrdiff_t.
Bah.
Add a nonnull_p flag to value_range ...
/me runs...
Honestly, the way to go is ditch VR_ANTI_RANGE and make value_range be
// template <unsigned N>
struct GTY(()) value_range
{
enum value_range_type type;
// The value range is the union of [ min[0], max[0] ], [ min[1], max[1] ] ...
tree min[N];
tree max[N];
bitmap equiv;
};
or better use a sub-struct for the individual sub-ranges (and maybe a vec so
that the actual N is variable and we just impose an upper limit somewhere).
for the moment with fixed N == 2. Then we can represent [MIN/4, 1] U [MAX/4, 1]
exactly.
Btw, there's always much talk about that mysterious VRP improvements by Andrew.
I hope he doesn't mind if his work gets torn apart during hypothetical
review which
usually happens if you develop stuff somewhere hidden in a dark
corner... and yes,
I didn't want to duplicate any work and thus I refrained from doing
the above kind of
refactorings at the end of stage1.
Richard.
> Jeff
>
More information about the Gcc-patches
mailing list