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

8263577: C2: reachable nodes shouldn't have dead uses at the end of optimizations #3012

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
Expand Up @@ -1066,7 +1066,7 @@ void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const Mem
is_dominator_same_ctrl(old_c, barrier, u, phase) ||
ShenandoahBarrierSetC2::is_shenandoah_state_load(u)) {
phase->igvn().rehash_node_delayed(u);
int nb = u->replace_edge(ctrl, region);
int nb = u->replace_edge(ctrl, region, &phase->igvn());
if (u->is_CFG()) {
if (phase->idom(u) == ctrl) {
phase->set_idom(u, region, phase->dom_depth(region));
Expand Down Expand Up @@ -1248,7 +1248,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
stack.push(u, 0);
assert(!cloned.test_set(u->_idx), "only one clone");
Node* u_clone = u->clone();
int nb = u_clone->replace_edge(n, n_clone);
int nb = u_clone->replace_edge(n, n_clone, &phase->igvn());
assert(nb > 0, "should have replaced some uses");
phase->register_new_node(u_clone, projs.catchall_catchproj);
clones.push(u_clone);
Expand All @@ -1270,7 +1270,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
} else {
if (phase->is_dominator(projs.catchall_catchproj, c)) {
phase->igvn().rehash_node_delayed(u);
int nb = u->replace_edge(n, n_clone);
int nb = u->replace_edge(n, n_clone, &phase->igvn());
assert(nb > 0, "should have replaced some uses");
replaced = true;
} else if (!phase->is_dominator(projs.fallthrough_catchproj, c)) {
Expand All @@ -1288,7 +1288,8 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
Node* nn_clone = clones.at(clones.size()-3);
assert(nn->Opcode() == nn_clone->Opcode(), "mismatch");

int nb = cmp_clone->replace_edge(nn, create_phis_on_call_return(ctrl, c, nn, nn_clone, projs, phase));
int nb = cmp_clone->replace_edge(nn, create_phis_on_call_return(ctrl, c, nn, nn_clone, projs, phase),
&phase->igvn());
assert(nb > 0, "should have replaced some uses");

phase->register_new_node(bol_clone, u->in(0));
Expand All @@ -1298,7 +1299,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {

} else {
phase->igvn().rehash_node_delayed(u);
int nb = u->replace_edge(n, create_phis_on_call_return(ctrl, c, n, n_clone, projs, phase));
int nb = u->replace_edge(n, create_phis_on_call_return(ctrl, c, n, n_clone, projs, phase), &phase->igvn());
assert(nb > 0, "should have replaced some uses");
}
replaced = true;
Expand Down
28 changes: 8 additions & 20 deletions src/hotspot/share/opto/addnode.cpp
Expand Up @@ -145,14 +145,8 @@ Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// The Add of the flattened expression
Node *x1 = add1->in(1);
Node *x2 = phase->makecon(add1->as_Add()->add_ring(t2, t12));
PhaseIterGVN *igvn = phase->is_IterGVN();
if (igvn) {
set_req_X(2,x2,igvn);
set_req_X(1,x1,igvn);
} else {
set_req(2,x2);
set_req(1,x1);
}
set_req_X(2, x2, phase);
set_req_X(1, x1, phase);
progress = this; // Made progress
add1 = in(1);
add1_op = add1->Opcode();
Expand All @@ -169,8 +163,8 @@ Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) {
add2 = add1->clone();
add2->set_req(2, in(2));
add2 = phase->transform(add2);
set_req(1, add2);
set_req(2, a12);
set_req_X(1, add2, phase);
set_req_X(2, a12, phase);
progress = this;
add2 = a12;
}
Expand Down Expand Up @@ -642,14 +636,8 @@ Node *AddPNode::Ideal(PhaseGVN *phase, bool can_reshape) {
address = phase->transform(new AddPNode(in(Base),addp->in(Address),in(Offset)));
offset = addp->in(Offset);
}
PhaseIterGVN *igvn = phase->is_IterGVN();
if( igvn ) {
set_req_X(Address,address,igvn);
set_req_X(Offset,offset,igvn);
} else {
set_req(Address,address);
set_req(Offset,offset);
}
set_req_X(Address, address, phase);
set_req_X(Offset, offset, phase);
return this;
}
}
Expand Down Expand Up @@ -1123,8 +1111,8 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
assert( l != l->in(1), "dead loop in MinINode::Ideal" );
r = phase->transform(new MinINode(l->in(2),r));
l = l->in(1);
set_req(1, l);
set_req(2, r);
set_req_X(1, l, phase);
set_req_X(2, r, phase);
return this;
}

