8181742: Load that bypasses arraycopy has wrong memory state

Set load memory edge to the memory state right before the arraycopy.

Reviewed-by: kvn, thartmann
This commit is contained in:
Roland Westrelin 2017-06-23 09:33:21 +02:00
parent f3ee3de2a3
commit 10d189d284
6 changed files with 116 additions and 65 deletions

View file

@ -748,41 +748,3 @@ bool ArrayCopyNode::modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseTransf
return false;
}
// We try to replace a load from the destination of an arraycopy with
// a load from the source so the arraycopy has a chance to be
// eliminated. It's only valid if the arraycopy doesn't change the
// element that would be loaded from the source array.
bool ArrayCopyNode::can_replace_dest_load_with_src_load(intptr_t offset_lo, intptr_t offset_hi, PhaseTransform* phase) const {
assert(_kind == ArrayCopy || _kind == CopyOf || _kind == CopyOfRange, "only for real array copies");
Node* src = in(Src);
Node* dest = in(Dest);
// Check whether, assuming source and destination are the same
// array, the arraycopy modifies the element from the source we
// would load.
if ((src != dest && in(SrcPos) == in(DestPos)) || !modifies(offset_lo, offset_hi, phase, false)) {
// if not the transformation is legal
return true;
}
AllocateNode* src_alloc = AllocateNode::Ideal_allocation(src, phase);
AllocateNode* dest_alloc = AllocateNode::Ideal_allocation(dest, phase);
// Check whether source and destination can be proved to be
// different arrays
const TypeOopPtr* t_src = phase->type(src)->isa_oopptr();
const TypeOopPtr* t_dest = phase->type(dest)->isa_oopptr();
if (t_src != NULL && t_dest != NULL &&
(t_src->is_known_instance() || t_dest->is_known_instance()) &&
t_src->instance_id() != t_dest->instance_id()) {
return true;
}
if (MemNode::detect_ptr_independence(src->uncast(), src_alloc, dest->uncast(), dest_alloc, phase)) {
return true;
}
return false;
}