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