[9] RFR (S): 8148754: C2 loop unrolling fails due to unexpected graph shape

Zoltán Majó zoltan.majo at oracle.com
Mon Feb 22 14:22:15 UTC 2016


Hi Vladimir,


thank you for the feedback!

On 02/16/2016 01:11 AM, Vladimir Kozlov wrote:
> Zoltan,
>
> It should not be "main" loop if peeling happened. See do_peeling():
>
>     if (cl->is_main_loop()) {
>       cl->set_normal_loop();
>
> Split-if optimization should not split through loop's phi. And 
> generally not through loop's head since it is not making code better - 
> split through backedge moves code into loop again. Making loop body 
> more complicated as this case shows.

I did more investigation to understand what causes the invalid graph 
shape to appear. It seems that the invalid graph shape appears because 
the compiler uses the Compile:: _major_progress inconsistently. Here are 
some details.

- If _major_progress *is set*, the compiler expects more loop 
optimizations to happen. Therefore, certain transformations on the graph 
are not allowed so that the graph is in a shape that can be processed by 
loop optimizations. See:
http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/2c3c43037e14/src/share/vm/opto/convertnode.cpp#l253
http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/2c3c43037e14/src/share/vm/opto/castnode.cpp#l251
http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/2c3c43037e14/src/share/vm/opto/loopnode.cpp#l950
http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/2c3c43037e14/src/share/vm/opto/opaquenode.cpp#l37

- If _major_progress *is not set*, the compiler is allowed to perform 
all possible transformations (because it does not have to care about 
future loop optimizations).

The crash reported for the current issue appears because _major_progress 
*can be accidentally set again* after the compiler decided to stop 
performing loop optimizations. As a result, invalid graph shapes appear.

Here are details about how this happens for both failures I've been 
studying:
https://bugs.openjdk.java.net/browse/JDK-8148754?focusedCommentId=13901941&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13901941

I would propose to change the compiler to use _major_progress 
consistently. (This goes into the same direction as Tobias's recent work 
on JDK-8144487.)

I propose that _major_progress:
- can be SET when the compiler is initialized (because loop 
optimizations are expected to happen afterwards);
- can be SET/RESET in the scope of loop optimizations (because we want 
to see if loop optimizations made progress);
- cannot be SET/RESET by neither incremental inlining nor IGVN (even if 
the IGVN is performed in the scope of loop optimizations).

Here is the updated webrev:
http://cr.openjdk.java.net/~zmajo/8148754/webrev.02/

Performance evaluation:
- The proposed webrev does not cause performance regressions for 
SPECjvm2008, SPECjbb2005, and Octane.

Testing:
- all hotspot JTREG tests on all supported platforms;
- JPRT;
- failing test case.

Thank you and best regards,


Zoltan


>
> Bailout unrolling is fine but performance may suffer because in some 
> cases loop unrolling is better then split-if.


>
> Thanks,
> Vladimir
>
> On 2/15/16 7:22 AM, Zoltán Majó wrote:
>> Hi,
>>
>>
>> please review the patch for 8148754.
>>
>> https://bugs.openjdk.java.net/browse/JDK-8148754
>>
>> Problem: Compilation fails when the C2 compiler attempts loop unrolling.
>> The cause of the failure is that the loop unrolling optimization expects
>> a well-defined graph shape at the entry control of a 'CountedLoopNode'
>> ('IfTrue'/'IfFalse' preceeded by 'If' preceeded by 'Bool' preceeded by
>> 'CmpI').
>>
>>
>> Solution: I investigated several different instances of the same
>> failure. It turns out that the shape of the graph at a loop's entry
>> control is often different from the way loop unrolling expects it to be
>> (please find some examples in the bug's JBS issue). The various graph
>> shapes are a result of previously performed transformations, e.g.,
>> split-if optimization and loop peeling.
>>
>> Loop unrolling requires the above mentioned graph shape so that it can
>> adjust the zero-trip guard of the loop. With the unexpected graph
>> shapes, it is not possible to perform loop unrolling. However, the graph
>> is still in a valid state (except for loop unrolling) and can be used to
>> produce correct code.
>>
>> I propose that (1) we check if an unexpected graph shape is encountered
>> and (2) bail out of loop unrolling if it is (but not fail in the
>> compiler in such cases).
>>
>> The failure was triggered by Aleksey's Indify String Concatenation
>> changes but the generated bytecodes are valid. So this seems to be a
>> compiler issue that was previously there but was not yet triggered.
>>
>>
>> Webrev:
>> http://cr.openjdk.java.net/~zmajo/8148754/webrev.00/
>>
>> Testing:
>> - JPRT;
>> - local testing (linux-86_64) with the failing test case;
>> - executed all hotspot tests locally, all tests pass that pass with an
>> unmodified build.
>>
>> Thank you!
>>
>> Best regards,
>>
>>
>> Zoltan
>>



More information about the hotspot-compiler-dev mailing list