888 } |
888 } |
889 |
889 |
890 // Is the value loaded previously stored by an arraycopy? If so return |
890 // Is the value loaded previously stored by an arraycopy? If so return |
891 // a load node that reads from the source array so we may be able to |
891 // a load node that reads from the source array so we may be able to |
892 // optimize out the ArrayCopy node later. |
892 // optimize out the ArrayCopy node later. |
893 Node* LoadNode::can_see_arraycopy_value(Node* st, PhaseTransform* phase) const { |
893 Node* LoadNode::can_see_arraycopy_value(Node* st, PhaseGVN* phase) const { |
894 Node* ld_adr = in(MemNode::Address); |
894 Node* ld_adr = in(MemNode::Address); |
895 intptr_t ld_off = 0; |
895 intptr_t ld_off = 0; |
896 AllocateNode* ld_alloc = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off); |
896 AllocateNode* ld_alloc = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off); |
897 Node* ac = find_previous_arraycopy(phase, ld_alloc, st, true); |
897 Node* ac = find_previous_arraycopy(phase, ld_alloc, st, true); |
898 if (ac != NULL) { |
898 if (ac != NULL) { |
899 assert(ac->is_ArrayCopy(), "what kind of node can this be?"); |
899 assert(ac->is_ArrayCopy(), "what kind of node can this be?"); |
900 |
900 |
901 Node* ld = clone(); |
901 Node* mem = ac->in(TypeFunc::Memory); |
|
902 Node* ctl = ac->in(0); |
|
903 Node* src = ac->in(ArrayCopyNode::Src); |
|
904 |
|
905 if (!ac->as_ArrayCopy()->is_clonebasic() && !phase->type(src)->isa_aryptr()) { |
|
906 return NULL; |
|
907 } |
|
908 |
|
909 LoadNode* ld = clone()->as_Load(); |
|
910 Node* addp = in(MemNode::Address)->clone(); |
902 if (ac->as_ArrayCopy()->is_clonebasic()) { |
911 if (ac->as_ArrayCopy()->is_clonebasic()) { |
903 assert(ld_alloc != NULL, "need an alloc"); |
912 assert(ld_alloc != NULL, "need an alloc"); |
904 Node* addp = in(MemNode::Address)->clone(); |
|
905 assert(addp->is_AddP(), "address must be addp"); |
913 assert(addp->is_AddP(), "address must be addp"); |
906 assert(addp->in(AddPNode::Base) == ac->in(ArrayCopyNode::Dest)->in(AddPNode::Base), "strange pattern"); |
914 assert(addp->in(AddPNode::Base) == ac->in(ArrayCopyNode::Dest)->in(AddPNode::Base), "strange pattern"); |
907 assert(addp->in(AddPNode::Address) == ac->in(ArrayCopyNode::Dest)->in(AddPNode::Address), "strange pattern"); |
915 assert(addp->in(AddPNode::Address) == ac->in(ArrayCopyNode::Dest)->in(AddPNode::Address), "strange pattern"); |
908 addp->set_req(AddPNode::Base, ac->in(ArrayCopyNode::Src)->in(AddPNode::Base)); |
916 addp->set_req(AddPNode::Base, src->in(AddPNode::Base)); |
909 addp->set_req(AddPNode::Address, ac->in(ArrayCopyNode::Src)->in(AddPNode::Address)); |
917 addp->set_req(AddPNode::Address, src->in(AddPNode::Address)); |
910 ld->set_req(MemNode::Address, phase->transform(addp)); |
|
911 if (in(0) != NULL) { |
|
912 assert(ld_alloc->in(0) != NULL, "alloc must have control"); |
|
913 ld->set_req(0, ld_alloc->in(0)); |
|
914 } |
|
915 } else { |
918 } else { |
916 Node* src = ac->in(ArrayCopyNode::Src); |
919 assert(ac->as_ArrayCopy()->is_arraycopy_validated() || |
917 Node* addp = in(MemNode::Address)->clone(); |
920 ac->as_ArrayCopy()->is_copyof_validated() || |
|
921 ac->as_ArrayCopy()->is_copyofrange_validated(), "only supported cases"); |
918 assert(addp->in(AddPNode::Base) == addp->in(AddPNode::Address), "should be"); |
922 assert(addp->in(AddPNode::Base) == addp->in(AddPNode::Address), "should be"); |
919 addp->set_req(AddPNode::Base, src); |
923 addp->set_req(AddPNode::Base, src); |
920 addp->set_req(AddPNode::Address, src); |
924 addp->set_req(AddPNode::Address, src); |
921 |
925 |
922 const TypeAryPtr* ary_t = phase->type(in(MemNode::Address))->isa_aryptr(); |
926 const TypeAryPtr* ary_t = phase->type(in(MemNode::Address))->isa_aryptr(); |
930 #endif |
934 #endif |
931 diff = phase->transform(new LShiftXNode(diff, phase->intcon(shift))); |
935 diff = phase->transform(new LShiftXNode(diff, phase->intcon(shift))); |
932 |
936 |
933 Node* offset = phase->transform(new AddXNode(addp->in(AddPNode::Offset), diff)); |
937 Node* offset = phase->transform(new AddXNode(addp->in(AddPNode::Offset), diff)); |
934 addp->set_req(AddPNode::Offset, offset); |
938 addp->set_req(AddPNode::Offset, offset); |
935 ld->set_req(MemNode::Address, phase->transform(addp)); |
939 } |
936 |
940 addp = phase->transform(addp); |
937 const TypeX *ld_offs_t = phase->type(offset)->isa_intptr_t(); |
941 #ifdef ASSERT |
938 |
942 const TypePtr* adr_type = phase->type(addp)->is_ptr(); |
939 if (!ac->as_ArrayCopy()->can_replace_dest_load_with_src_load(ld_offs_t->_lo, ld_offs_t->_hi, phase)) { |
943 ld->_adr_type = adr_type; |
940 return NULL; |
944 #endif |
941 } |
945 ld->set_req(MemNode::Address, addp); |
942 |
946 ld->set_req(0, ctl); |
943 if (in(0) != NULL) { |
947 ld->set_req(MemNode::Memory, mem); |
944 assert(ac->in(0) != NULL, "alloc must have control"); |
|
945 ld->set_req(0, ac->in(0)); |
|
946 } |
|
947 } |
|
948 // load depends on the tests that validate the arraycopy |
948 // load depends on the tests that validate the arraycopy |
949 ld->as_Load()->_control_dependency = Pinned; |
949 ld->_control_dependency = Pinned; |
950 return ld; |
950 return ld; |
951 } |
951 } |
952 return NULL; |
952 return NULL; |
953 } |
953 } |
954 |
954 |