Expand Down
30 changes: 15 additions & 15 deletions src/hotspot/share/opto/cfgnode.cpp
Expand Up @@ -625,6 +625,13 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) {
for (DUIterator_Last imin, i = last_outs(imin); i >= imin; --i) {
Node* n = last_out(i);
igvn->hash_delete(n); // Remove from worklist before modifying edges
if (n->outcnt() == 0) {
int uses_found = n->replace_edge(this, phase->C->top(), igvn);
if (uses_found > 1) { // (--i) done at the end of the loop.
i -= (uses_found - 1);
}
continue;
}
if( n->is_Phi() ) { // Collapse all Phis
// Eagerly replace phis to avoid regionless phis.
Node* in;
Expand All @@ -641,14 +648,8 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
else if( n->is_Region() ) { // Update all incoming edges
assert(n != this, "Must be removed from DefUse edges");
uint uses_found = 0;
for( uint k=1; k < n->req(); k++ ) {
if( n->in(k) == this ) {
n->set_req(k, parent_ctrl);
uses_found++;
}
}
if( uses_found > 1 ) { // (--i) done at the end of the loop.
int uses_found = n->replace_edge(this, parent_ctrl, igvn);
if (uses_found > 1) { // (--i) done at the end of the loop.
i -= (uses_found - 1);
}
}
Expand Down Expand Up @@ -881,6 +882,9 @@ bool RegionNode::optimize_trichotomy(PhaseIterGVN* igvn) {
// Replace bool input of iff2 with merged test
BoolNode* new_bol = new BoolNode(bol2->in(1), res);
igvn->replace_input_of(iff2, 1, igvn->transform((proj2->_con == 1) ? new_bol : new_bol->negate(igvn)));
if (new_bol->outcnt() == 0) {
igvn->remove_dead_node(new_bol);
}
}
return false;
}
Expand Down Expand Up @@ -1916,11 +1920,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
igvn->_worklist.push(r);
}
// Nuke it down
if (can_reshape) {
set_req_X(j, top, igvn);
} else {
set_req(j, top);
}
set_req_X(j, top, phase);
progress = this; // Record progress
}
}
Expand Down Expand Up @@ -1958,7 +1958,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
} else {
// We can't return top if we are in Parse phase - cut inputs only
// let Identity to handle the case.
replace_edge(uin, top);
replace_edge(uin, top, phase);
return NULL;
}
}
Expand Down Expand Up @@ -2227,7 +2227,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
m->as_MergeMem()->memory_at(alias_idx) : m;
// Update input if it is progress over what we have now
if (new_mem != ii) {
set_req(i, new_mem);
set_req_X(i, new_mem, phase->is_IterGVN());
progress = this;
}
}
Expand Down
21 changes: 21 additions & 0 deletions src/hotspot/share/opto/compile.cpp
Expand Up @@ -2345,6 +2345,8 @@ void Compile::Optimize() {
}
} // (End scope of igvn; run destructor if necessary for asserts.)

check_no_dead_use();

process_print_inlining();

// A method with only infinite loops has no edges entering loops from root
Expand All @@ -2360,6 +2362,25 @@ void Compile::Optimize() {
DEBUG_ONLY(set_phase_optimize_finished();)
}

#ifdef ASSERT
void Compile::check_no_dead_use() const {
ResourceMark rm;
Unique_Node_List wq;
wq.push(root());
for (uint i = 0; i < wq.size(); ++i) {
Node* n = wq.at(i);
for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
Node* u = n->fast_out(j);
if (u->outcnt() == 0 && !u->is_Con()) {
u->dump();
fatal("no reachable node should have no use");
}
wq.push(u);
}
}
}
#endif

