RFR(M): 8244504: C2: refactor counted loop code in preparation for long counted loop
Roland Westrelin
rwestrel at redhat.com
Thu May 7 08:20:46 UTC 2020
Thanks for looking at this.
> Looking a little more at the interval arithmetic subroutines,
> I think it would be reasonable to leave out most of the linkage to
> TypeInt/TypeLong, and isolate the logic that does the min-ing
> and max-ing, with separate routines for translating to and from
> the Type* world.
>
> Maybe:
>
> struct MinMaxInterval {
> julong shi, slo, uhi, ulo;
> boolean is_int;
> void signedMaxWith(const Interval& that);
> void unsignedMaxWith(const Interval& that);
> void signedMinWith(const Interval& that);
> void unsignedMinWith(const Interval& that);
> MinMaxInterval(TypeInt*);
> MinMaxInterval(TypeLong*);
> const TypeInt* asTypeInt();
> const TypeInt* asTypeLong();
> };
>
> It would be overkill in many cases to put such small routines
> into their own class, but in this case the min/max interval logic
> is very subtle and deserves a little display platform.
I added this code because in the code that computes the number of
iterations of the inner loop of a transformed long loop:
inner_iters_max = GraphKit::max_diff_with_zero(adjusted_limit, outer_phi, _igvn);
Node* inner_iters_actual = GraphKit::unsigned_min(inner_iters_max, inner_iters_limit, _igvn);
inner_iters_actual is in the interval [0, max_jint-stride]
Because of that, there's no need for the inner int counted loop to be
guarded by a limit check. But the method constructing the int counted
loop emits a limit check unless the type of inner_iters_actual is
accurate enough.
Another way to deal with that, would be to pass the expected result type
as argument to unsigned_min() rather than compute it.
Or, we don't care about the useless loop limit check...
Roland.
More information about the hotspot-compiler-dev
mailing list