RFR: 8273409: Receiver type narrowed by CCP does not always trigger post-parse call devirtualization
Tobias Hartmann
thartmann at openjdk.java.net
Wed Sep 8 14:49:23 UTC 2021
While working on [JDK-8273323](https://bugs.openjdk.java.net/browse/JDK-8273323), I noticed that even if CCP is able to narrow the receiver type of a virtual call to an exact type, post-parse call devirtualization is not always triggered. The problem is that CCP only adds nodes to the IGVN worklist if their types have been improved:
https://github.com/openjdk/jdk/blob/4023646ed1bcb821b1d18f7e5104f04995e8171d/src/hotspot/share/opto/phaseX.cpp#L1961-L1965
And in turn, IGVN only adds user nodes to the worklist if the type of the parent node could be further improved. As a result, a `CallNode` is not always added to the worklist if the type of its receiver node has been improved. Often, we are lucky and macro expansion or another optimization phase after CCP adds the `CallNode` to the worklist. However, as `testDynamicCallWithCCP` shows, that's not always the case.
The fix is to explicitly add `CallStaticJavaNode` and `CallDynamicJava` to the worklist after CCP to give call devirtualization a chance to run:
https://github.com/openjdk/jdk/blob/4023646ed1bcb821b1d18f7e5104f04995e8171d/src/hotspot/share/opto/callnode.cpp#L1054-L1057
https://github.com/openjdk/jdk/blob/4023646ed1bcb821b1d18f7e5104f04995e8171d/src/hotspot/share/opto/callnode.cpp#L1137-L1140
I also considered moving the optimization from `Ideal` to `Value` (which in contrast to `Ideal` is already executed **during** CCP) but we can't trust receiver types during CCP (because CCP goes from optimistic types to pessimistic ones). Also, the current implementation relies on setting the `_generator` field which is not possible from `Value` which is declared `const`:
https://github.com/openjdk/jdk/blob/4023646ed1bcb821b1d18f7e5104f04995e8171d/src/hotspot/share/opto/callnode.cpp#L1169-L1172
All the newly added tests fail IR verification if post-parse call devirtualization is disabled (`-XX:-IncrementalInlineVirtual -XX:-IncrementalInlineMH`). Without the fix, `testDynamicCallWithCCP` always fails.
I filed [JDK-8273496](https://bugs.openjdk.java.net/browse/JDK-8273496) to improve how CCP handles this.
Thanks,
Tobias
-------------
Commit messages:
- 8273409: Receiver type narrowed by CCP does not always trigger post-parse call devirtualization
Changes: https://git.openjdk.java.net/jdk/pull/5418/files
Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=5418&range=00
Issue: https://bugs.openjdk.java.net/browse/JDK-8273409
Stats: 205 lines in 3 files changed: 204 ins; 0 del; 1 mod
Patch: https://git.openjdk.java.net/jdk/pull/5418.diff
Fetch: git fetch https://git.openjdk.java.net/jdk pull/5418/head:pull/5418
PR: https://git.openjdk.java.net/jdk/pull/5418
More information about the hotspot-compiler-dev
mailing list