changeset 49461:b82b45a1fae5 lworld

[lworld] Fixed scalarization for flattened value type arrays
author thartmann
date Tue, 27 Mar 2018 17:54:25 +0200
parents b53e2a635454
children cdd867831958
files src/hotspot/share/opto/addnode.cpp src/hotspot/share/opto/callnode.cpp src/hotspot/share/opto/machnode.cpp src/hotspot/share/opto/macro.cpp src/hotspot/share/opto/type.cpp src/hotspot/share/opto/type.hpp test/hotspot/jtreg/compiler/valhalla/valuetypes/TestArrays.java
diffstat 7 files changed, 65 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/opto/addnode.cpp	Mon Mar 26 11:41:51 2018 -0700
+++ b/src/hotspot/share/opto/addnode.cpp	Tue Mar 27 17:54:25 2018 +0200
@@ -659,7 +659,7 @@
     // In the case of a flattened value type array, each field has its
     // own slice so we need to extract the field being accessed from
     // the address computation
-    return tp->is_aryptr()->with_field_offset_and_offset(txoffset);
+    return tp->is_aryptr()->add_field_offset_and_offset(txoffset);
   }
   return tp->add_offset(txoffset);
 }
@@ -685,7 +685,7 @@
     // In the case of a flattened value type array, each field has its
     // own slice so we need to extract the field being accessed from
     // the address computation
-    return p1->is_aryptr()->with_field_offset_and_offset(p2offset);
+    return p1->is_aryptr()->add_field_offset_and_offset(p2offset);
   }
   return p1->add_offset(p2offset);
 }
--- a/src/hotspot/share/opto/callnode.cpp	Mon Mar 26 11:41:51 2018 -0700
+++ b/src/hotspot/share/opto/callnode.cpp	Tue Mar 27 17:54:25 2018 +0200
@@ -479,6 +479,14 @@
         while (ndim-- > 0) {
           st->print("[]");
         }
+      } else if (cik->is_value_array_klass()) {
+        ciKlass* cie = cik->as_value_array_klass()->base_element_klass();
+        cie->print_name_on(st);
+        st->print("[%d]", spobj->n_fields());
+        int ndim = cik->as_array_klass()->dimension() - 1;
+        while (ndim-- > 0) {
+          st->print("[]");
+        }
       }
       st->print("={");
       uint nf = spobj->n_fields();
--- a/src/hotspot/share/opto/machnode.cpp	Mon Mar 26 11:41:51 2018 -0700
+++ b/src/hotspot/share/opto/machnode.cpp	Tue Mar 27 17:54:25 2018 +0200
@@ -390,10 +390,10 @@
       const MachOper* oper = memory_inputs(base, index);
       if (oper != (MachOper*)-1) {
         offset = oper->constant_disp();
-        return tp->is_aryptr()->with_field_offset_and_offset(offset)->add_offset(Type::OffsetBot);
+        return tp->is_aryptr()->add_field_offset_and_offset(offset)->add_offset(Type::OffsetBot);
       }
     }
-    return tp->is_aryptr()->with_field_offset_and_offset(offset);
+    return tp->is_aryptr()->add_field_offset_and_offset(offset);
   }
 
   return tp->add_offset(offset);
--- a/src/hotspot/share/opto/macro.cpp	Mon Mar 26 11:41:51 2018 -0700
+++ b/src/hotspot/share/opto/macro.cpp	Tue Mar 27 17:54:25 2018 +0200
@@ -366,7 +366,7 @@
       int adr_idx = phase->C->get_alias_index(atype);
       if (adr_idx == alias_idx) {
         assert(atype->isa_oopptr(), "address type must be oopptr");
-        int adr_offset = atype->offset();
+        int adr_offset = atype->is_oopptr()->flattened_offset();
         uint adr_iid = atype->is_oopptr()->instance_id();
         // Array elements references have the same alias_idx
         // but different offset and different instance_id.
@@ -477,7 +477,7 @@
 Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, AllocateNode *alloc, Node_Stack *value_phis, int level) {
   assert(mem->is_Phi(), "sanity");
   int alias_idx = C->get_alias_index(adr_t);
-  int offset = adr_t->offset();
+  int offset = adr_t->flattened_offset();
   int instance_id = adr_t->instance_id();
 
   // Check if an appropriate value phi already exists.
@@ -576,14 +576,7 @@
   assert((uint)instance_id == alloc->_idx, "wrong allocation");
 
   int alias_idx = C->get_alias_index(adr_t);
-  int offset = adr_t->offset();
-  if (adr_t->isa_aryptr()) {
-    int field_offset = adr_t->isa_aryptr()->field_offset().get();
-    if (field_offset != Type::OffsetBot) {
-      // Increment offset by the field offset for flattened value type arrays
-      offset += field_offset;
-    }
-  }
+  int offset = adr_t->flattened_offset();
   Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
   Node *alloc_ctrl = alloc->in(TypeFunc::Control);
   Node *alloc_mem = alloc->in(TypeFunc::Memory);
@@ -612,7 +605,7 @@
       const TypeOopPtr* atype = mem->as_Store()->adr_type()->isa_oopptr();
       assert(atype != NULL, "address type must be oopptr");
       assert(C->get_alias_index(atype) == alias_idx &&
-             atype->is_known_instance_field() && atype->offset() == offset &&
+             atype->is_known_instance_field() && atype->flattened_offset() == offset &&
              atype->instance_id() == instance_id, "store is correct memory slice");
       done = true;
     } else if (mem->is_Phi()) {
--- a/src/hotspot/share/opto/type.cpp	Mon Mar 26 11:41:51 2018 -0700
+++ b/src/hotspot/share/opto/type.cpp	Tue Mar 27 17:54:25 2018 +0200
@@ -3619,6 +3619,10 @@
   return make(_ptr, xadd_offset(offset), _instance_id, add_offset_speculative(offset), _inline_depth);
 }
 
