[15] RFR(M): 8240227: Loop predicates should be copied to unswitched loops
Nils Eliasson
nils.eliasson at oracle.com
Wed Mar 18 09:48:43 UTC 2020
For the record - I'm okay with the cleaned up version too.
Best regards,
Nils
On 2020-03-13 13:10, Christian Hagedorn wrote:
> Hi Tobias
>
> Thank you for your review and your comments!
>
> On 13.03.20 09:24, Tobias Hartmann wrote:
>> - loopPredicate.cpp:157 Wrong indentation
>> - loopPredicate.cpp:363 Should be "sanity" but in general, I prefer
>> are more meaningful message
>> - Maybe replace all these predicate->as_Proj() /
>> predicate->as_IfProj() by declaring a new local
>> "proj" or something
>> - loopPredicate.cpp:389 Can be replaced by
>> igvn->replace_input_of(iff, 1 igvn->intcon(proj->_con));
>> - loopUnswitch.cpp:160 Wrong indentation
>> - PartialPeelingUnswitch.java:1811 Should be "} else if {" (also in
>> the following lines)
>> - PartialPeelingUnswitch.java:1838 Missing whitespace
>
> Fixed.
>
>> - loopPredicate.cpp:415/422 Why are two versions of
>> PhaseIdealLoop::clone_loop_predicates required?
>
> There was originally a method PhaseIterGVN::clone_loop_predicates
> which did not have any uses. I removed it in the current webrev. But
> in addition, we can also remove one of those remaining
> clone_loop_predicates methods which is not required anymore and make
> all involved methods non-static. I removed all related dead code.
>
>> - loopPredicate.cpp:421 Isn't that code only used for unswitching?
>> I.e., the comment needs to be
>> updated and maybe the assert from line 308 should be moved upwards.
>
> Yes, it is only used for loop unswitching. Fixed.
>
>> Since we want to backport both 8240227 and 8237859, it may be good to
>> run some more extra days of
>> Lucene testing on a server machine while this is backing in JDK 15.
>
> Definitely a good idea. I'll run some testing of Lucene and ZGC on a
> machine over the weekend.
>
> I created new updated webrevs with the cleaned up code:
> Full: http://cr.openjdk.java.net/~chagedorn/8240227/webrev.01/
> Inc: http://cr.openjdk.java.net/~chagedorn/8240227/webrev.00-01/
>
> I'll run again some testing over the weekend, just to be sure (and
> also together with the fix for JDK-8237859).
>
> Best regards,
> Christian
>
>> On 11.03.20 13:20, Christian Hagedorn wrote:
>>> Hi
>>>
>>> Please review the following patch:
>>> https://bugs.openjdk.java.net/browse/JDK-8240227
>>> http://cr.openjdk.java.net/~chagedorn/8240227/webrev.00/
>>>
>>> This is the same problem as for JDK-8203915 [1] but now with
>>> additional loop unswitching which was
>>> not handled in the fix for JDK-8203915.
>>>
>>> Background:
>>> The original idea of inserting skeleton predicates [2] for range
>>> check predicates involving the loop
>>> induction variable was to copy those concrete predicates down to the
>>> main loop when creating
>>> pre/main/post loops. When unrolling the loop later, the limit check
>>> predicate for the induction
>>> variable is updated to become stronger and cover all accesses of the
>>> unrolled loop body. If a
>>> predicate for the main loop later turns out to always fail due to
>>> type information, then the main
>>> loop can be completely removed.
>>>
>>> If we did not do that (which exactly happens in the test case since
>>> we do not copy the range check
>>> predicates to the unswitched loops which are therefore not found
>>> when creating pre/main/post loops
>>> for the slow and fast loop) then the C2 matcher can hit the bad AD
>>> file assert when over-unrolling
>>> the main loop. In the test case some data paths die because CastII
>>> nodes for an array load are
>>> replaced by TOP. This happens after Opaque1 nodes are removed and
>>> the type information about the
>>> maximum number of iterations for the pre-loop propagate to the
>>> induction variable of the main loop.
>>> IGVN concludes that the induction variable is out-of-bounds for some
>>> CastII nodes which are then
>>> replaced by TOP. As a result, the graph contains vectorized results
>>> with a TOP memory input which
>>> cannot be handled by the matcher.
>>>
>>> [3] shows the IR before doing the first IGVN iteration where
>>> major_progress() is false (Opaque1
>>> nodes can be removed). The 719 Opaque1 is removed and the type
>>> information of 1063 MinI [int:0..13]
>>> propagates to the induction variable of the pre-loop 701 Phi
>>> [int:5..13] (loop starts with j = 5, at
>>> most 8 iterations of the pre-loop) which then propagates over 716
>>> CastII [int:6..14] -> 1665 Phi
>>> [int:6..max-31] (32 iterations after unrolling) -> 1537 AddI
>>> [int:30..max-7] (adds 24) which is then
>>> compared with 1027 CastII [int:5..7] (iArr[i]). [int:5..7] does not
>>> contain [int:30..max-7] and
>>> therefore 1027 CastII is replaced with TOP.
>>>
>>> The main loop is dead but is not removed since there is no range
>>> check predicate for the main loop
>>> that would notice that some loads are always out-of-bounds due to
>>> the type information. The fix for
>>> JDK-8203915 avoids that (for loops without unswitching) by adding
>>> range check predicates for the
>>> main loop which are then updated while unrolling and later allow the
>>> main loop to be removed.
>>>
>>> The only thing missing is that the created range check predicates
>>> for a loop to be unswitched are
>>> not cloned to both unswitched loop versions. Therefore, the changes
>>> for [1] cannot be applied since
>>> it does not find any predicates when creating pre/main/post loops
>>> for the slow and fast loop. This
>>> fix addresses that and clones all range check predicates that have
>>> at least one control edge to a
>>> data node which is part of the loop to be unswitched. All control
>>> edges to data nodes which are part
>>> of either the slow or fast loop are updated to the new cloned
>>> predicates accordingly. All old range
>>> predicates of the original loop to be unswitched that do not have
>>> any control edges to data nodes
>>> can be removed.
>>>
>>> This patch is also a prerequisite for the fix of JDK-8237859 [4]. I
>>> included some renaming for
>>> predicate related code that should make the difference between the
>>> various predicate types and how
>>> they are used clearer (skeleton, concrete, empty, updated...). I
>>> also included many more unswitch
>>> tests (PartialPeelingUnswitch.java) that I originally wrote as part
>>> of an RFE in progress [5] but
>>> also helped with testing this fix.
>>>
>>> Thank you!
>>>
>>> Best regards,
>>> Christian
>>>
>>>
>>> [1] https://bugs.openjdk.java.net/browse/JDK-8203915
>>> [2] https://bugs.openjdk.java.net/browse/JDK-8193130
>>> [3]
>>> https://bugs.openjdk.java.net/secure/attachment/87257/IR_before_IGVN_major_progress_false.png
>>> [4] https://bugs.openjdk.java.net/browse/JDK-8237859
>>> [5] https://bugs.openjdk.java.net/browse/JDK-8236722
More information about the hotspot-compiler-dev
mailing list