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