+const int TypeOopPtr::flattened_offset() const {
+  return offset();
+}
+
 /**
  * Return same type without a speculative part
  */
@@ -4754,7 +4758,7 @@
   return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, Offset(offset), _instance_id, _speculative, _inline_depth, _is_autobox_cache);
 }
 
-const TypePtr* TypeAryPtr::with_field_offset_and_offset(intptr_t offset) const {
+const TypePtr* TypeAryPtr::add_field_offset_and_offset(intptr_t offset) const {
   int adj = 0;
   if (offset != Type::OffsetBot && offset != Type::OffsetTop) {
     const Type* elemtype = elem();
@@ -4791,6 +4795,15 @@
   return add_offset(offset - adj);
 }
 
+// Return offset incremented by field_offset for flattened value type arrays
+const int TypeAryPtr::flattened_offset() const {
+  int offset = _offset.get();
+  if (_field_offset != Offset::bottom && _field_offset != Offset::top) {
+    offset += _field_offset.get();
+  }
+  return offset;
+}
+
 //=============================================================================
 
 
--- a/src/hotspot/share/opto/type.hpp	Mon Mar 26 11:41:51 2018 -0700
+++ b/src/hotspot/share/opto/type.hpp	Tue Mar 27 17:54:25 2018 +0200
@@ -1098,6 +1098,7 @@
   const TypeKlassPtr* as_klass_type() const;
 
   virtual const TypePtr *add_offset( intptr_t offset ) const;
+  virtual const int flattened_offset() const;
 
   // Speculative type helper methods.
   virtual const Type* remove_speculative() const;
@@ -1288,9 +1289,10 @@
 
   const TypeAryPtr* cast_to_autobox_cache(bool cache) const;
 
+  const int flattened_offset() const;
   const Offset field_offset() const { return _field_offset; }
   const TypeAryPtr* with_field_offset(int offset) const;
-  const TypePtr* with_field_offset_and_offset(intptr_t offset) const;
+  const TypePtr* add_field_offset_and_offset(intptr_t offset) const;
 
   // Convenience common pre-built types.
   static const TypeAryPtr *RANGE;
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestArrays.java	Mon Mar 26 11:41:51 2018 -0700
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestArrays.java	Tue Mar 27 17:54:25 2018 +0200
@@ -666,9 +666,9 @@
 
     @DontCompile
     public void test28_verifier(boolean warmup) {
-        MyValue2 va = MyValue2.createWithFieldsInline(rI, false);
+        MyValue2 v = MyValue2.createWithFieldsInline(rI, false);
         MyValue2 result = test28();
-        Asserts.assertEQ(result.hash(), va.hash());
+        Asserts.assertEQ(result.hash(), v.hash());
     }
 
     // non escaping allocations
@@ -685,8 +685,8 @@
         for (int i = 0; i < 10; ++i) {
             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
         }
-        MyValue2 va = test29(src);
-        Asserts.assertEQ(src[0].hash(), va.hash());
+        MyValue2 v = test29(src);
+        Asserts.assertEQ(src[0].hash(), v.hash());
     }
 
     // non escaping allocation with uncommon trap that needs
@@ -706,7 +706,33 @@
         for (int i = 0; i < 10; ++i) {
             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
         }
-        MyValue2 va = test30(src, false);
-        Asserts.assertEQ(src[0].hash(), va.hash());
+        MyValue2 v = test30(src, false);
+        Asserts.assertEQ(src[0].hash(), v.hash());
+    }
+
+    // non escaping allocation with memory phi
+    @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + LOADP + TRAP)
+    public long test31(boolean b, boolean deopt) {
+        MyValue2[] src = new MyValue2[1];
+        if (b) {
+            src[0] = MyValue2.createWithFieldsInline(rI, true);
+        } else {
+            src[0] = MyValue2.createWithFieldsInline(rI, false);
+        }
+        if (deopt) {
+            // uncommon trap
+            WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test31"));
+        }
+        return src[0].hash();
+    }
+
+    @DontCompile
+    public void test31_verifier(boolean warmup) {
+        MyValue2 v1 = MyValue2.createWithFieldsInline(rI, true);
+        long result1 = test31(true, !warmup);
+        Asserts.assertEQ(result1, v1.hash());
+        MyValue2 v2 = MyValue2.createWithFieldsInline(rI, false);
+        long result2 = test31(false, !warmup);
+        Asserts.assertEQ(result2, v2.hash());
     }
 }