Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8242457: [lworld] Cherry pick and adjust JDK-8241997 for Valhalla #18

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -315,7 +315,7 @@ Node* PhaseMacroExpand::make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset,
Node* res = NULL;
if (ac->is_clonebasic()) {
assert(ac->in(ArrayCopyNode::Src) != ac->in(ArrayCopyNode::Dest), "clone source equals destination");
Node* base = ac->in(ArrayCopyNode::Src)->in(AddPNode::Base);
Node* base = ac->in(ArrayCopyNode::Src);
Node* adr = _igvn.transform(new AddPNode(base, base, MakeConX(offset)));
const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset);
res = LoadNode::make(_igvn, ctl, mem, adr, adr_type, type, bt, MemNode::unordered, LoadNode::UnknownControl);
@@ -681,11 +681,8 @@ bool PhaseMacroExpand::can_eliminate_allocation(AllocateNode *alloc, GrowableArr
for (DUIterator_Fast kmax, k = use->fast_outs(kmax);
k < kmax && can_eliminate; k++) {
Node* n = use->fast_out(k);
if (!n->is_Store() && n->Opcode() != Op_CastP2X &&
SHENANDOAHGC_ONLY((!UseShenandoahGC || !ShenandoahBarrierSetC2::is_shenandoah_wb_pre_call(n)) &&)
!(n->is_ArrayCopy() &&
n->as_ArrayCopy()->is_clonebasic() &&
n->in(ArrayCopyNode::Dest) == use)) {
if (!n->is_Store() && n->Opcode() != Op_CastP2X
SHENANDOAHGC_ONLY(&& (!UseShenandoahGC || !ShenandoahBarrierSetC2::is_shenandoah_wb_pre_call(n))) ) {
DEBUG_ONLY(disq_node = n;)
if (n->is_Load() || n->is_LoadStore()) {
NOT_PRODUCT(fail_eliminate = "Field load";)
@@ -696,7 +693,8 @@ bool PhaseMacroExpand::can_eliminate_allocation(AllocateNode *alloc, GrowableArr
}
}
} else if (use->is_ArrayCopy() &&
(use->as_ArrayCopy()->is_arraycopy_validated() ||
(use->as_ArrayCopy()->is_clonebasic() ||
use->as_ArrayCopy()->is_arraycopy_validated() ||
use->as_ArrayCopy()->is_copyof_validated() ||
use->as_ArrayCopy()->is_copyofrange_validated()) &&
use->in(ArrayCopyNode::Dest) == res) {
@@ -1008,18 +1006,6 @@ void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
}
#endif
_igvn.replace_node(n, n->in(MemNode::Memory));
} else if (n->is_ArrayCopy()) {
// Disconnect ArrayCopy node
ArrayCopyNode* ac = n->as_ArrayCopy();
assert(ac->is_clonebasic(), "unexpected array copy kind");
Node* membar_after = ac->proj_out(TypeFunc::Control)->unique_ctrl_out();
disconnect_projections(ac, _igvn);
assert(alloc->in(0)->is_Proj() && alloc->in(0)->in(0)->Opcode() == Op_MemBarCPUOrder, "mem barrier expected before allocation");
Node* membar_before = alloc->in(0)->in(0);
disconnect_projections(membar_before->as_MemBar(), _igvn);
if (membar_after->is_MemBar()) {
disconnect_projections(membar_after->as_MemBar(), _igvn);
}
} else {
eliminate_gc_barrier(n);
}
@@ -1029,29 +1015,39 @@ void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
} else if (use->is_ArrayCopy()) {
// Disconnect ArrayCopy node
ArrayCopyNode* ac = use->as_ArrayCopy();
assert(ac->is_arraycopy_validated() ||
ac->is_copyof_validated() ||
ac->is_copyofrange_validated(), "unsupported");
CallProjections* callprojs = ac->extract_projections(true);

_igvn.replace_node(callprojs->fallthrough_ioproj, ac->in(TypeFunc::I_O));
_igvn.replace_node(callprojs->fallthrough_memproj, ac->in(TypeFunc::Memory));
_igvn.replace_node(callprojs->fallthrough_catchproj, ac->in(TypeFunc::Control));

// Set control to top. IGVN will remove the remaining projections
ac->set_req(0, top());
ac->replace_edge(res, top());

// Disconnect src right away: it can help find new
// opportunities for allocation elimination
Node* src = ac->in(ArrayCopyNode::Src);
ac->replace_edge(src, top());
// src can be top at this point if src and dest of the
// arraycopy were the same
if (src->outcnt() == 0 && !src->is_top()) {
_igvn.remove_dead_node(src);
if (ac->is_clonebasic()) {
Node* membar_after = ac->proj_out(TypeFunc::Control)->unique_ctrl_out();
disconnect_projections(ac, _igvn);
assert(alloc->in(0)->is_Proj() && alloc->in(0)->in(0)->Opcode() == Op_MemBarCPUOrder, "mem barrier expected before allocation");
Node* membar_before = alloc->in(0)->in(0);
disconnect_projections(membar_before->as_MemBar(), _igvn);
if (membar_after->is_MemBar()) {
disconnect_projections(membar_after->as_MemBar(), _igvn);
}
} else {
assert(ac->is_arraycopy_validated() ||
ac->is_copyof_validated() ||
ac->is_copyofrange_validated(), "unsupported");
CallProjections* callprojs = ac->extract_projections(true);

_igvn.replace_node(callprojs->fallthrough_ioproj, ac->in(TypeFunc::I_O));
_igvn.replace_node(callprojs->fallthrough_memproj, ac->in(TypeFunc::Memory));
_igvn.replace_node(callprojs->fallthrough_catchproj, ac->in(TypeFunc::Control));

// Set control to top. IGVN will remove the remaining projections
ac->set_req(0, top());
ac->replace_edge(res, top());

// Disconnect src right away: it can help find new
// opportunities for allocation elimination
Node* src = ac->in(ArrayCopyNode::Src);
ac->replace_edge(src, top());
// src can be top at this point if src and dest of the
// arraycopy were the same
if (src->outcnt() == 0 && !src->is_top()) {
_igvn.remove_dead_node(src);
}
}

_igvn._worklist.push(ac);
} else if (use->is_ValueType()) {
assert(use->isa_ValueType()->get_oop() == res, "unexpected value type use");
@@ -539,8 +539,7 @@ Node* LoadNode::find_previous_arraycopy(PhaseTransform* phase, Node* ld_alloc, N
mb->in(0)->in(0) != NULL && mb->in(0)->in(0)->is_ArrayCopy()) {
ArrayCopyNode* ac = mb->in(0)->in(0)->as_ArrayCopy();
if (ac->is_clonebasic()) {
intptr_t offset;
AllocateNode* alloc = AllocateNode::Ideal_allocation(ac->in(ArrayCopyNode::Dest), phase, offset);
AllocateNode* alloc = AllocateNode::Ideal_allocation(ac->in(ArrayCopyNode::Dest), phase);
if (alloc != NULL && alloc == ld_alloc) {
return ac;
}
@@ -948,12 +947,11 @@ Node* LoadNode::can_see_arraycopy_value(Node* st, PhaseGVN* phase) const {
if (ac->as_ArrayCopy()->is_clonebasic()) {
assert(ld_alloc != NULL, "need an alloc");
assert(addp->is_AddP(), "address must be addp");
assert(ac->in(ArrayCopyNode::Dest)->is_AddP(), "dest must be an address");
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
assert(bs->step_over_gc_barrier(addp->in(AddPNode::Base)) == bs->step_over_gc_barrier(ac->in(ArrayCopyNode::Dest)->in(AddPNode::Base)), "strange pattern");
assert(bs->step_over_gc_barrier(addp->in(AddPNode::Address)) == bs->step_over_gc_barrier(ac->in(ArrayCopyNode::Dest)->in(AddPNode::Address)), "strange pattern");
addp->set_req(AddPNode::Base, src->in(AddPNode::Base));
addp->set_req(AddPNode::Address, src->in(AddPNode::Address));
assert(bs->step_over_gc_barrier(addp->in(AddPNode::Base)) == bs->step_over_gc_barrier(ac->in(ArrayCopyNode::Dest)), "strange pattern");
assert(bs->step_over_gc_barrier(addp->in(AddPNode::Address)) == bs->step_over_gc_barrier(ac->in(ArrayCopyNode::Dest)), "strange pattern");
addp->set_req(AddPNode::Base, src);
addp->set_req(AddPNode::Address, src);
} else {
assert(ac->as_ArrayCopy()->is_arraycopy_validated() ||
ac->as_ArrayCopy()->is_copyof_validated() ||