void Compile::inline_vector_reboxing_calls() {
if (C->_vector_reboxing_late_inlines.length() > 0) {
_late_inlines_pos = C->_late_inlines.length();
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/opto/compile.hpp
Expand Up @@ -1116,6 +1116,7 @@ class Compile : public Phase {
uint compute_truth_table(Unique_Node_List& partition, Unique_Node_List& inputs);
uint eval_macro_logic_op(uint func, uint op1, uint op2, uint op3);
Node* xform_to_MacroLogicV(PhaseIterGVN &igvn, const TypeVect* vt, Unique_Node_List& partitions, Unique_Node_List& inputs);
void check_no_dead_use() const NOT_DEBUG_RETURN;

public:

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/convertnode.cpp
Expand Up @@ -500,7 +500,7 @@ Node *ConvL2INode::Ideal(PhaseGVN *phase, bool can_reshape) {
if( andl_op == Op_AndL ) {
// Blow off prior masking to int
if( phase->type(andl->in(2)) == TypeLong::make( 0xFFFFFFFF ) ) {
set_req(1,andl->in(1));
set_req_X(1,andl->in(1), phase);
return this;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/escape.cpp
Expand Up @@ -2769,7 +2769,7 @@ void ConnectionGraph::move_inst_mem(Node* n, GrowableArray<PhiNode *> &orig_phi
Node* m = find_inst_mem(n, general_idx, orig_phis);
assert(orig_uniq == C->unique(), "no new nodes");
igvn->hash_delete(use);
imax -= use->replace_edge(n, m);
imax -= use->replace_edge(n, m, igvn);
igvn->hash_insert(use);
record_for_optimizer(use);
--i;
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/opto/ifnode.cpp
Expand Up @@ -1128,14 +1128,14 @@ void IfNode::improve_address_types(Node* l, Node* r, ProjNode* fail, PhaseIterGV
for (uint j = 2; j < stack.size(); j++) {
Node* n = stack.node_at(j);
Node* clone = n->clone();
int rep = clone->replace_edge(init_n, new_n);
int rep = clone->replace_edge(init_n, new_n, igvn);
assert(rep > 0, "can't find expected node?");
clone = igvn->transform(clone);
init_n = n;
new_n = clone;
}
igvn->hash_delete(use);
int rep = use->replace_edge(init_n, new_n);
int rep = use->replace_edge(init_n, new_n, igvn);
assert(rep > 0, "can't find expected node?");
igvn->transform(use);
if (init_n->outcnt() == 0) {
Expand Down Expand Up @@ -1364,7 +1364,7 @@ static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) {

Node* new_bol = (flip ? phase->transform( bol2->negate(phase) ) : bol2);
assert(new_bol != iff->in(1), "must make progress");
iff->set_req(1, new_bol);
iff->set_req_X(1, new_bol, phase);
// Intervening diamond probably goes dead
phase->C->set_major_progress();
return iff;
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/loopTransform.cpp
Expand Up @@ -1199,7 +1199,7 @@ Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop)
for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {
Node* n = incr->fast_out(i);
if (n->is_Phi() && n->in(0) == loop) {
int nrep = n->replace_edge(incr, castii);
int nrep = n->replace_edge(incr, castii, &_igvn);
return castii;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/loopnode.cpp
Expand Up @@ -543,7 +543,7 @@ void PhaseIdealLoop::long_loop_replace_long_iv(Node* iv_to_replace, Node* inner_
}
#endif
_igvn.rehash_node_delayed(u);
int nb = u->replace_edge(iv_to_replace, iv_replacement);
int nb = u->replace_edge(iv_to_replace, iv_replacement, &_igvn);
i -= nb;
}
}
Expand Down Expand Up @@ -1170,7 +1170,7 @@ bool PhaseIdealLoop::convert_to_long_loop(Node* cmp, Node* phi, IdealLoopTree* l
set_subtree_ctrl(m, false);
}
_igvn.rehash_node_delayed(u);
int nb = u->replace_edge(n, m);
int nb = u->replace_edge(n, m, &_igvn);
--i, imax -= nb;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/loopopts.cpp
Expand Up @@ -924,7 +924,7 @@ void PhaseIdealLoop::try_move_store_after_loop(Node* n) {
Node* hook = new Node(1);
hook->init_req(0, n_ctrl); // Add an input to prevent hook from being dead
_igvn.rehash_node_delayed(phi);
int count = phi->replace_edge(n, hook);
int count = phi->replace_edge(n, hook, &_igvn);
assert(count > 0, "inconsistent phi");

// Compute latest point this store can go
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/opto/macro.cpp
Expand Up @@ -892,7 +892,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa
// to the allocated object with "sobj"
int start = jvms->debug_start();
int end = jvms->debug_end();
sfpt->replace_edges_in_range(res, sobj, start, end);
sfpt->replace_edges_in_range(res, sobj, start, end, &_igvn);
_igvn._worklist.push(sfpt);
safepoints_done.append_if_missing(sfpt); // keep it for rollback
}
Expand Down Expand Up @@ -967,12 +967,12 @@ void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {

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

// Disconnect src right away: it can help find new
// opportunities for allocation elimination
Node* src = ac->in(ArrayCopyNode::Src);
ac->replace_edge(src, top());
ac->replace_edge(src, top(), &_igvn);
// src can be top at this point if src and dest of the
// arraycopy were the same
if (src->outcnt() == 0 && !src->is_top()) {
Expand Down
22 changes: 9 additions & 13 deletions src/hotspot/share/opto/memnode.cpp
Expand Up @@ -336,7 +336,7 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) {
Node* u = ctl->fast_out(i);
if (u != ctl) {
igvn->rehash_node_delayed(u);
int nb = u->replace_edge(ctl, phase->C->top());
int nb = u->replace_edge(ctl, phase->C->top(), igvn);
--i, imax -= nb;
}
}
Expand Down Expand Up @@ -2650,13 +2650,9 @@ Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (phase->is_IterGVN()) {
phase->is_IterGVN()->rehash_node_delayed(use);
}
if (can_reshape) {
use->set_req_X(MemNode::Memory, st->in(MemNode::Memory), phase->is_IterGVN());
} else {
// It's OK to do this in the parser, since DU info is always accurate,
// and the parser always refers to nodes via SafePointNode maps.
use->set_req(MemNode::Memory, st->in(MemNode::Memory));
}
// It's OK to do this in the parser, since DU info is always accurate,
// and the parser always refers to nodes via SafePointNode maps.
use->set_req_X(MemNode::Memory, st->in(MemNode::Memory), phase);
return this;
}
st = st->in(MemNode::Memory);
Expand Down Expand Up @@ -2801,7 +2797,7 @@ Node *StoreNode::Ideal_masked_input(PhaseGVN *phase, uint mask) {
if( val->Opcode() == Op_AndI ) {
const TypeInt *t = phase->type( val->in(2) )->isa_int();
if( t && t->is_con() && (t->get_con() & mask) == mask ) {
set_req(MemNode::ValueIn, val->in(1));
set_req_X(MemNode::ValueIn, val->in(1), phase);
return this;
}
}
Expand All @@ -2823,7 +2819,7 @@ Node *StoreNode::Ideal_sign_extended_input(PhaseGVN *phase, int num_bits) {
if( shl->Opcode() == Op_LShiftI ) {
const TypeInt *t2 = phase->type( shl->in(2) )->isa_int();
if( t2 && t2->is_con() && (t2->get_con() == t->get_con()) ) {
set_req(MemNode::ValueIn, shl->in(1));
set_req_X(MemNode::ValueIn, shl->in(1), phase);
return this;
}
}
Expand Down Expand Up @@ -2934,7 +2930,7 @@ Node *StoreCMNode::Ideal(PhaseGVN *phase, bool can_reshape){
Node* my_store = in(MemNode::OopStore);
if (my_store->is_MergeMem()) {
Node* mem = my_store->as_MergeMem()->memory_at(oop_alias_idx());
set_req(MemNode::OopStore, mem);
set_req_X(MemNode::OopStore, mem, phase);
return this;
}

Expand Down Expand Up @@ -4734,13 +4730,13 @@ Node *MergeMemNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Warning: Do not combine this "if" with the previous "if"
// A memory slice might have be be rewritten even if it is semantically
// unchanged, if the base_memory value has changed.
set_req(i, new_in);
set_req_X(i, new_in, phase);
progress = this; // Report progress
}
}

if (new_base != old_base) {
set_req(Compile::AliasIdxBot, new_base);
set_req_X(Compile::AliasIdxBot, new_base, phase);
// Don't use set_base_memory(new_base), because we need to update du.
assert(base_memory() == new_base, "");
progress = this;
Expand Down