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