hotspot/src/share/vm/opto/memnode.cpp
changeset 45766 4b5557c9b656
parent 45427 64e07017ce01
child 46735 219c4312853e
--- a/hotspot/src/share/vm/opto/memnode.cpp	Thu Jun 22 18:42:45 2017 +0000
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Fri Jun 23 09:33:21 2017 +0200
@@ -885,7 +885,7 @@
 // Is the value loaded previously stored by an arraycopy? If so return
 // a load node that reads from the source array so we may be able to
 // optimize out the ArrayCopy node later.
-Node* LoadNode::can_see_arraycopy_value(Node* st, PhaseTransform* phase) const {
+Node* LoadNode::can_see_arraycopy_value(Node* st, PhaseGVN* phase) const {
   Node* ld_adr = in(MemNode::Address);
   intptr_t ld_off = 0;
   AllocateNode* ld_alloc = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off);
@@ -893,23 +893,27 @@
   if (ac != NULL) {
     assert(ac->is_ArrayCopy(), "what kind of node can this be?");
 
-    Node* ld = clone();
+    Node* mem = ac->in(TypeFunc::Memory);
+    Node* ctl = ac->in(0);
+    Node* src = ac->in(ArrayCopyNode::Src);
+
+    if (!ac->as_ArrayCopy()->is_clonebasic() && !phase->type(src)->isa_aryptr()) {
+      return NULL;
+    }
+
+    LoadNode* ld = clone()->as_Load();
+    Node* addp = in(MemNode::Address)->clone();
     if (ac->as_ArrayCopy()->is_clonebasic()) {
       assert(ld_alloc != NULL, "need an alloc");
-      Node* addp = in(MemNode::Address)->clone();
       assert(addp->is_AddP(), "address must be addp");
       assert(addp->in(AddPNode::Base) == ac->in(ArrayCopyNode::Dest)->in(AddPNode::Base), "strange pattern");
       assert(addp->in(AddPNode::Address) == ac->in(ArrayCopyNode::Dest)->in(AddPNode::Address), "strange pattern");
-      addp->set_req(AddPNode::Base, ac->in(ArrayCopyNode::Src)->in(AddPNode::Base));
-      addp->set_req(AddPNode::Address, ac->in(ArrayCopyNode::Src)->in(AddPNode::Address));
-      ld->set_req(MemNode::Address, phase->transform(addp));
-      if (in(0) != NULL) {
-        assert(ld_alloc->in(0) != NULL, "alloc must have control");
-        ld->set_req(0, ld_alloc->in(0));
-      }
+      addp->set_req(AddPNode::Base, src->in(AddPNode::Base));
+      addp->set_req(AddPNode::Address, src->in(AddPNode::Address));
     } else {
-      Node* src = ac->in(ArrayCopyNode::Src);
-      Node* addp = in(MemNode::Address)->clone();
+      assert(ac->as_ArrayCopy()->is_arraycopy_validated() ||
+             ac->as_ArrayCopy()->is_copyof_validated() ||
+             ac->as_ArrayCopy()->is_copyofrange_validated(), "only supported cases");
       assert(addp->in(AddPNode::Base) == addp->in(AddPNode::Address), "should be");
       addp->set_req(AddPNode::Base, src);
       addp->set_req(AddPNode::Address, src);
@@ -927,21 +931,17 @@
 
       Node* offset = phase->transform(new AddXNode(addp->in(AddPNode::Offset), diff));
       addp->set_req(AddPNode::Offset, offset);
-      ld->set_req(MemNode::Address, phase->transform(addp));
-
-      const TypeX *ld_offs_t = phase->type(offset)->isa_intptr_t();
-
-      if (!ac->as_ArrayCopy()->can_replace_dest_load_with_src_load(ld_offs_t->_lo, ld_offs_t->_hi, phase)) {
-        return NULL;
-      }
-
-      if (in(0) != NULL) {
-        assert(ac->in(0) != NULL, "alloc must have control");
-        ld->set_req(0, ac->in(0));
-      }
     }
+    addp = phase->transform(addp);
+#ifdef ASSERT
+    const TypePtr* adr_type = phase->type(addp)->is_ptr();
+    ld->_adr_type = adr_type;
+#endif
+    ld->set_req(MemNode::Address, addp);
+    ld->set_req(0, ctl);
+    ld->set_req(MemNode::Memory, mem);
     // load depends on the tests that validate the arraycopy
-    ld->as_Load()->_control_dependency = Pinned;
+    ld->_control_dependency = Pinned;
     return ld;
   }
   return NULL;