RFR: 8345067: C2: enable implicit null checks for ZGC reads

Roberto Castañeda Lozano rcastanedalo at openjdk.org
Wed Dec 11 20:48:35 UTC 2024


Currently, C2 cannot exploit late-expanded GC memory accesses as implicit null checks because of their use of temporary operands, 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::has_initial_implicit_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:

![example](https://github.com/user-attachments/assets/b5f9bbc8-d75d-4cf3-841e-73db3dbae753)

Exploiting ZGC loads increases the effectiveness of the implicit null check optimization (measured in percent of explicit null checks turned into implicit ones at compile time) by around 10% in the DaCapo chopin benchmarks:

![C2-inc-hit-rate-jdk-25+1-vs-jdk-25+1-with-8345067](https://github.com/user-attachments/assets/8d114058-c6b2-4254-a374-0d0b220af718)

The larger number of implicit null checks 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.

A further extension of the optimization to arbitrary memory access instructions (including e.g. G1 object stores, which emit multiple memory accesses at arbitrary address offsets) will be investigated separately as part of [JDK-8344627](https://bugs.openjdk.org/browse/JDK-8344627).

#### Testing
- tier1-5, compiler stress test (linux-x64, macosx-x64, windows-x64, linux-aarch64, macosx-aarch64; release and debug mode).

-------------

Commit messages:
 - Revert unnecessary changes
 - Move check to original location
 - Enable zLoadP as implicit null check candidates on riscv and ppc
 - Refactor assertion
 - Simplify test
 - Mark zLoadP in x64 as exploitable by implicit null check optimization
 - Fix comment
 - Do not mark g1LoadP/g1LoadN as initial_implicit_null_check_candidate, they cannot be exploited anyway due to indirect memory operand
 - Exploit zLoadP only if the memory operand is indOffL8 (indirect does not work anyway due to limitations in C2's analysis)
 - Complete test with stores and atomics
 - ... and 10 more: https://git.openjdk.org/jdk/compare/bedb68ab...01dd8618

Changes: https://git.openjdk.org/jdk/pull/22678/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=22678&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8345067
  Stats: 381 lines in 15 files changed: 336 ins; 37 del; 8 mod
  Patch: https://git.openjdk.org/jdk/pull/22678.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/22678/head:pull/22678

PR: https://git.openjdk.org/jdk/pull/22678


More information about the hotspot-compiler-dev mailing list