8155729: C2: Skip transformation of LoadConP for heap-based compressed oops
Reviewed-by: kvn
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad Tue Oct 04 21:21:10 2016 +0300
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad Fri Apr 29 15:23:15 2016 +0200
@@ -3496,6 +3496,16 @@
return false;
}
+bool Matcher::const_oop_prefer_decode() {
+ // Prefer ConN+DecodeN over ConP in simple compressed oops mode.
+ return Universe::narrow_oop_base() == NULL;
+}
+
+bool Matcher::const_klass_prefer_decode() {
+ // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
+ return Universe::narrow_klass_base() == NULL;
+}
+
// Is it better to copy float constants, or load them directly from
// memory? Intel can load a float constant from a direct address,
// requiring no extra registers. Most RISCs will have to materialize
--- a/hotspot/src/cpu/ppc/vm/ppc.ad Tue Oct 04 21:21:10 2016 +0300
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad Fri Apr 29 15:23:15 2016 +0200
@@ -2166,6 +2166,16 @@
return false;
}
+bool Matcher::const_oop_prefer_decode() {
+ // Prefer ConN+DecodeN over ConP in simple compressed oops mode.
+ return Universe::narrow_oop_base() == NULL;
+}
+
+bool Matcher::const_klass_prefer_decode() {
+ // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
+ return Universe::narrow_klass_base() == NULL;
+}
+
// Is it better to copy float constants, or load them directly from memory?
// Intel can load a float constant from a direct address, requiring no
// extra registers. Most RISCs will have to materialize an address into a
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Tue Oct 04 21:21:10 2016 +0300
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Fri Apr 29 15:23:15 2016 +0200
@@ -2003,6 +2003,20 @@
return false;
}
+bool Matcher::const_oop_prefer_decode() {
+ // TODO: Check if loading ConP from TOC in heap-based mode is better:
+ // Prefer ConN+DecodeN over ConP in simple compressed oops mode.
+ // return Universe::narrow_oop_base() == NULL;
+ return true;
+}
+
+bool Matcher::const_klass_prefer_decode() {
+ // TODO: Check if loading ConP from TOC in heap-based mode is better:
+ // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
+ // return Universe::narrow_klass_base() == NULL;
+ return true;
+}
+
// Is it better to copy float constants, or load them directly from memory?
// Intel can load a float constant from a direct address, requiring no
// extra registers. Most RISCs will have to materialize an address into a
--- a/hotspot/src/cpu/x86/vm/x86_32.ad Tue Oct 04 21:21:10 2016 +0300
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad Fri Apr 29 15:23:15 2016 +0200
@@ -1452,6 +1452,15 @@
return true;
}
+bool Matcher::const_oop_prefer_decode() {
+ ShouldNotCallThis();
+ return true;
+}
+
+bool Matcher::const_klass_prefer_decode() {
+ ShouldNotCallThis();
+ return true;
+}
// Is it better to copy float constants, or load them directly from memory?
// Intel can load a float constant from a direct address, requiring no
--- a/hotspot/src/cpu/x86/vm/x86_64.ad Tue Oct 04 21:21:10 2016 +0300
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad Fri Apr 29 15:23:15 2016 +0200
@@ -1660,6 +1660,19 @@
return (LogKlassAlignmentInBytes <= 3);
}
+bool Matcher::const_oop_prefer_decode() {
+ // Prefer ConN+DecodeN over ConP.
+ return true;
+}
+
+bool Matcher::const_klass_prefer_decode() {
+ // TODO: Either support matching DecodeNKlass (heap-based) in operand
+ // or condisider the following:
+ // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
+ //return Universe::narrow_klass_base() == NULL;
+ return true;
+}
+
// Is it better to copy float constants, or load them directly from
// memory? Intel can load a float constant from a direct address,
// requiring no extra registers. Most RISCs will have to materialize
--- a/hotspot/src/share/vm/opto/compile.cpp Tue Oct 04 21:21:10 2016 +0300
+++ b/hotspot/src/share/vm/opto/compile.cpp Fri Apr 29 15:23:15 2016 +0200
@@ -2867,15 +2867,20 @@
addp->Opcode() == Op_ConP &&
addp == n->in(AddPNode::Base) &&
n->in(AddPNode::Offset)->is_Con()) {
+ // If the transformation of ConP to ConN+DecodeN is beneficial depends
+ // on the platform and on the compressed oops mode.
// Use addressing with narrow klass to load with offset on x86.
- // On sparc loading 32-bits constant and decoding it have less
- // instructions (4) then load 64-bits constant (7).
+ // Some platforms can use the constant pool to load ConP.
// Do this transformation here since IGVN will convert ConN back to ConP.
const Type* t = addp->bottom_type();
- if (t->isa_oopptr() || t->isa_klassptr()) {
+ bool is_oop = t->isa_oopptr() != NULL;
+ bool is_klass = t->isa_klassptr() != NULL;
+
+ if ((is_oop && Matcher::const_oop_prefer_decode() ) ||
+ (is_klass && Matcher::const_klass_prefer_decode())) {
Node* nn = NULL;
- int op = t->isa_oopptr() ? Op_ConN : Op_ConNKlass;
+ int op = is_oop ? Op_ConN : Op_ConNKlass;
// Look for existing ConN node of the same exact type.
Node* r = root();
@@ -2891,7 +2896,7 @@
if (nn != NULL) {
// Decode a narrow oop to match address
// [R12 + narrow_oop_reg<<3 + offset]
- if (t->isa_oopptr()) {
+ if (is_oop) {
nn = new DecodeNNode(nn, t);
} else {
nn = new DecodeNKlassNode(nn, t);
--- a/hotspot/src/share/vm/opto/matcher.hpp Tue Oct 04 21:21:10 2016 +0300
+++ b/hotspot/src/share/vm/opto/matcher.hpp Fri Apr 29 15:23:15 2016 +0200
@@ -457,6 +457,9 @@
static bool narrow_oop_use_complex_address();
static bool narrow_klass_use_complex_address();
+ static bool const_oop_prefer_decode();
+ static bool const_klass_prefer_decode();
+
// Generate implicit null check for narrow oops if it can fold
// into address expression (x64).
//