RFR: 8278228: C2: Improve identical back-to-back if elimination [v4]
Roland Westrelin
roland at openjdk.java.net
Fri Jan 7 09:23:47 UTC 2022
> 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 incrementally with one additional commit since the last revision:
review
-------------
Changes:
- all: https://git.openjdk.java.net/jdk/pull/6882/files
- new: https://git.openjdk.java.net/jdk/pull/6882/files/9bbe513a..a7a58a7c
Webrevs:
- full: https://webrevs.openjdk.java.net/?repo=jdk&pr=6882&range=03
- incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=6882&range=02-03
Stats: 5 lines in 3 files changed: 0 ins; 0 del; 5 mod
Patch: https://git.openjdk.java.net/jdk/pull/6882.diff
Fetch: git fetch https://git.openjdk.java.net/jdk pull/6882/head:pull/6882
PR: https://git.openjdk.java.net/jdk/pull/6882
More information about the hotspot-compiler-dev
mailing list