changeset 12157:5baf89bc0a4b

8155729: C2: Skip transformation of LoadConP for heap-based compressed oops Reviewed-by: kvn
author mdoerr
date Fri, 29 Apr 2016 15:23:15 +0200
parents 802c4b6f5119
children 99ba38bd0e7c d3032d8d3bc7
files src/cpu/aarch64/vm/aarch64.ad src/cpu/ppc/vm/ppc.ad src/cpu/sparc/vm/sparc.ad src/cpu/x86/vm/x86_32.ad src/cpu/x86/vm/x86_64.ad src/share/vm/opto/compile.cpp src/share/vm/opto/matcher.hpp
diffstat 7 files changed, 69 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/aarch64.ad	Tue Oct 04 21:21:10 2016 +0300
+++ b/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/src/cpu/ppc/vm/ppc.ad	Tue Oct 04 21:21:10 2016 +0300
+++ b/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/src/cpu/sparc/vm/sparc.ad	Tue Oct 04 21:21:10 2016 +0300
+++ b/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/src/cpu/x86/vm/x86_32.ad	Tue Oct 04 21:21:10 2016 +0300
+++ b/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/src/cpu/x86/vm/x86_64.ad	Tue Oct 04 21:21:10 2016 +0300
+++ b/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/src/share/vm/opto/compile.cpp	Tue Oct 04 21:21:10 2016 +0300
+++ b/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/src/share/vm/opto/matcher.hpp	Tue Oct 04 21:21:10 2016 +0300
+++ b/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).
   //