RFR: 8278228: C2: Improve identical back-to-back if elimination [v3]
Christian Hagedorn
chagedorn at openjdk.java.net
Thu Jan 6 12:35:18 UTC 2022
On Wed, 5 Jan 2022 17:06:57 GMT, Roland Westrelin <roland at openjdk.org> wrote:
>> C2 has had the ability to optimize:
>>
>> (1)
>>
>> if (some_condition) {
>> // body 1
>> } else {
>> // body 2
>> }
>> if (some_condition) {
>> // body 3
>> } else {
>> // body 4
>> }
>>
>> into:
>>
>> (4)
>>
>> if (some_condition) {
>> // body 1
>> // body 3
>> } else {
>> // body 2
>> // body 4
>> }
>>
>> for a while.
>>
>> This is achieved by the intermediate step:
>>
>> (2)
>>
>> if (some_condition) {
>> // body 1
>> some_condition2 = true;
>> } else {
>> // body 2
>> some_condition2 = false;
>> }
>> if (some_condition2) {
>> // body 3
>> } else {
>> // body 4
>> }
>>
>> which then allows the use of the exiting split if optimization. As a
>> result, the graph is transformed to:
>>
>> (3)
>>
>> if (some_condition) {
>> // body 1
>> some_condition2 = true;
>> if (some_condition2) {
>> body3: // a Region here
>> // body3
>> } else {
>> goto body4;
>> }
>> } else {
>> // body 2
>> some_condition2 = false;
>> if (some_condition2) {
>> goto body3;
>> } else {
>> body4: // another Region here
>> // body4;
>> }
>> }
>>
>> and finally to (4) above.
>>
>> Recently, 8275610 has shown that this can break if some_condition is a
>> null check. If, say, body 3 has a control dependent CastPP, then when
>> body 1 and body 3 are merged, the CastPP of body 3 doesn't become
>> control dependent on the dominating if (because in step (2), the
>> CastPP hides behind a Region). As a result, the CastPP loses its
>> dependency on the null check.
>>
>> After discussing this with Christian, it seemed this was caused by the
>> way this transformation relies on split if: having custom code that
>> wouldn't create Regions at body3 and body4 that are then optimized out
>> would solve the problem. Anyway, after looking at the split if code,
>> trying to figure out how to tease it apart in smaller steps and
>> reusing some of them to build a new transformation, it seemed too
>> complicated. So instead, I propose reusing split if in a slightly
>> different way:
>>
>> skip step (2) but perform split if anyway to obtain:
>>
>> if (some_condition) {
>> // body 1
>> if (some_condition) {
>> body3: // Region1
>> // CastPP is here, control dependent on Region1
>> // body3
>> } else {
>> goto body4;
>> }
>> } else {
>> // body 2
>> if (some_condition) {
>> goto body3;
>> } else {
>> body4: // Region2
>> // body4;
>> }
>> }
>>
>> - A CastPP node would still be behind a Region. So next step, is to push
>> control dependent nodes through Region1 and Region2:
>>
>> if (some_condition) {
>> // body 1
>> if (some_condition) {
>> // A CastPP here
>> body3: // Region1
>> // body3
>> } else {
>> goto body4;
>> }
>> } else {
>> // body 2
>> if (some_condition) {
>> // A CastPP here
>> goto body3;
>> } else {
>> body4: // Region2
>> // body4;
>> }
>> }
>>
>> - And then call dominated_by() to optimize the dominated:
>>
>> if (some_condition) {
>>
>> in both branches of the dominating if (some_condition) {. That also
>> causes the CastPP to become dependent on the dominating if.
>
> Roland Westrelin has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains eight additional commits since the last revision:
>
> - Christian's review
> - Merge branch 'master' into JDK-8278228
> - only for nodes that depends_only_on_test()
> - more
> - more
> - more
> - more
> - exps
Thanks for doing the updates! That's even better to move it to a separate method.
Two more things I've noticed:
https://github.com/openjdk/jdk/blob/bc12381105ef5ba14f99304a220817e97c9a99b5/src/hotspot/share/opto/split_if.cpp#L445
This could also be changed to `RegionNode*` with an assertion moved from
https://github.com/openjdk/jdk/blob/bc12381105ef5ba14f99304a220817e97c9a99b5/src/hotspot/share/opto/split_if.cpp#L37
And `new_iff` could also be changed to `RegionNode*`:
https://github.com/openjdk/jdk/blob/bc12381105ef5ba14f99304a220817e97c9a99b5/src/hotspot/share/opto/split_if.cpp#L494
Will submit some testing and get back with the results.
-------------
PR: https://git.openjdk.java.net/jdk/pull/6882
More information about the hotspot-compiler-dev
mailing list