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 investigatingJDK-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).
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
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).
- relates to
-
JDK-8321820 TestLoadNIdeal fails on 32-bit because -XX:+UseCompressedOops is not recognized
- Resolved
-
JDK-8326438 C2: assert(ld->in(1)->Opcode() == Op_LoadN) failed: Assumption invalid: input to DecodeN is not LoadN
- Resolved
-
JDK-8303513 C2: LoadKlassNode::make fails with 'expecting TypeKlassPtr'
- Resolved