aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkvn <none@none>2012-06-12 16:23:31 -0700
committerkvn <none@none>2012-06-12 16:23:31 -0700
commit7bbb2f7ff7a7746cf1e3f625d1753df786eaa995 (patch)
tree4098660ec4e0cf4a3c9454b63201b1462755d309
parent18d70d36ba60e0ddaf1678ab763d010b498e1854 (diff)
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
Summary: replace frequent C2 optimizer code patterns with new methods calls Reviewed-by: kvn, twisti Contributed-by: vladimir.x.ivanov@oracle.com
-rw-r--r--src/share/vm/opto/domgraph.cpp8
-rw-r--r--src/share/vm/opto/ifnode.cpp16
-rw-r--r--src/share/vm/opto/loopPredicate.cpp6
-rw-r--r--src/share/vm/opto/loopTransform.cpp24
-rw-r--r--src/share/vm/opto/loopUnswitch.cpp25
-rw-r--r--src/share/vm/opto/loopnode.cpp11
-rw-r--r--src/share/vm/opto/loopopts.cpp101
-rw-r--r--src/share/vm/opto/macro.cpp22
-rw-r--r--src/share/vm/opto/phaseX.hpp19
-rw-r--r--src/share/vm/opto/split_if.cpp12
-rw-r--r--src/share/vm/opto/superword.cpp28
11 files changed, 92 insertions, 180 deletions
diff --git a/src/share/vm/opto/domgraph.cpp b/src/share/vm/opto/domgraph.cpp
index ef4e1b17d..b3a367d53 100644
--- a/src/share/vm/opto/domgraph.cpp
+++ b/src/share/vm/opto/domgraph.cpp
@@ -465,15 +465,11 @@ void PhaseIdealLoop::Dominators() {
// Kill dead input path
assert( !visited.test(whead->in(i)->_idx),
"input with no loop must be dead" );
- _igvn.hash_delete(whead);
- whead->del_req(i);
- _igvn._worklist.push(whead);
+ _igvn.delete_input_of(whead, i);
for (DUIterator_Fast jmax, j = whead->fast_outs(jmax); j < jmax; j++) {
Node* p = whead->fast_out(j);
if( p->is_Phi() ) {
- _igvn.hash_delete(p);
- p->del_req(i);
- _igvn._worklist.push(p);
+ _igvn.delete_input_of(p, i);
}
}
i--; // Rerun same iteration
diff --git a/src/share/vm/opto/ifnode.cpp b/src/share/vm/opto/ifnode.cpp
index ce84f649f..c48e982ba 100644
--- a/src/share/vm/opto/ifnode.cpp
+++ b/src/share/vm/opto/ifnode.cpp
@@ -338,8 +338,7 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
Node *phi_f = NULL; // do not construct unless needed
for (DUIterator_Last i2min, i2 = phi->last_outs(i2min); i2 >= i2min; --i2) {
Node* v = phi->last_out(i2);// User of the phi
- igvn->hash_delete(v); // Have to fixup other Phi users
- igvn->_worklist.push(v);
+ igvn->rehash_node_delayed(v); // Have to fixup other Phi users
uint vop = v->Opcode();
Node *proj = NULL;
if( vop == Op_Phi ) { // Remote merge point
@@ -552,9 +551,8 @@ static void adjust_check(Node* proj, Node* range, Node* index,
if( new_cmp == cmp ) return;
// Else, adjust existing check
Node *new_bol = gvn->transform( new (gvn->C, 2) BoolNode( new_cmp, bol->as_Bool()->_test._test ) );
- igvn->hash_delete( iff );
+ igvn->rehash_node_delayed( iff );
iff->set_req_X( 1, new_bol, igvn );
- igvn->_worklist.push( iff );
}
//------------------------------up_one_dom-------------------------------------
@@ -732,9 +730,7 @@ Node* IfNode::fold_compares(PhaseGVN* phase) {
Node* adjusted = phase->transform(new (phase->C, 3) SubINode(n, phase->intcon(failtype->_lo)));
Node* newcmp = phase->transform(new (phase->C, 3) CmpUNode(adjusted, phase->intcon(bound)));
Node* newbool = phase->transform(new (phase->C, 2) BoolNode(newcmp, cond));
- phase->hash_delete(dom_iff);
- dom_iff->set_req(1, phase->intcon(ctrl->as_Proj()->_con));
- phase->is_IterGVN()->_worklist.push(dom_iff);
+ phase->is_IterGVN()->replace_input_of(dom_iff, 1, phase->intcon(ctrl->as_Proj()->_con));
phase->hash_delete(this);
set_req(1, newbool);
return this;
@@ -1042,17 +1038,15 @@ void IfNode::dominated_by( Node *prev_dom, PhaseIterGVN *igvn ) {
// Loop ends when projection has no more uses.
for (DUIterator_Last jmin, j = ifp->last_outs(jmin); j >= jmin; --j) {
Node* s = ifp->last_out(j); // Get child of IfTrue/IfFalse
- igvn->hash_delete(s); // Yank from hash table before edge hacking
if( !s->depends_only_on_test() ) {
// Find the control input matching this def-use edge.
// For Regions it may not be in slot 0.
uint l;
for( l = 0; s->in(l) != ifp; l++ ) { }
- s->set_req(l, ctrl_target);
+ igvn->replace_input_of(s, l, ctrl_target);
} else { // Else, for control producers,
- s->set_req(0, data_target); // Move child to data-target
+ igvn->replace_input_of(s, 0, data_target); // Move child to data-target
}
- igvn->_worklist.push(s); // Revisit collapsed Phis
} // End for each child of a projection
igvn->remove_dead_node(ifp);
diff --git a/src/share/vm/opto/loopPredicate.cpp b/src/share/vm/opto/loopPredicate.cpp
index d4a575d7b..048cba894 100644
--- a/src/share/vm/opto/loopPredicate.cpp
+++ b/src/share/vm/opto/loopPredicate.cpp
@@ -212,9 +212,8 @@ ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node*
Node* use = rgn->fast_out(i);
if (use->is_Phi() && use->outcnt() > 0) {
assert(use->in(0) == rgn, "");
- _igvn.hash_delete(use);
+ _igvn.rehash_node_delayed(use);
use->add_req(use->in(proj_index));
- _igvn._worklist.push(use);
has_phi = true;
}
}
@@ -284,9 +283,8 @@ ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* n
for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) {
Node* use = rgn->fast_out(i);
if (use->is_Phi() && use->outcnt() > 0) {
- hash_delete(use);
+ rehash_node_delayed(use);
use->add_req(use->in(proj_index));
- _worklist.push(use);
has_phi = true;
}
}
diff --git a/src/share/vm/opto/loopTransform.cpp b/src/share/vm/opto/loopTransform.cpp
index eee153a89..0ee3436c7 100644
--- a/src/share/vm/opto/loopTransform.cpp
+++ b/src/share/vm/opto/loopTransform.cpp
@@ -961,9 +961,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
set_loop(zer_iff, loop->_parent);
// Plug in the false-path, taken if we need to skip post-loop
- _igvn.hash_delete( main_exit );
- main_exit->set_req(0, zer_iff);
- _igvn._worklist.push(main_exit);
+ _igvn.replace_input_of(main_exit, 0, zer_iff);
set_idom(main_exit, zer_iff, dd_main_exit);
set_idom(main_exit->unique_out(), zer_iff, dd_main_exit);
// Make the true-path, must enter the post loop
@@ -1956,9 +1954,7 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
C->set_major_progress();
Node *kill_con = _igvn.intcon( 1-flip );
set_ctrl(kill_con, C->root());
- _igvn.hash_delete(iff);
- iff->set_req(1, kill_con);
- _igvn._worklist.push(iff);
+ _igvn.replace_input_of(iff, 1, kill_con);
// Find surviving projection
assert(iff->is_If(), "");
ProjNode* dp = ((IfNode*)iff)->proj_out(1-flip);
@@ -1966,11 +1962,9 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
Node* cd = dp->fast_out(i); // Control-dependent node
if( cd->is_Load() ) { // Loads can now float around in the loop
- _igvn.hash_delete(cd);
// Allow the load to float around in the loop, or before it
// but NOT before the pre-loop.
- cd->set_req(0, ctrl); // ctrl, not NULL
- _igvn._worklist.push(cd);
+ _igvn.replace_input_of(cd, 0, ctrl); // ctrl, not NULL
--i;
--imax;
}
@@ -2029,14 +2023,10 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
main_bol->set_req(1,main_cmp);
}
// Hack the now-private loop bounds
- _igvn.hash_delete(main_cmp);
- main_cmp->set_req(2, main_limit);
- _igvn._worklist.push(main_cmp);
+ _igvn.replace_input_of(main_cmp, 2, main_limit);
// The OpaqueNode is unshared by design
- _igvn.hash_delete(opqzm);
assert( opqzm->outcnt() == 1, "cannot hack shared node" );
- opqzm->set_req(1,main_limit);
- _igvn._worklist.push(opqzm);
+ _igvn.replace_input_of(opqzm, 1, main_limit);
}
//------------------------------DCE_loop_body----------------------------------
@@ -2178,9 +2168,7 @@ bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
Node* cmp = cl->loopexit()->cmp_node();
assert(cl->limit() == cmp->in(2), "sanity");
phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist
- phase->_igvn.hash_delete(cmp);
- cmp->set_req(2, exact_limit);
- phase->_igvn._worklist.push(cmp); // put cmp on worklist
+ phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist
}
// Note: the final value after increment should not overflow since
// counted loop has limit check predicate.
diff --git a/src/share/vm/opto/loopUnswitch.cpp b/src/share/vm/opto/loopUnswitch.cpp
index 20ddf7827..47e3990fd 100644
--- a/src/share/vm/opto/loopUnswitch.cpp
+++ b/src/share/vm/opto/loopUnswitch.cpp
@@ -174,27 +174,21 @@ void PhaseIdealLoop::do_unswitching (IdealLoopTree *loop, Node_List &old_new) {
Node* use = worklist.pop();
Node* nuse = use->clone();
nuse->set_req(0, invar_proj);
- _igvn.hash_delete(use);
- use->set_req(1, nuse);
- _igvn._worklist.push(use);
+ _igvn.replace_input_of(use, 1, nuse);
register_new_node(nuse, invar_proj);
// Same for the clone
Node* use_clone = old_new[use->_idx];
- _igvn.hash_delete(use_clone);
- use_clone->set_req(1, nuse);
- _igvn._worklist.push(use_clone);
+ _igvn.replace_input_of(use_clone, 1, nuse);
}
}
// Hardwire the control paths in the loops into if(true) and if(false)
- _igvn.hash_delete(unswitch_iff);
+ _igvn.rehash_node_delayed(unswitch_iff);
short_circuit_if(unswitch_iff, proj_true);
- _igvn._worklist.push(unswitch_iff);
IfNode* unswitch_iff_clone = old_new[unswitch_iff->_idx]->as_If();
- _igvn.hash_delete(unswitch_iff_clone);
+ _igvn.rehash_node_delayed(unswitch_iff_clone);
short_circuit_if(unswitch_iff_clone, proj_false);
- _igvn._worklist.push(unswitch_iff_clone);
// Reoptimize loops
loop->record_for_igvn();
@@ -224,8 +218,7 @@ ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
LoopNode* head = loop->_head->as_Loop();
bool counted_loop = head->is_CountedLoop();
Node* entry = head->in(LoopNode::EntryControl);
- _igvn.hash_delete(entry);
- _igvn._worklist.push(entry);
+ _igvn.rehash_node_delayed(entry);
IdealLoopTree* outer_loop = loop->_parent;
Node *cont = _igvn.intcon(1);
@@ -249,18 +242,14 @@ ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
// Fast (true) control
Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
- _igvn.hash_delete(head);
- head->set_req(LoopNode::EntryControl, iffast_pred);
+ _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
set_idom(head, iffast_pred, dom_depth(head));
- _igvn._worklist.push(head);
// Slow (false) control
Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
LoopNode* slow_head = old_new[head->_idx]->as_Loop();
- _igvn.hash_delete(slow_head);
- slow_head->set_req(LoopNode::EntryControl, ifslow_pred);
+ _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow_pred);
set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
- _igvn._worklist.push(slow_head);
recompute_dom_depth();
diff --git a/src/share/vm/opto/loopnode.cpp b/src/share/vm/opto/loopnode.cpp
index 2d045e47d..afd96045a 100644
--- a/src/share/vm/opto/loopnode.cpp
+++ b/src/share/vm/opto/loopnode.cpp
@@ -1129,8 +1129,7 @@ void IdealLoopTree::split_fall_in( PhaseIdealLoop *phase, int fall_in_cnt ) {
// I'm mid-iteration over the Region's uses.
for (DUIterator_Last imin, i = old_phi->last_outs(imin); i >= imin; ) {
Node* use = old_phi->last_out(i);
- igvn.hash_delete(use);
- igvn._worklist.push(use);
+ igvn.rehash_node_delayed(use);
uint uses_found = 0;
for (uint j = 0; j < use->len(); j++) {
if (use->in(j) == old_phi) {
@@ -1186,10 +1185,8 @@ void IdealLoopTree::split_outer_loop( PhaseIdealLoop *phase ) {
phi->init_req(LoopNode::LoopBackControl, old_phi->in(outer_idx));
phi = igvn.register_new_node_with_optimizer(phi, old_phi);
// Make old Phi point to new Phi on the fall-in path
- igvn.hash_delete(old_phi);
- old_phi->set_req(LoopNode::EntryControl, phi);
+ igvn.replace_input_of(old_phi, LoopNode::EntryControl, phi);
old_phi->del_req(outer_idx);
- igvn._worklist.push(old_phi);
}
}
@@ -1992,9 +1989,7 @@ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts)
// we do it here.
for( uint i = 1; i < C->root()->req(); i++ ) {
if( !_nodes[C->root()->in(i)->_idx] ) { // Dead path into Root?
- _igvn.hash_delete(C->root());
- C->root()->del_req(i);
- _igvn._worklist.push(C->root());
+ _igvn.delete_input_of(C->root(), i);
i--; // Rerun same iteration on compressed edges
}
}
diff --git a/src/share/vm/opto/loopopts.cpp b/src/share/vm/opto/loopopts.cpp
index e93fb4d08..ee6c36d22 100644
--- a/src/share/vm/opto/loopopts.cpp
+++ b/src/share/vm/opto/loopopts.cpp
@@ -216,9 +216,7 @@ void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip, bool exc
Node *con = _igvn.makecon(pop == Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO);
set_ctrl(con, C->root()); // Constant gets a new use
// Hack the dominated test
- _igvn.hash_delete(iff);
- iff->set_req(1, con);
- _igvn._worklist.push(iff);
+ _igvn.replace_input_of(iff, 1, con);
// If I dont have a reachable TRUE and FALSE path following the IfNode then
// I can assume this path reaches an infinite loop. In this case it's not
@@ -245,10 +243,8 @@ void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip, bool exc
Node* cd = dp->fast_out(i); // Control-dependent node
if (cd->depends_only_on_test()) {
assert(cd->in(0) == dp, "");
- _igvn.hash_delete(cd);
- cd->set_req(0, prevdom);
+ _igvn.replace_input_of(cd, 0, prevdom);
set_early_ctrl(cd);
- _igvn._worklist.push(cd);
IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
if (old_loop != new_loop) {
if (!old_loop->_child) old_loop->_body.yank(cd);
@@ -952,8 +948,7 @@ void PhaseIdealLoop::split_if_with_blocks_post( Node *n ) {
if (!n->is_Load() || late_load_ctrl != n_ctrl) {
for (DUIterator_Last jmin, j = n->last_outs(jmin); j >= jmin; ) {
Node *u = n->last_out(j); // Clone private computation per use
- _igvn.hash_delete(u);
- _igvn._worklist.push(u);
+ _igvn.rehash_node_delayed(u);
Node *x = n->clone(); // Clone computation
Node *x_ctrl = NULL;
if( u->is_Phi() ) {
@@ -1089,9 +1084,7 @@ BoolNode *PhaseIdealLoop::clone_iff( PhiNode *phi, IdealLoopTree *loop ) {
for( i = 1; i < phi->req(); i++ ) {
Node *b = phi->in(i);
if( b->is_Phi() ) {
- _igvn.hash_delete(phi);
- _igvn._worklist.push(phi);
- phi->set_req(i, clone_iff( b->as_Phi(), loop ));
+ _igvn.replace_input_of(phi, i, clone_iff( b->as_Phi(), loop ));
} else {
assert( b->is_Bool(), "" );
}
@@ -1161,9 +1154,7 @@ CmpNode *PhaseIdealLoop::clone_bool( PhiNode *phi, IdealLoopTree *loop ) {
for( i = 1; i < phi->req(); i++ ) {
Node *b = phi->in(i);
if( b->is_Phi() ) {
- _igvn.hash_delete(phi);
- _igvn._worklist.push(phi);
- phi->set_req(i, clone_bool( b->as_Phi(), loop ));
+ _igvn.replace_input_of(phi, i, clone_bool( b->as_Phi(), loop ));
} else {
assert( b->is_Cmp() || b->is_top(), "inputs are all Cmp or TOP" );
}
@@ -1347,8 +1338,7 @@ void PhaseIdealLoop::clone_loop( IdealLoopTree *loop, Node_List &old_new, int dd
// The original user of 'use' uses 'r' instead.
for (DUIterator_Last lmin, l = use->last_outs(lmin); l >= lmin;) {
Node* useuse = use->last_out(l);
- _igvn.hash_delete(useuse);
- _igvn._worklist.push(useuse);
+ _igvn.rehash_node_delayed(useuse);
uint uses_found = 0;
if( useuse->in(0) == use ) {
useuse->set_req(0, r);
@@ -1435,9 +1425,7 @@ void PhaseIdealLoop::clone_loop( IdealLoopTree *loop, Node_List &old_new, int dd
if( use->is_Phi() ) // Phi use is in prior block
cfg = prev->in(idx); // NOT in block of Phi itself
if (cfg->is_top()) { // Use is dead?
- _igvn.hash_delete(use);
- _igvn._worklist.push(use);
- use->set_req(idx, C->top());
+ _igvn.replace_input_of(use, idx, C->top());
continue;
}
@@ -1487,9 +1475,7 @@ void PhaseIdealLoop::clone_loop( IdealLoopTree *loop, Node_List &old_new, int dd
set_ctrl(phi, prev);
}
// Make 'use' use the Phi instead of the old loop body exit value
- _igvn.hash_delete(use);
- _igvn._worklist.push(use);
- use->set_req(idx, phi);
+ _igvn.replace_input_of(use, idx, phi);
if( use->_idx >= new_counter ) { // If updating new phis
// Not needed for correctness, but prevents a weak assert
// in AddPNode from tripping (when we end up with different
@@ -1517,9 +1503,7 @@ void PhaseIdealLoop::clone_loop( IdealLoopTree *loop, Node_List &old_new, int dd
Node *iff = split_if_set->pop();
if( iff->in(1)->is_Phi() ) {
BoolNode *b = clone_iff( iff->in(1)->as_Phi(), loop );
- _igvn.hash_delete(iff);
- _igvn._worklist.push(iff);
- iff->set_req(1, b);
+ _igvn.replace_input_of(iff, 1, b);
}
}
}
@@ -1529,9 +1513,7 @@ void PhaseIdealLoop::clone_loop( IdealLoopTree *loop, Node_List &old_new, int dd
Node *phi = b->in(1);
assert( phi->is_Phi(), "" );
CmpNode *cmp = clone_bool( (PhiNode*)phi, loop );
- _igvn.hash_delete(b);
- _igvn._worklist.push(b);
- b->set_req(1, cmp);
+ _igvn.replace_input_of(b, 1, cmp);
}
}
if( split_cex_set ) {
@@ -1686,10 +1668,8 @@ ProjNode* PhaseIdealLoop::insert_if_before_proj(Node* left, bool Signed, BoolTes
ProjNode *other_proj = iff->proj_out(!proj->is_IfTrue())->as_Proj();
int ddepth = dom_depth(proj);
- _igvn.hash_delete(iff);
- _igvn._worklist.push(iff);
- _igvn.hash_delete(proj);
- _igvn._worklist.push(proj);
+ _igvn.rehash_node_delayed(iff);
+ _igvn.rehash_node_delayed(proj);
proj->set_req(0, NULL); // temporary disconnect
ProjNode* proj2 = proj_clone(proj, iff);
@@ -1745,10 +1725,8 @@ RegionNode* PhaseIdealLoop::insert_region_before_proj(ProjNode* proj) {
ProjNode *other_proj = iff->proj_out(!proj->is_IfTrue())->as_Proj();
int ddepth = dom_depth(proj);
- _igvn.hash_delete(iff);
- _igvn._worklist.push(iff);
- _igvn.hash_delete(proj);
- _igvn._worklist.push(proj);
+ _igvn.rehash_node_delayed(iff);
+ _igvn.rehash_node_delayed(proj);
proj->set_req(0, NULL); // temporary disconnect
ProjNode* proj2 = proj_clone(proj, iff);
@@ -1970,9 +1948,7 @@ void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, N
// clone "n" and insert it between the inputs of "n" and the use outside the loop
Node* n_clone = n->clone();
- _igvn.hash_delete(use);
- use->set_req(j, n_clone);
- _igvn._worklist.push(use);
+ _igvn.replace_input_of(use, j, n_clone);
Node* use_c;
if (!use->is_Phi()) {
use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0);
@@ -2028,8 +2004,7 @@ void PhaseIdealLoop::clone_for_special_use_inside_loop( IdealLoopTree *loop, Nod
#endif
while( worklist.size() ) {
Node *use = worklist.pop();
- _igvn.hash_delete(use);
- _igvn._worklist.push(use);
+ _igvn.rehash_node_delayed(use);
for (uint j = 1; j < use->req(); j++) {
if (use->in(j) == n) {
use->set_req(j, n_clone);
@@ -2055,9 +2030,7 @@ void PhaseIdealLoop::insert_phi_for_loop( Node* use, uint idx, Node* lp_entry_va
_igvn.remove_dead_node(phi);
phi = hit;
}
- _igvn.hash_delete(use);
- _igvn._worklist.push(use);
- use->set_req(idx, phi);
+ _igvn.replace_input_of(use, idx, phi);
}
#ifdef ASSERT
@@ -2630,9 +2603,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
// use is in loop
if (old_new[use->_idx] != NULL) { // null for dead code
Node* use_clone = old_new[use->_idx];
- _igvn.hash_delete(use);
- use->set_req(j, C->top());
- _igvn._worklist.push(use);
+ _igvn.replace_input_of(use, j, C->top());
insert_phi_for_loop( use_clone, j, old_new[def->_idx], def, new_head_clone );
}
} else {
@@ -2667,46 +2638,35 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
if (!n->is_CFG() && n->in(0) != NULL &&
not_peel.test(n->_idx) && peel.test(n->in(0)->_idx)) {
Node* n_clone = old_new[n->_idx];
- _igvn.hash_delete(n_clone);
- n_clone->set_req(0, new_head_clone);
- _igvn._worklist.push(n_clone);
+ _igvn.replace_input_of(n_clone, 0, new_head_clone);
}
}
// Backedge of the surviving new_head (the clone) is original last_peel
- _igvn.hash_delete(new_head_clone);
- new_head_clone->set_req(LoopNode::LoopBackControl, last_peel);
- _igvn._worklist.push(new_head_clone);
+ _igvn.replace_input_of(new_head_clone, LoopNode::LoopBackControl, last_peel);
// Cut first node in original not_peel set
- _igvn.hash_delete(new_head);
- new_head->set_req(LoopNode::EntryControl, C->top());
- new_head->set_req(LoopNode::LoopBackControl, C->top());
- _igvn._worklist.push(new_head);
+ _igvn.rehash_node_delayed(new_head); // Multiple edge updates:
+ new_head->set_req(LoopNode::EntryControl, C->top()); // use rehash_node_delayed / set_req instead of
+ new_head->set_req(LoopNode::LoopBackControl, C->top()); // multiple replace_input_of calls
// Copy head_clone back-branch info to original head
// and remove original head's loop entry and
// clone head's back-branch
- _igvn.hash_delete(head);
- _igvn.hash_delete(head_clone);
- head->set_req(LoopNode::EntryControl, head_clone->in(LoopNode::LoopBackControl));
+ _igvn.rehash_node_delayed(head); // Multiple edge updates
+ head->set_req(LoopNode::EntryControl, head_clone->in(LoopNode::LoopBackControl));
head->set_req(LoopNode::LoopBackControl, C->top());
- head_clone->set_req(LoopNode::LoopBackControl, C->top());
- _igvn._worklist.push(head);
- _igvn._worklist.push(head_clone);
+ _igvn.replace_input_of(head_clone, LoopNode::LoopBackControl, C->top());
// Similarly modify the phis
for (DUIterator_Fast kmax, k = head->fast_outs(kmax); k < kmax; k++) {
Node* use = head->fast_out(k);
if (use->is_Phi() && use->outcnt() > 0) {
Node* use_clone = old_new[use->_idx];
- _igvn.hash_delete(use);
- _igvn.hash_delete(use_clone);
- use->set_req(LoopNode::EntryControl, use_clone->in(LoopNode::LoopBackControl));
+ _igvn.rehash_node_delayed(use); // Multiple edge updates
+ use->set_req(LoopNode::EntryControl, use_clone->in(LoopNode::LoopBackControl));
use->set_req(LoopNode::LoopBackControl, C->top());
- use_clone->set_req(LoopNode::LoopBackControl, C->top());
- _igvn._worklist.push(use);
- _igvn._worklist.push(use_clone);
+ _igvn.replace_input_of(use_clone, LoopNode::LoopBackControl, C->top());
}
}
@@ -2792,8 +2752,7 @@ void PhaseIdealLoop::reorg_offsets(IdealLoopTree *loop) {
set_ctrl(neg_stride, C->root());
Node *post = new (C, 3) AddINode( opaq, neg_stride);
register_new_node( post, u_ctrl );
- _igvn.hash_delete(use);
- _igvn._worklist.push(use);
+ _igvn.rehash_node_delayed(use);
for (uint j = 1; j < use->req(); j++) {
if (use->in(j) == phi)
use->set_req(j, post);
diff --git a/src/share/vm/opto/macro.cpp b/src/share/vm/opto/macro.cpp
index 11416ac47..b4d54f7e9 100644
--- a/src/share/vm/opto/macro.cpp
+++ b/src/share/vm/opto/macro.cpp
@@ -1447,9 +1447,8 @@ void PhaseMacroExpand::expand_allocate_common(
if (!always_slow && _memproj_fallthrough != NULL) {
for (DUIterator_Fast imax, i = _memproj_fallthrough->fast_outs(imax); i < imax; i++) {
Node *use = _memproj_fallthrough->fast_out(i);
- _igvn.hash_delete(use);
+ _igvn.rehash_node_delayed(use);
imax -= replace_input(use, _memproj_fallthrough, result_phi_rawmem);
- _igvn._worklist.push(use);
// back up iterator
--i;
}
@@ -1463,9 +1462,8 @@ void PhaseMacroExpand::expand_allocate_common(
}
for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) {
Node *use = _memproj_catchall->fast_out(i);
- _igvn.hash_delete(use);
+ _igvn.rehash_node_delayed(use);
imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough);
- _igvn._worklist.push(use);
// back up iterator
--i;
}
@@ -1481,9 +1479,8 @@ void PhaseMacroExpand::expand_allocate_common(
if (_ioproj_fallthrough != NULL) {
for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) {
Node *use = _ioproj_fallthrough->fast_out(i);
- _igvn.hash_delete(use);
+ _igvn.rehash_node_delayed(use);
imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o);
- _igvn._worklist.push(use);
// back up iterator
--i;
}
@@ -1497,9 +1494,8 @@ void PhaseMacroExpand::expand_allocate_common(
}
for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) {
Node *use = _ioproj_catchall->fast_out(i);
- _igvn.hash_delete(use);
+ _igvn.rehash_node_delayed(use);
imax -= replace_input(use, _ioproj_catchall, _ioproj_fallthrough);
- _igvn._worklist.push(use);
// back up iterator
--i;
}
@@ -1857,18 +1853,16 @@ void PhaseMacroExpand::mark_eliminated_box(Node* oldbox, Node* obj) {
if (alock->box_node() == oldbox && alock->obj_node()->eqv_uncast(obj)) {
// Replace Box and mark eliminated all related locks and unlocks.
alock->set_non_esc_obj();
- _igvn.hash_delete(alock);
+ _igvn.rehash_node_delayed(alock);
alock->set_box_node(newbox);
- _igvn._worklist.push(alock);
next_edge = false;
}
}
if (u->is_FastLock() && u->as_FastLock()->obj_node()->eqv_uncast(obj)) {
FastLockNode* flock = u->as_FastLock();
assert(flock->box_node() == oldbox, "sanity");
- _igvn.hash_delete(flock);
+ _igvn.rehash_node_delayed(flock);
flock->set_box_node(newbox);
- _igvn._worklist.push(flock);
next_edge = false;
}
@@ -1886,9 +1880,7 @@ void PhaseMacroExpand::mark_eliminated_box(Node* oldbox, Node* obj) {
Node* box_node = sfn->monitor_box(jvms, idx);
if (box_node == oldbox && obj_node->eqv_uncast(obj)) {
int j = jvms->monitor_box_offset(idx);
- _igvn.hash_delete(u);
- u->set_req(j, newbox);
- _igvn._worklist.push(u);
+ _igvn.replace_input_of(u, j, newbox);
next_edge = false;
}
}
diff --git a/src/share/vm/opto/phaseX.hpp b/src/share/vm/opto/phaseX.hpp
index ef5bbb55f..1affa5c15 100644
--- a/src/share/vm/opto/phaseX.hpp
+++ b/src/share/vm/opto/phaseX.hpp
@@ -460,6 +460,25 @@ public:
subsume_node(old, nn);
}
+ // Delayed node rehash: remove a node from the hash table and rehash it during
+ // next optimizing pass
+ void rehash_node_delayed(Node* n) {
+ hash_delete(n);
+ _worklist.push(n);
+ }
+
+ // Replace ith edge of "n" with "in"
+ void replace_input_of(Node* n, int i, Node* in) {
+ rehash_node_delayed(n);
+ n->set_req(i, in);
+ }
+
+ // Delete ith edge of "n"
+ void delete_input_of(Node* n, int i) {
+ rehash_node_delayed(n);
+ n->del_req(i);
+ }
+
bool delay_transform() const { return _delay_transform; }
void set_delay_transform(bool delay) {
diff --git a/src/share/vm/opto/split_if.cpp b/src/share/vm/opto/split_if.cpp
index 55de3d70e..bd5eec942 100644
--- a/src/share/vm/opto/split_if.cpp
+++ b/src/share/vm/opto/split_if.cpp
@@ -137,9 +137,7 @@ bool PhaseIdealLoop::split_up( Node *n, Node *blk1, Node *blk2 ) {
Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff);
Node *x = bol->clone();
register_new_node(x, iff_ctrl);
- _igvn.hash_delete(iff);
- iff->set_req(1, x);
- _igvn._worklist.push(iff);
+ _igvn.replace_input_of(iff, 1, x);
}
_igvn.remove_dead_node( bol );
--i;
@@ -151,9 +149,7 @@ bool PhaseIdealLoop::split_up( Node *n, Node *blk1, Node *blk2 ) {
assert( bol->in(1) == n, "" );
Node *x = n->clone();
register_new_node(x, get_ctrl(bol));
- _igvn.hash_delete(bol);
- bol->set_req(1, x);
- _igvn._worklist.push(bol);
+ _igvn.replace_input_of(bol, 1, x);
}
_igvn.remove_dead_node( n );
@@ -387,9 +383,7 @@ void PhaseIdealLoop::handle_use( Node *use, Node *def, small_cache *cache, Node
if( use->in(i) == def )
break;
assert( i < use->req(), "def should be among use's inputs" );
- _igvn.hash_delete(use);
- use->set_req(i, new_def);
- _igvn._worklist.push(use);
+ _igvn.replace_input_of(use, i, new_def);
}
//------------------------------do_split_if------------------------------------
diff --git a/src/share/vm/opto/superword.cpp b/src/share/vm/opto/superword.cpp
index 28c4cfe41..ae46e7f17 100644
--- a/src/share/vm/opto/superword.cpp
+++ b/src/share/vm/opto/superword.cpp
@@ -944,7 +944,7 @@ void SuperWord::schedule() {
void SuperWord::remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip,
Node *uip, Unique_Node_List &sched_before) {
Node* my_mem = current->in(MemNode::Memory);
- _igvn.hash_delete(current);
+ _igvn.rehash_node_delayed(current);
_igvn.hash_delete(my_mem);
//remove current_store from its current position in the memmory graph
@@ -952,7 +952,7 @@ void SuperWord::remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip,
Node* use = current->out(i);
if (use->is_Mem()) {
assert(use->in(MemNode::Memory) == current, "must be");
- _igvn.hash_delete(use);
+ _igvn.rehash_node_delayed(use);
if (use == prev) { // connect prev to my_mem
use->set_req(MemNode::Memory, my_mem);
} else if (sched_before.member(use)) {
@@ -962,7 +962,6 @@ void SuperWord::remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip,
_igvn.hash_delete(lip);
use->set_req(MemNode::Memory, lip);
}
- _igvn._worklist.push(use);
--i; //deleted this edge; rescan position
}
}
@@ -976,25 +975,20 @@ void SuperWord::remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip,
Node* use = insert_pt->out(i);
if (use->is_Mem()) {
assert(use->in(MemNode::Memory) == insert_pt, "must be");
- _igvn.hash_delete(use);
- use->set_req(MemNode::Memory, current);
- _igvn._worklist.push(use);
+ _igvn.replace_input_of(use, MemNode::Memory, current);
--i; //deleted this edge; rescan position
} else if (!sched_up && use->is_Phi() && use->bottom_type() == Type::MEMORY) {
uint pos; //lip (lower insert point) must be the last one in the memory slice
- _igvn.hash_delete(use);
for (pos=1; pos < use->req(); pos++) {
if (use->in(pos) == insert_pt) break;
}
- use->set_req(pos, current);
- _igvn._worklist.push(use);
+ _igvn.replace_input_of(use, pos, current);
--i;
}
}
//connect current to insert_pt
current->set_req(MemNode::Memory, insert_pt);
- _igvn._worklist.push(current);
}
//------------------------------co_locate_pack----------------------------------
@@ -1077,15 +1071,13 @@ void SuperWord::co_locate_pack(Node_List* pk) {
Node* use = current->out(i);
if (use->is_Mem() && use != previous) {
assert(use->in(MemNode::Memory) == current, "must be");
- _igvn.hash_delete(use);
if (schedule_before_pack.member(use)) {
_igvn.hash_delete(upper_insert_pt);
- use->set_req(MemNode::Memory, upper_insert_pt);
+ _igvn.replace_input_of(use, MemNode::Memory, upper_insert_pt);
} else {
_igvn.hash_delete(lower_insert_pt);
- use->set_req(MemNode::Memory, lower_insert_pt);
+ _igvn.replace_input_of(use, MemNode::Memory, lower_insert_pt);
}
- _igvn._worklist.push(use);
--i; // deleted this edge; rescan position
}
}
@@ -1122,9 +1114,7 @@ void SuperWord::co_locate_pack(Node_List* pk) {
// Give each load the same memory state
for (uint i = 0; i < pk->size(); i++) {
LoadNode* ld = pk->at(i)->as_Load();
- _igvn.hash_delete(ld);
- ld->set_req(MemNode::Memory, mem_input);
- _igvn._worklist.push(ld);
+ _igvn.replace_input_of(ld, MemNode::Memory, mem_input);
}
}
}
@@ -1282,16 +1272,14 @@ void SuperWord::insert_extracts(Node_List* p) {
// Insert extract operation
_igvn.hash_delete(def);
- _igvn.hash_delete(use);
int def_pos = alignment(def) / data_size(def);
const Type* def_t = velt_type(def);
Node* ex = ExtractNode::make(_phase->C, def, def_pos, def_t);
_phase->_igvn.register_new_node_with_optimizer(ex);
_phase->set_ctrl(ex, _phase->get_ctrl(def));
- use->set_req(idx, ex);
+ _igvn.replace_input_of(use, idx, ex);
_igvn._worklist.push(def);
- _igvn._worklist.push(use);
bb_insert_after(ex, bb_idx(def));
set_velt_type(ex, def_t);