RFR: 8345067: C2: enable implicit null checks for ZGC reads [v5]
Axel Boldt-Christmas
aboldtch at openjdk.org
Fri May 16 08:40:56 UTC 2025
On Fri, 16 May 2025 07:44:53 GMT, Roberto Castañeda Lozano <rcastanedalo at openjdk.org> wrote:
>> Currently, C2 cannot exploit late-expanded GC memory accesses as implicit null checks because of their use of temporary operands (`MachTemp`), which prevents `PhaseCFG::implicit_null_check` from [hoisting the memory accesses to the test basic block](https://github.com/openjdk/jdk/blob/f88c1c6ff86b8f29a71647e46136b6432bb67619/src/hotspot/share/opto/lcm.cpp#L319-L335).
>>
>> This changeset extends the scope of the implicit null check optimization so that it can exploit ZGC object loads. It introduces a platform-dependent predicate (`MachNode::is_late_expanded_null_check_candidate`) to mark late-expanded instructions that emit a suitable memory access as a first instruction as candidates, and extends the optimization to recognize and hoist candidate memory accesses that use temporary operands:
>>
>> 
>>
>> ZGC object loads are marked as late-expanded null-check candidates unconditionally on all ZGC-supported platforms except on aarch64, where only loads that do not require an initial `lea` instruction (due to [address legitimization](https://github.com/openjdk/jdk/blob/ddd07b107e814ec846579a66d4f2005b7db9bb2f/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp#L132-L144)) are marked as candidates. Fortunately, most aarch64 loads seen in practice use small offsets and can be marked as candidates.
>>
>> Exploiting ZGC loads increases the effectiveness of the implicit null check optimization (percent of explicit null checks turned into implicit ones at compile time) by around 10% in the DaCapo23 benchmarks. This results in slight performance improvements (in the 1-2% range) in a few DaCapo and SPECjvm2008 benchmarks and an overall slight improvement across Renaissance benchmarks.
>>
>> #### Testing
>> - tier1-5, compiler stress test (linux-x64, macosx-x64, windows-x64, linux-aarch64, macosx-aarch64; release and debug mode).
>
> Roberto Castañeda Lozano has updated the pull request incrementally with one additional commit since the last revision:
>
> Replace control type with PhaseCFG::is_CFG test
The GC changes looks good. Only took a cursory look of the ADLC and C2 changes, but nothing stands out.
Only had a small comment about `legitimize_address_requires_lea`.
src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp line 141:
> 139: Address legitimize_address(const Address &a, int size, Register scratch) {
> 140: if (a.getMode() == Address::base_plus_offset) {
> 141: if (legitimize_address_requires_lea(a, size)) {
It is a little strange that `legitimize_address_requires_lea` is only the second condition and not
return a.getMode() == Address::base_plus_offset && !Address::offset_ok_for_immed(a.offset(), exact_log2(size));
And have the check in `legitimize_address` simply be `if (legitimize_address_requires_lea(a, size))`
I guess we never end up calling `legitimize_address_requires_lea` with a literal address, where it would assert in `a.offset()`. But requiring the Address parameter of legitimize_address_requires_lea to be in a specific mode as a precondition seems weird to me.
-------------
PR Review: https://git.openjdk.org/jdk/pull/25066#pullrequestreview-2845912788
PR Review Comment: https://git.openjdk.org/jdk/pull/25066#discussion_r2092596572
More information about the hotspot-gc-dev
mailing list