8255665: C2 should aggressively remove temporary hook nodes
Reviewed-by: chagedorn, kvn
This commit is contained in:
parent
18bc95ba51
commit
eb85b8da32
@ -2377,7 +2377,7 @@ void MemoryGraphFixer::collect_memory_nodes() {
|
||||
while (dead_phis.size() > 0) {
|
||||
Node* n = dead_phis.pop();
|
||||
n->replace_by(_phase->C->top());
|
||||
n->destruct();
|
||||
n->destruct(&_phase->igvn());
|
||||
}
|
||||
for (int i = rpo_list.size() - 1; i >= 0; i--) {
|
||||
Node* c = rpo_list.at(i);
|
||||
|
@ -183,7 +183,7 @@ Node* ArrayCopyNode::try_clone_instance(PhaseGVN *phase, bool can_reshape, int c
|
||||
|
||||
const Type* src_type = phase->type(base_src);
|
||||
|
||||
MergeMemNode* mem = MergeMemNode::make(in_mem);
|
||||
MergeMemNode* mem = phase->transform(MergeMemNode::make(in_mem))->as_MergeMem();
|
||||
|
||||
const TypeInstPtr* inst_src = src_type->isa_instptr();
|
||||
|
||||
@ -367,7 +367,7 @@ void ArrayCopyNode::array_copy_test_overlap(PhaseGVN *phase, bool can_reshape, b
|
||||
Node* ArrayCopyNode::array_copy_forward(PhaseGVN *phase,
|
||||
bool can_reshape,
|
||||
Node*& forward_ctl,
|
||||
MergeMemNode* mm,
|
||||
Node* mem,
|
||||
const TypePtr* atp_src,
|
||||
const TypePtr* atp_dest,
|
||||
Node* adr_src,
|
||||
@ -379,7 +379,7 @@ Node* ArrayCopyNode::array_copy_forward(PhaseGVN *phase,
|
||||
int count) {
|
||||
if (!forward_ctl->is_top()) {
|
||||
// copy forward
|
||||
mm = mm->clone()->as_MergeMem();
|
||||
MergeMemNode* mm = MergeMemNode::make(mem);
|
||||
|
||||
if (count > 0) {
|
||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
@ -392,7 +392,7 @@ Node* ArrayCopyNode::array_copy_forward(PhaseGVN *phase,
|
||||
v = load(bs, phase, forward_ctl, mm, next_src, atp_src, value_type, copy_type);
|
||||
store(bs, phase, forward_ctl, mm, next_dest, atp_dest, v, value_type, copy_type);
|
||||
}
|
||||
} else if(can_reshape) {
|
||||
} else if (can_reshape) {
|
||||
PhaseIterGVN* igvn = phase->is_IterGVN();
|
||||
igvn->_worklist.push(adr_src);
|
||||
igvn->_worklist.push(adr_dest);
|
||||
@ -405,7 +405,7 @@ Node* ArrayCopyNode::array_copy_forward(PhaseGVN *phase,
|
||||
Node* ArrayCopyNode::array_copy_backward(PhaseGVN *phase,
|
||||
bool can_reshape,
|
||||
Node*& backward_ctl,
|
||||
MergeMemNode* mm,
|
||||
Node* mem,
|
||||
const TypePtr* atp_src,
|
||||
const TypePtr* atp_dest,
|
||||
Node* adr_src,
|
||||
@ -417,7 +417,7 @@ Node* ArrayCopyNode::array_copy_backward(PhaseGVN *phase,
|
||||
int count) {
|
||||
if (!backward_ctl->is_top()) {
|
||||
// copy backward
|
||||
mm = mm->clone()->as_MergeMem();
|
||||
MergeMemNode* mm = MergeMemNode::make(mem);
|
||||
|
||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
assert(copy_type != T_OBJECT || !bs->array_copy_requires_gc_barriers(false, T_OBJECT, false, BarrierSetC2::Optimization), "only tightly coupled allocations for object arrays");
|
||||
@ -432,7 +432,7 @@ Node* ArrayCopyNode::array_copy_backward(PhaseGVN *phase,
|
||||
}
|
||||
Node* v = load(bs, phase, backward_ctl, mm, adr_src, atp_src, value_type, copy_type);
|
||||
store(bs, phase, backward_ctl, mm, adr_dest, atp_dest, v, value_type, copy_type);
|
||||
} else if(can_reshape) {
|
||||
} else if (can_reshape) {
|
||||
PhaseIterGVN* igvn = phase->is_IterGVN();
|
||||
igvn->_worklist.push(adr_src);
|
||||
igvn->_worklist.push(adr_dest);
|
||||
@ -564,11 +564,7 @@ Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
Node* dest = in(ArrayCopyNode::Dest);
|
||||
const TypePtr* atp_src = get_address_type(phase, _src_type, src);
|
||||
const TypePtr* atp_dest = get_address_type(phase, _dest_type, dest);
|
||||
|
||||
Node *in_mem = in(TypeFunc::Memory);
|
||||
if (!in_mem->is_MergeMem()) {
|
||||
in_mem = MergeMemNode::make(in_mem);
|
||||
}
|
||||
Node* in_mem = in(TypeFunc::Memory);
|
||||
|
||||
if (can_reshape) {
|
||||
assert(!phase->is_IterGVN()->delay_transform(), "cannot delay transforms");
|
||||
@ -580,13 +576,13 @@ Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
array_copy_test_overlap(phase, can_reshape, disjoint_bases, count, forward_ctl, backward_ctl);
|
||||
|
||||
Node* forward_mem = array_copy_forward(phase, can_reshape, forward_ctl,
|
||||
in_mem->as_MergeMem(),
|
||||
in_mem,
|
||||
atp_src, atp_dest,
|
||||
adr_src, base_src, adr_dest, base_dest,
|
||||
copy_type, value_type, count);
|
||||
|
||||
Node* backward_mem = array_copy_backward(phase, can_reshape, backward_ctl,
|
||||
in_mem->as_MergeMem(),
|
||||
in_mem,
|
||||
atp_src, atp_dest,
|
||||
adr_src, base_src, adr_dest, base_dest,
|
||||
copy_type, value_type, count);
|
||||
|
@ -100,12 +100,12 @@ private:
|
||||
bool disjoint_bases, int count,
|
||||
Node*& forward_ctl, Node*& backward_ctl);
|
||||
Node* array_copy_forward(PhaseGVN *phase, bool can_reshape, Node*& ctl,
|
||||
MergeMemNode* mm,
|
||||
Node* mem,
|
||||
const TypePtr* atp_src, const TypePtr* atp_dest,
|
||||
Node* adr_src, Node* base_src, Node* adr_dest, Node* base_dest,
|
||||
BasicType copy_type, const Type* value_type, int count);
|
||||
Node* array_copy_backward(PhaseGVN *phase, bool can_reshape, Node*& ctl,
|
||||
MergeMemNode* mm,
|
||||
Node* mem,
|
||||
const TypePtr* atp_src, const TypePtr* atp_dest,
|
||||
Node* adr_src, Node* base_src, Node* adr_dest, Node* base_dest,
|
||||
BasicType copy_type, const Type* value_type, int count);
|
||||
|
@ -2302,12 +2302,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
Node* phi = mms.memory();
|
||||
mms.set_memory(phase->transform(phi));
|
||||
}
|
||||
if (igvn) { // Unhook.
|
||||
igvn->hash_delete(hook);
|
||||
for (uint i = 1; i < hook->req(); i++) {
|
||||
hook->set_req(i, NULL);
|
||||
}
|
||||
}
|
||||
hook->destruct(igvn);
|
||||
// Replace self with the result.
|
||||
return result;
|
||||
}
|
||||
|
@ -1128,8 +1128,7 @@ void Compile::print_missing_nodes() {
|
||||
}
|
||||
}
|
||||
void Compile::record_modified_node(Node* n) {
|
||||
if (_modified_nodes != NULL && !_inlining_incrementally &&
|
||||
n->outcnt() != 0 && !n->is_Con()) {
|
||||
if (_modified_nodes != NULL && !_inlining_incrementally && !n->is_Con()) {
|
||||
_modified_nodes->push(n);
|
||||
}
|
||||
}
|
||||
|
@ -403,8 +403,7 @@ Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
Node *hook = new Node(1);
|
||||
hook->init_req(0, cx); // Add a use to cx to prevent him from dying
|
||||
Node* cy = phase->C->constrained_convI2L(phase, y, TypeInt::make(rylo, ryhi, widen), NULL);
|
||||
hook->del_req(0); // Just yank bogus edge
|
||||
hook->destruct();
|
||||
hook->destruct(phase);
|
||||
switch (op) {
|
||||
case Op_AddI: return new AddLNode(cx, cy);
|
||||
case Op_SubI: return new SubLNode(cx, cy);
|
||||
|
@ -326,14 +326,7 @@ static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_con
|
||||
Node* temp2 = phase->transform(new RShiftLNode(w1, phase->intcon(N / 2)));
|
||||
|
||||
// Remove the bogus extra edges used to keep things alive
|
||||
PhaseIterGVN* igvn = phase->is_IterGVN();
|
||||
if (igvn != NULL) {
|
||||
igvn->remove_dead_node(hook);
|
||||
} else {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
hook->set_req(i, NULL);
|
||||
}
|
||||
}
|
||||
hook->destruct(phase);
|
||||
|
||||
return new AddLNode(temp1, temp2);
|
||||
}
|
||||
@ -916,11 +909,7 @@ Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// cmov2 is now the mod
|
||||
|
||||
// Now remove the bogus extra edges used to keep things alive
|
||||
if (can_reshape) {
|
||||
phase->is_IterGVN()->remove_dead_node(hook);
|
||||
} else {
|
||||
hook->set_req(0, NULL); // Just yank bogus edge during Parse phase
|
||||
}
|
||||
hook->destruct(phase);
|
||||
return cmov2;
|
||||
}
|
||||
}
|
||||
@ -972,11 +961,7 @@ Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
}
|
||||
|
||||
// Now remove the bogus extra edges used to keep things alive
|
||||
if (can_reshape) {
|
||||
phase->is_IterGVN()->remove_dead_node(hook);
|
||||
} else {
|
||||
hook->set_req(0, NULL); // Just yank bogus edge during Parse phase
|
||||
}
|
||||
hook->destruct(phase);
|
||||
|
||||
// return the value
|
||||
return result;
|
||||
@ -1091,11 +1076,7 @@ Node *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// cmov2 is now the mod
|
||||
|
||||
// Now remove the bogus extra edges used to keep things alive
|
||||
if (can_reshape) {
|
||||
phase->is_IterGVN()->remove_dead_node(hook);
|
||||
} else {
|
||||
hook->set_req(0, NULL); // Just yank bogus edge during Parse phase
|
||||
}
|
||||
hook->destruct(phase);
|
||||
return cmov2;
|
||||
}
|
||||
}
|
||||
@ -1147,11 +1128,7 @@ Node *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
}
|
||||
|
||||
// Now remove the bogus extra edges used to keep things alive
|
||||
if (can_reshape) {
|
||||
phase->is_IterGVN()->remove_dead_node(hook);
|
||||
} else {
|
||||
hook->set_req(0, NULL); // Just yank bogus edge during Parse phase
|
||||
}
|
||||
hook->destruct(phase);
|
||||
|
||||
// return the value
|
||||
return result;
|
||||
|
@ -999,8 +999,7 @@ bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* f
|
||||
if (adjusted_lim == NULL) {
|
||||
adjusted_lim = igvn->transform(new SubINode(hi, lo));
|
||||
}
|
||||
hook->del_req(0); // Just yank bogus edge
|
||||
hook->destruct();
|
||||
hook->destruct(igvn);
|
||||
Node* newcmp = igvn->transform(new CmpUNode(adjusted_val, adjusted_lim));
|
||||
Node* newbool = igvn->transform(new BoolNode(newcmp, cond));
|
||||
|
||||
|
@ -430,7 +430,7 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo
|
||||
tmp1->replace_by(tmp);
|
||||
tmp2->replace_by(tmp1);
|
||||
tmp->replace_by(tmp2);
|
||||
tmp->destruct();
|
||||
tmp->destruct(NULL);
|
||||
}
|
||||
|
||||
// Remove the existing null check; use a new implicit null check instead.
|
||||
|
@ -727,7 +727,7 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
|
||||
idx_type = (TypeInt*)mul->mul_ring(idx_type, scale_type);
|
||||
if (overflow || TypeInt::INT->higher_equal(idx_type)) {
|
||||
// May overflow
|
||||
mul->destruct();
|
||||
mul->destruct(&_igvn);
|
||||
if (!overflow) {
|
||||
max_idx_expr = new ConvI2LNode(max_idx_expr);
|
||||
register_new_node(max_idx_expr, ctrl);
|
||||
|
@ -1400,8 +1400,6 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*& loop) {
|
||||
assert(x->Opcode() == Op_Loop, "regular loops only");
|
||||
C->print_method(PHASE_BEFORE_CLOOPS, 3);
|
||||
|
||||
Node *hook = new Node(6);
|
||||
|
||||
// ===================================================
|
||||
// Generate loop limit check to avoid integer overflow
|
||||
// in cases like next (cyclic loops):
|
||||
@ -1691,9 +1689,6 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*& loop) {
|
||||
}
|
||||
}
|
||||
|
||||
// Free up intermediate goo
|
||||
_igvn.remove_dead_node(hook);
|
||||
|
||||
#ifdef ASSERT
|
||||
assert(l->is_valid_counted_loop(), "counted loop shape is messed up");
|
||||
assert(l == loop->_head && l->phi() == phi && l->loopexit_or_null() == lex, "" );
|
||||
@ -2656,7 +2651,7 @@ void IdealLoopTree::split_fall_in( PhaseIdealLoop *phase, int fall_in_cnt ) {
|
||||
// with the CSE to avoid O(N^2) node blow-up.
|
||||
Node *p2 = igvn.hash_find_insert(p); // Look for a CSE
|
||||
if( p2 ) { // Found CSE
|
||||
p->destruct(); // Recover useless new node
|
||||
p->destruct(&igvn); // Recover useless new node
|
||||
p = p2; // Use old node
|
||||
} else {
|
||||
igvn.register_new_node_with_optimizer(p, old_phi);
|
||||
|
@ -329,7 +329,7 @@ Node* PhaseMacroExpand::make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset,
|
||||
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);
|
||||
MergeMemNode* mergemen = MergeMemNode::make(mem);
|
||||
MergeMemNode* mergemen = _igvn.transform(MergeMemNode::make(mem))->as_MergeMem();
|
||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
res = ArrayCopyNode::load(bs, &_igvn, ctl, mergemen, adr, adr_type, type, bt);
|
||||
} else {
|
||||
@ -369,7 +369,7 @@ Node* PhaseMacroExpand::make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
MergeMemNode* mergemen = MergeMemNode::make(mem);
|
||||
MergeMemNode* mergemen = _igvn.transform(MergeMemNode::make(mem))->as_MergeMem();
|
||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
res = ArrayCopyNode::load(bs, &_igvn, ctl, mergemen, adr, adr_type, type, bt);
|
||||
}
|
||||
|
@ -581,8 +581,11 @@ void Node::setup_is_top() {
|
||||
|
||||
//------------------------------~Node------------------------------------------
|
||||
// Fancy destructor; eagerly attempt to reclaim Node numberings and storage
|
||||
void Node::destruct() {
|
||||
Compile* compile = Compile::current();
|
||||
void Node::destruct(PhaseValues* phase) {
|
||||
Compile* compile = (phase != NULL) ? phase->C : Compile::current();
|
||||
if (phase != NULL && phase->is_IterGVN()) {
|
||||
phase->is_IterGVN()->_worklist.remove(this);
|
||||
}
|
||||
// If this is the most recently created node, reclaim its index. Otherwise,
|
||||
// record the node as dead to keep liveness information accurate.
|
||||
if ((uint)_idx+1 == compile->unique()) {
|
||||
@ -1399,7 +1402,6 @@ static void kill_dead_code( Node *dead, PhaseIterGVN *igvn ) {
|
||||
// Done with outputs.
|
||||
igvn->hash_delete(dead);
|
||||
igvn->_worklist.remove(dead);
|
||||
igvn->C->remove_modified_node(dead);
|
||||
igvn->set_type(dead, Type::TOP);
|
||||
if (dead->is_macro()) {
|
||||
igvn->C->remove_macro_node(dead);
|
||||
@ -1435,6 +1437,7 @@ static void kill_dead_code( Node *dead, PhaseIterGVN *igvn ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
igvn->C->remove_modified_node(dead);
|
||||
} // (dead->outcnt() == 0)
|
||||
} // while (nstack.size() > 0) for outputs
|
||||
return;
|
||||
|
@ -236,7 +236,7 @@ public:
|
||||
// Delete is a NOP
|
||||
void operator delete( void *ptr ) {}
|
||||
// Fancy destructor; eagerly attempt to reclaim Node numberings and storage
|
||||
void destruct();
|
||||
void destruct(PhaseValues* phase);
|
||||
|
||||
// Create a new Node. Required is the number is of inputs required for
|
||||
// semantic correctness.
|
||||
|
@ -749,7 +749,7 @@ ConNode* PhaseValues::uncached_makecon(const Type *t) {
|
||||
loc->clear(); // do not put debug info on constants
|
||||
}
|
||||
} else {
|
||||
x->destruct(); // Hit, destroy duplicate constant
|
||||
x->destruct(this); // Hit, destroy duplicate constant
|
||||
x = k; // use existing constant
|
||||
}
|
||||
return x;
|
||||
@ -1069,9 +1069,9 @@ void PhaseIterGVN::init_verifyPhaseIterGVN() {
|
||||
Unique_Node_List* modified_list = C->modified_nodes();
|
||||
while (modified_list != NULL && modified_list->size()) {
|
||||
Node* n = modified_list->pop();
|
||||
if (n->outcnt() != 0 && !n->is_Con() && !_worklist.member(n)) {
|
||||
if (!n->is_Con() && !_worklist.member(n)) {
|
||||
n->dump();
|
||||
assert(false, "modified node is not on IGVN._worklist");
|
||||
fatal("modified node is not on IGVN._worklist");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1083,9 +1083,9 @@ void PhaseIterGVN::verify_PhaseIterGVN() {
|
||||
Unique_Node_List* modified_list = C->modified_nodes();
|
||||
while (modified_list != NULL && modified_list->size()) {
|
||||
Node* n = modified_list->pop();
|
||||
if (n->outcnt() != 0 && !n->is_Con()) { // skip dead and Con nodes
|
||||
if (!n->is_Con()) { // skip Con nodes
|
||||
n->dump();
|
||||
assert(false, "modified node was not processed by IGVN.transform_old()");
|
||||
fatal("modified node was not processed by IGVN.transform_old()");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1472,8 +1472,7 @@ void PhaseIterGVN::subsume_node( Node *old, Node *nn ) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
_worklist.remove(temp); // this can be necessary
|
||||
temp->destruct(); // reuse the _idx of this little guy
|
||||
temp->destruct(this); // reuse the _idx of this little guy
|
||||
}
|
||||
|
||||
//------------------------------add_users_to_worklist--------------------------
|
||||
|
@ -337,7 +337,7 @@ Node *PhaseIdealLoop::spinup( Node *iff_dom, Node *new_false, Node *new_true, No
|
||||
if( t ) { // See if we already have this one
|
||||
// phi_post will not be used, so kill it
|
||||
_igvn.remove_dead_node(phi_post);
|
||||
phi_post->destruct();
|
||||
phi_post->destruct(&_igvn);
|
||||
phi_post = t;
|
||||
} else {
|
||||
register_new_node( phi_post, prior_n );
|
||||
|
Loading…
Reference in New Issue
Block a user