JDK-8310524 : C2: record parser-generated LoadN nodes for IGVN
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 21,22,23
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2023-06-21
  • Updated: 2025-09-29
  • Resolved: 2023-12-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 23
23 b02Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
GraphKit::make_load() records newly created load OOP nodes for IGVN:

https://github.com/openjdk/jdk/blob/67fbd87378a9b3861f1676977f9f2b36052add29/src/hotspot/share/opto/graphKit.cpp#L1563-L1566

This is however limited to load *native* OOP (LoadP) nodes and precludes later IGVN optimization of load *compressed* OOP (LoadN) nodes. This is due to the fact that, for LoadN nodes, LoadNode::make() creates and returns their successor DecodeNNode instead, which is the one recorded for IGVN in GraphKit::make_load():

https://github.com/openjdk/jdk/blob/67fbd87378a9b3861f1676977f9f2b36052add29/src/hotspot/share/opto/memnode.cpp#L956

The missing optimization is illustrated by missing-idealization.png (attached), observed while investigating JDK-8303513. When disabling UseCompressedOops, the leftmost subgraph is transformed into the middle one when 1590 LoadP is selected for Idealization during the first IGVN run. This step replaces 1590 LoadP with the value stored by the dominating 1551 StoreP node since they access the same address. If UseCompressedOops is enabled though (default value), the rightmost subgraph is never optimized similarly because 1618 LoadN is never selected for Idealization.

This RFE suggests recording also LoadN nodes for IGVN (besides, or perhaps instead of, their successor DecodeN nodes), along the lines of:

diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index 39a377ee700..b92b907eea1 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -1563,6 +1574,9 @@ Node* GraphKit::make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
   if (((bt == T_OBJECT) && C->do_escape_analysis()) || C->eliminate_boxing()) {
     // Improve graph before escape analysis and boxing elimination.
     record_for_igvn(ld);
+    if (ld->is_DecodeN()) {
+      record_for_igvn(ld->in(1));
+    }
   }
   return ld;
 }

Applying this tentative patch enables the same optimization in the case where UseCompressedOops is disabled, leading to the subgraph shown in after-recording-loadn-for-igvn.png (attached).
Comments
Changeset: 9e48b90c Author: Daniel Lundén <daniel.lunden@oracle.com> Committer: Roberto Castañeda Lozano <rcastanedalo@openjdk.org> Date: 2023-12-08 11:04:39 +0000 URL: https://git.openjdk.org/jdk/commit/9e48b90c7fd349195a1389c480c66dfd9b1a7f75
08-12-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/16967 Date: 2023-12-05 09:05:35 +0000
05-12-2023