Tue, 12 Jun 2012 16:23:31 -0700
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
1.1 --- a/src/share/vm/opto/domgraph.cpp Tue Jun 12 14:31:44 2012 -0700 1.2 +++ b/src/share/vm/opto/domgraph.cpp Tue Jun 12 16:23:31 2012 -0700 1.3 @@ -465,15 +465,11 @@ 1.4 // Kill dead input path 1.5 assert( !visited.test(whead->in(i)->_idx), 1.6 "input with no loop must be dead" ); 1.7 - _igvn.hash_delete(whead); 1.8 - whead->del_req(i); 1.9 - _igvn._worklist.push(whead); 1.10 + _igvn.delete_input_of(whead, i); 1.11 for (DUIterator_Fast jmax, j = whead->fast_outs(jmax); j < jmax; j++) { 1.12 Node* p = whead->fast_out(j); 1.13 if( p->is_Phi() ) { 1.14 - _igvn.hash_delete(p); 1.15 - p->del_req(i); 1.16 - _igvn._worklist.push(p); 1.17 + _igvn.delete_input_of(p, i); 1.18 } 1.19 } 1.20 i--; // Rerun same iteration
2.1 --- a/src/share/vm/opto/ifnode.cpp Tue Jun 12 14:31:44 2012 -0700 2.2 +++ b/src/share/vm/opto/ifnode.cpp Tue Jun 12 16:23:31 2012 -0700 2.3 @@ -338,8 +338,7 @@ 2.4 Node *phi_f = NULL; // do not construct unless needed 2.5 for (DUIterator_Last i2min, i2 = phi->last_outs(i2min); i2 >= i2min; --i2) { 2.6 Node* v = phi->last_out(i2);// User of the phi 2.7 - igvn->hash_delete(v); // Have to fixup other Phi users 2.8 - igvn->_worklist.push(v); 2.9 + igvn->rehash_node_delayed(v); // Have to fixup other Phi users 2.10 uint vop = v->Opcode(); 2.11 Node *proj = NULL; 2.12 if( vop == Op_Phi ) { // Remote merge point 2.13 @@ -552,9 +551,8 @@ 2.14 if( new_cmp == cmp ) return; 2.15 // Else, adjust existing check 2.16 Node *new_bol = gvn->transform( new (gvn->C, 2) BoolNode( new_cmp, bol->as_Bool()->_test._test ) ); 2.17 - igvn->hash_delete( iff ); 2.18 + igvn->rehash_node_delayed( iff ); 2.19 iff->set_req_X( 1, new_bol, igvn ); 2.20 - igvn->_worklist.push( iff ); 2.21 } 2.22 2.23 //------------------------------up_one_dom------------------------------------- 2.24 @@ -732,9 +730,7 @@ 2.25 Node* adjusted = phase->transform(new (phase->C, 3) SubINode(n, phase->intcon(failtype->_lo))); 2.26 Node* newcmp = phase->transform(new (phase->C, 3) CmpUNode(adjusted, phase->intcon(bound))); 2.27 Node* newbool = phase->transform(new (phase->C, 2) BoolNode(newcmp, cond)); 2.28 - phase->hash_delete(dom_iff); 2.29 - dom_iff->set_req(1, phase->intcon(ctrl->as_Proj()->_con)); 2.30 - phase->is_IterGVN()->_worklist.push(dom_iff); 2.31 + phase->is_IterGVN()->replace_input_of(dom_iff, 1, phase->intcon(ctrl->as_Proj()->_con)); 2.32 phase->hash_delete(this); 2.33 set_req(1, newbool); 2.34 return this; 2.35 @@ -1042,17 +1038,15 @@ 2.36 // Loop ends when projection has no more uses. 2.37 for (DUIterator_Last jmin, j = ifp->last_outs(jmin); j >= jmin; --j) { 2.38 Node* s = ifp->last_out(j); // Get child of IfTrue/IfFalse 2.39 - igvn->hash_delete(s); // Yank from hash table before edge hacking 2.40 if( !s->depends_only_on_test() ) { 2.41 // Find the control input matching this def-use edge. 2.42 // For Regions it may not be in slot 0. 2.43 uint l; 2.44 for( l = 0; s->in(l) != ifp; l++ ) { } 2.45 - s->set_req(l, ctrl_target); 2.46 + igvn->replace_input_of(s, l, ctrl_target); 2.47 } else { // Else, for control producers, 2.48 - s->set_req(0, data_target); // Move child to data-target 2.49 + igvn->replace_input_of(s, 0, data_target); // Move child to data-target 2.50 } 2.51 - igvn->_worklist.push(s); // Revisit collapsed Phis 2.52 } // End for each child of a projection 2.53 2.54 igvn->remove_dead_node(ifp);
3.1 --- a/src/share/vm/opto/loopPredicate.cpp Tue Jun 12 14:31:44 2012 -0700 3.2 +++ b/src/share/vm/opto/loopPredicate.cpp Tue Jun 12 16:23:31 2012 -0700 3.3 @@ -212,9 +212,8 @@ 3.4 Node* use = rgn->fast_out(i); 3.5 if (use->is_Phi() && use->outcnt() > 0) { 3.6 assert(use->in(0) == rgn, ""); 3.7 - _igvn.hash_delete(use); 3.8 + _igvn.rehash_node_delayed(use); 3.9 use->add_req(use->in(proj_index)); 3.10 - _igvn._worklist.push(use); 3.11 has_phi = true; 3.12 } 3.13 } 3.14 @@ -284,9 +283,8 @@ 3.15 for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) { 3.16 Node* use = rgn->fast_out(i); 3.17 if (use->is_Phi() && use->outcnt() > 0) { 3.18 - hash_delete(use); 3.19 + rehash_node_delayed(use); 3.20 use->add_req(use->in(proj_index)); 3.21 - _worklist.push(use); 3.22 has_phi = true; 3.23 } 3.24 }
4.1 --- a/src/share/vm/opto/loopTransform.cpp Tue Jun 12 14:31:44 2012 -0700 4.2 +++ b/src/share/vm/opto/loopTransform.cpp Tue Jun 12 16:23:31 2012 -0700 4.3 @@ -961,9 +961,7 @@ 4.4 set_loop(zer_iff, loop->_parent); 4.5 4.6 // Plug in the false-path, taken if we need to skip post-loop 4.7 - _igvn.hash_delete( main_exit ); 4.8 - main_exit->set_req(0, zer_iff); 4.9 - _igvn._worklist.push(main_exit); 4.10 + _igvn.replace_input_of(main_exit, 0, zer_iff); 4.11 set_idom(main_exit, zer_iff, dd_main_exit); 4.12 set_idom(main_exit->unique_out(), zer_iff, dd_main_exit); 4.13 // Make the true-path, must enter the post loop 4.14 @@ -1956,9 +1954,7 @@ 4.15 C->set_major_progress(); 4.16 Node *kill_con = _igvn.intcon( 1-flip ); 4.17 set_ctrl(kill_con, C->root()); 4.18 - _igvn.hash_delete(iff); 4.19 - iff->set_req(1, kill_con); 4.20 - _igvn._worklist.push(iff); 4.21 + _igvn.replace_input_of(iff, 1, kill_con); 4.22 // Find surviving projection 4.23 assert(iff->is_If(), ""); 4.24 ProjNode* dp = ((IfNode*)iff)->proj_out(1-flip); 4.25 @@ -1966,11 +1962,9 @@ 4.26 for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) { 4.27 Node* cd = dp->fast_out(i); // Control-dependent node 4.28 if( cd->is_Load() ) { // Loads can now float around in the loop 4.29 - _igvn.hash_delete(cd); 4.30 // Allow the load to float around in the loop, or before it 4.31 // but NOT before the pre-loop. 4.32 - cd->set_req(0, ctrl); // ctrl, not NULL 4.33 - _igvn._worklist.push(cd); 4.34 + _igvn.replace_input_of(cd, 0, ctrl); // ctrl, not NULL 4.35 --i; 4.36 --imax; 4.37 } 4.38 @@ -2029,14 +2023,10 @@ 4.39 main_bol->set_req(1,main_cmp); 4.40 } 4.41 // Hack the now-private loop bounds 4.42 - _igvn.hash_delete(main_cmp); 4.43 - main_cmp->set_req(2, main_limit); 4.44 - _igvn._worklist.push(main_cmp); 4.45 + _igvn.replace_input_of(main_cmp, 2, main_limit); 4.46 // The OpaqueNode is unshared by design 4.47 - _igvn.hash_delete(opqzm); 4.48 assert( opqzm->outcnt() == 1, "cannot hack shared node" ); 4.49 - opqzm->set_req(1,main_limit); 4.50 - _igvn._worklist.push(opqzm); 4.51 + _igvn.replace_input_of(opqzm, 1, main_limit); 4.52 } 4.53 4.54 //------------------------------DCE_loop_body---------------------------------- 4.55 @@ -2178,9 +2168,7 @@ 4.56 Node* cmp = cl->loopexit()->cmp_node(); 4.57 assert(cl->limit() == cmp->in(2), "sanity"); 4.58 phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist 4.59 - phase->_igvn.hash_delete(cmp); 4.60 - cmp->set_req(2, exact_limit); 4.61 - phase->_igvn._worklist.push(cmp); // put cmp on worklist 4.62 + phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist 4.63 } 4.64 // Note: the final value after increment should not overflow since 4.65 // counted loop has limit check predicate.
5.1 --- a/src/share/vm/opto/loopUnswitch.cpp Tue Jun 12 14:31:44 2012 -0700 5.2 +++ b/src/share/vm/opto/loopUnswitch.cpp Tue Jun 12 16:23:31 2012 -0700 5.3 @@ -174,27 +174,21 @@ 5.4 Node* use = worklist.pop(); 5.5 Node* nuse = use->clone(); 5.6 nuse->set_req(0, invar_proj); 5.7 - _igvn.hash_delete(use); 5.8 - use->set_req(1, nuse); 5.9 - _igvn._worklist.push(use); 5.10 + _igvn.replace_input_of(use, 1, nuse); 5.11 register_new_node(nuse, invar_proj); 5.12 // Same for the clone 5.13 Node* use_clone = old_new[use->_idx]; 5.14 - _igvn.hash_delete(use_clone); 5.15 - use_clone->set_req(1, nuse); 5.16 - _igvn._worklist.push(use_clone); 5.17 + _igvn.replace_input_of(use_clone, 1, nuse); 5.18 } 5.19 } 5.20 5.21 // Hardwire the control paths in the loops into if(true) and if(false) 5.22 - _igvn.hash_delete(unswitch_iff); 5.23 + _igvn.rehash_node_delayed(unswitch_iff); 5.24 short_circuit_if(unswitch_iff, proj_true); 5.25 - _igvn._worklist.push(unswitch_iff); 5.26 5.27 IfNode* unswitch_iff_clone = old_new[unswitch_iff->_idx]->as_If(); 5.28 - _igvn.hash_delete(unswitch_iff_clone); 5.29 + _igvn.rehash_node_delayed(unswitch_iff_clone); 5.30 short_circuit_if(unswitch_iff_clone, proj_false); 5.31 - _igvn._worklist.push(unswitch_iff_clone); 5.32 5.33 // Reoptimize loops 5.34 loop->record_for_igvn(); 5.35 @@ -224,8 +218,7 @@ 5.36 LoopNode* head = loop->_head->as_Loop(); 5.37 bool counted_loop = head->is_CountedLoop(); 5.38 Node* entry = head->in(LoopNode::EntryControl); 5.39 - _igvn.hash_delete(entry); 5.40 - _igvn._worklist.push(entry); 5.41 + _igvn.rehash_node_delayed(entry); 5.42 IdealLoopTree* outer_loop = loop->_parent; 5.43 5.44 Node *cont = _igvn.intcon(1); 5.45 @@ -249,18 +242,14 @@ 5.46 5.47 // Fast (true) control 5.48 Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop); 5.49 - _igvn.hash_delete(head); 5.50 - head->set_req(LoopNode::EntryControl, iffast_pred); 5.51 + _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred); 5.52 set_idom(head, iffast_pred, dom_depth(head)); 5.53 - _igvn._worklist.push(head); 5.54 5.55 // Slow (false) control 5.56 Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop); 5.57 LoopNode* slow_head = old_new[head->_idx]->as_Loop(); 5.58 - _igvn.hash_delete(slow_head); 5.59 - slow_head->set_req(LoopNode::EntryControl, ifslow_pred); 5.60 + _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow_pred); 5.61 set_idom(slow_head, ifslow_pred, dom_depth(slow_head)); 5.62 - _igvn._worklist.push(slow_head); 5.63 5.64 recompute_dom_depth(); 5.65
6.1 --- a/src/share/vm/opto/loopnode.cpp Tue Jun 12 14:31:44 2012 -0700 6.2 +++ b/src/share/vm/opto/loopnode.cpp Tue Jun 12 16:23:31 2012 -0700 6.3 @@ -1129,8 +1129,7 @@ 6.4 // I'm mid-iteration over the Region's uses. 6.5 for (DUIterator_Last imin, i = old_phi->last_outs(imin); i >= imin; ) { 6.6 Node* use = old_phi->last_out(i); 6.7 - igvn.hash_delete(use); 6.8 - igvn._worklist.push(use); 6.9 + igvn.rehash_node_delayed(use); 6.10 uint uses_found = 0; 6.11 for (uint j = 0; j < use->len(); j++) { 6.12 if (use->in(j) == old_phi) { 6.13 @@ -1186,10 +1185,8 @@ 6.14 phi->init_req(LoopNode::LoopBackControl, old_phi->in(outer_idx)); 6.15 phi = igvn.register_new_node_with_optimizer(phi, old_phi); 6.16 // Make old Phi point to new Phi on the fall-in path 6.17 - igvn.hash_delete(old_phi); 6.18 - old_phi->set_req(LoopNode::EntryControl, phi); 6.19 + igvn.replace_input_of(old_phi, LoopNode::EntryControl, phi); 6.20 old_phi->del_req(outer_idx); 6.21 - igvn._worklist.push(old_phi); 6.22 } 6.23 } 6.24 6.25 @@ -1992,9 +1989,7 @@ 6.26 // we do it here. 6.27 for( uint i = 1; i < C->root()->req(); i++ ) { 6.28 if( !_nodes[C->root()->in(i)->_idx] ) { // Dead path into Root? 6.29 - _igvn.hash_delete(C->root()); 6.30 - C->root()->del_req(i); 6.31 - _igvn._worklist.push(C->root()); 6.32 + _igvn.delete_input_of(C->root(), i); 6.33 i--; // Rerun same iteration on compressed edges 6.34 } 6.35 }
7.1 --- a/src/share/vm/opto/loopopts.cpp Tue Jun 12 14:31:44 2012 -0700 7.2 +++ b/src/share/vm/opto/loopopts.cpp Tue Jun 12 16:23:31 2012 -0700 7.3 @@ -216,9 +216,7 @@ 7.4 Node *con = _igvn.makecon(pop == Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO); 7.5 set_ctrl(con, C->root()); // Constant gets a new use 7.6 // Hack the dominated test 7.7 - _igvn.hash_delete(iff); 7.8 - iff->set_req(1, con); 7.9 - _igvn._worklist.push(iff); 7.10 + _igvn.replace_input_of(iff, 1, con); 7.11 7.12 // If I dont have a reachable TRUE and FALSE path following the IfNode then 7.13 // I can assume this path reaches an infinite loop. In this case it's not 7.14 @@ -245,10 +243,8 @@ 7.15 Node* cd = dp->fast_out(i); // Control-dependent node 7.16 if (cd->depends_only_on_test()) { 7.17 assert(cd->in(0) == dp, ""); 7.18 - _igvn.hash_delete(cd); 7.19 - cd->set_req(0, prevdom); 7.20 + _igvn.replace_input_of(cd, 0, prevdom); 7.21 set_early_ctrl(cd); 7.22 - _igvn._worklist.push(cd); 7.23 IdealLoopTree *new_loop = get_loop(get_ctrl(cd)); 7.24 if (old_loop != new_loop) { 7.25 if (!old_loop->_child) old_loop->_body.yank(cd); 7.26 @@ -952,8 +948,7 @@ 7.27 if (!n->is_Load() || late_load_ctrl != n_ctrl) { 7.28 for (DUIterator_Last jmin, j = n->last_outs(jmin); j >= jmin; ) { 7.29 Node *u = n->last_out(j); // Clone private computation per use 7.30 - _igvn.hash_delete(u); 7.31 - _igvn._worklist.push(u); 7.32 + _igvn.rehash_node_delayed(u); 7.33 Node *x = n->clone(); // Clone computation 7.34 Node *x_ctrl = NULL; 7.35 if( u->is_Phi() ) { 7.36 @@ -1089,9 +1084,7 @@ 7.37 for( i = 1; i < phi->req(); i++ ) { 7.38 Node *b = phi->in(i); 7.39 if( b->is_Phi() ) { 7.40 - _igvn.hash_delete(phi); 7.41 - _igvn._worklist.push(phi); 7.42 - phi->set_req(i, clone_iff( b->as_Phi(), loop )); 7.43 + _igvn.replace_input_of(phi, i, clone_iff( b->as_Phi(), loop )); 7.44 } else { 7.45 assert( b->is_Bool(), "" ); 7.46 } 7.47 @@ -1161,9 +1154,7 @@ 7.48 for( i = 1; i < phi->req(); i++ ) { 7.49 Node *b = phi->in(i); 7.50 if( b->is_Phi() ) { 7.51 - _igvn.hash_delete(phi); 7.52 - _igvn._worklist.push(phi); 7.53 - phi->set_req(i, clone_bool( b->as_Phi(), loop )); 7.54 + _igvn.replace_input_of(phi, i, clone_bool( b->as_Phi(), loop )); 7.55 } else { 7.56 assert( b->is_Cmp() || b->is_top(), "inputs are all Cmp or TOP" ); 7.57 } 7.58 @@ -1347,8 +1338,7 @@ 7.59 // The original user of 'use' uses 'r' instead. 7.60 for (DUIterator_Last lmin, l = use->last_outs(lmin); l >= lmin;) { 7.61 Node* useuse = use->last_out(l); 7.62 - _igvn.hash_delete(useuse); 7.63 - _igvn._worklist.push(useuse); 7.64 + _igvn.rehash_node_delayed(useuse); 7.65 uint uses_found = 0; 7.66 if( useuse->in(0) == use ) { 7.67 useuse->set_req(0, r); 7.68 @@ -1435,9 +1425,7 @@ 7.69 if( use->is_Phi() ) // Phi use is in prior block 7.70 cfg = prev->in(idx); // NOT in block of Phi itself 7.71 if (cfg->is_top()) { // Use is dead? 7.72 - _igvn.hash_delete(use); 7.73 - _igvn._worklist.push(use); 7.74 - use->set_req(idx, C->top()); 7.75 + _igvn.replace_input_of(use, idx, C->top()); 7.76 continue; 7.77 } 7.78 7.79 @@ -1487,9 +1475,7 @@ 7.80 set_ctrl(phi, prev); 7.81 } 7.82 // Make 'use' use the Phi instead of the old loop body exit value 7.83 - _igvn.hash_delete(use); 7.84 - _igvn._worklist.push(use); 7.85 - use->set_req(idx, phi); 7.86 + _igvn.replace_input_of(use, idx, phi); 7.87 if( use->_idx >= new_counter ) { // If updating new phis 7.88 // Not needed for correctness, but prevents a weak assert 7.89 // in AddPNode from tripping (when we end up with different 7.90 @@ -1517,9 +1503,7 @@ 7.91 Node *iff = split_if_set->pop(); 7.92 if( iff->in(1)->is_Phi() ) { 7.93 BoolNode *b = clone_iff( iff->in(1)->as_Phi(), loop ); 7.94 - _igvn.hash_delete(iff); 7.95 - _igvn._worklist.push(iff); 7.96 - iff->set_req(1, b); 7.97 + _igvn.replace_input_of(iff, 1, b); 7.98 } 7.99 } 7.100 } 7.101 @@ -1529,9 +1513,7 @@ 7.102 Node *phi = b->in(1); 7.103 assert( phi->is_Phi(), "" ); 7.104 CmpNode *cmp = clone_bool( (PhiNode*)phi, loop ); 7.105 - _igvn.hash_delete(b); 7.106 - _igvn._worklist.push(b); 7.107 - b->set_req(1, cmp); 7.108 + _igvn.replace_input_of(b, 1, cmp); 7.109 } 7.110 } 7.111 if( split_cex_set ) { 7.112 @@ -1686,10 +1668,8 @@ 7.113 ProjNode *other_proj = iff->proj_out(!proj->is_IfTrue())->as_Proj(); 7.114 int ddepth = dom_depth(proj); 7.115 7.116 - _igvn.hash_delete(iff); 7.117 - _igvn._worklist.push(iff); 7.118 - _igvn.hash_delete(proj); 7.119 - _igvn._worklist.push(proj); 7.120 + _igvn.rehash_node_delayed(iff); 7.121 + _igvn.rehash_node_delayed(proj); 7.122 7.123 proj->set_req(0, NULL); // temporary disconnect 7.124 ProjNode* proj2 = proj_clone(proj, iff); 7.125 @@ -1745,10 +1725,8 @@ 7.126 ProjNode *other_proj = iff->proj_out(!proj->is_IfTrue())->as_Proj(); 7.127 int ddepth = dom_depth(proj); 7.128 7.129 - _igvn.hash_delete(iff); 7.130 - _igvn._worklist.push(iff); 7.131 - _igvn.hash_delete(proj); 7.132 - _igvn._worklist.push(proj); 7.133 + _igvn.rehash_node_delayed(iff); 7.134 + _igvn.rehash_node_delayed(proj); 7.135 7.136 proj->set_req(0, NULL); // temporary disconnect 7.137 ProjNode* proj2 = proj_clone(proj, iff); 7.138 @@ -1970,9 +1948,7 @@ 7.139 7.140 // clone "n" and insert it between the inputs of "n" and the use outside the loop 7.141 Node* n_clone = n->clone(); 7.142 - _igvn.hash_delete(use); 7.143 - use->set_req(j, n_clone); 7.144 - _igvn._worklist.push(use); 7.145 + _igvn.replace_input_of(use, j, n_clone); 7.146 Node* use_c; 7.147 if (!use->is_Phi()) { 7.148 use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0); 7.149 @@ -2028,8 +2004,7 @@ 7.150 #endif 7.151 while( worklist.size() ) { 7.152 Node *use = worklist.pop(); 7.153 - _igvn.hash_delete(use); 7.154 - _igvn._worklist.push(use); 7.155 + _igvn.rehash_node_delayed(use); 7.156 for (uint j = 1; j < use->req(); j++) { 7.157 if (use->in(j) == n) { 7.158 use->set_req(j, n_clone); 7.159 @@ -2055,9 +2030,7 @@ 7.160 _igvn.remove_dead_node(phi); 7.161 phi = hit; 7.162 } 7.163 - _igvn.hash_delete(use); 7.164 - _igvn._worklist.push(use); 7.165 - use->set_req(idx, phi); 7.166 + _igvn.replace_input_of(use, idx, phi); 7.167 } 7.168 7.169 #ifdef ASSERT 7.170 @@ -2630,9 +2603,7 @@ 7.171 // use is in loop 7.172 if (old_new[use->_idx] != NULL) { // null for dead code 7.173 Node* use_clone = old_new[use->_idx]; 7.174 - _igvn.hash_delete(use); 7.175 - use->set_req(j, C->top()); 7.176 - _igvn._worklist.push(use); 7.177 + _igvn.replace_input_of(use, j, C->top()); 7.178 insert_phi_for_loop( use_clone, j, old_new[def->_idx], def, new_head_clone ); 7.179 } 7.180 } else { 7.181 @@ -2667,46 +2638,35 @@ 7.182 if (!n->is_CFG() && n->in(0) != NULL && 7.183 not_peel.test(n->_idx) && peel.test(n->in(0)->_idx)) { 7.184 Node* n_clone = old_new[n->_idx]; 7.185 - _igvn.hash_delete(n_clone); 7.186 - n_clone->set_req(0, new_head_clone); 7.187 - _igvn._worklist.push(n_clone); 7.188 + _igvn.replace_input_of(n_clone, 0, new_head_clone); 7.189 } 7.190 } 7.191 7.192 // Backedge of the surviving new_head (the clone) is original last_peel 7.193 - _igvn.hash_delete(new_head_clone); 7.194 - new_head_clone->set_req(LoopNode::LoopBackControl, last_peel); 7.195 - _igvn._worklist.push(new_head_clone); 7.196 + _igvn.replace_input_of(new_head_clone, LoopNode::LoopBackControl, last_peel); 7.197 7.198 // Cut first node in original not_peel set 7.199 - _igvn.hash_delete(new_head); 7.200 - new_head->set_req(LoopNode::EntryControl, C->top()); 7.201 - new_head->set_req(LoopNode::LoopBackControl, C->top()); 7.202 - _igvn._worklist.push(new_head); 7.203 + _igvn.rehash_node_delayed(new_head); // Multiple edge updates: 7.204 + new_head->set_req(LoopNode::EntryControl, C->top()); // use rehash_node_delayed / set_req instead of 7.205 + new_head->set_req(LoopNode::LoopBackControl, C->top()); // multiple replace_input_of calls 7.206 7.207 // Copy head_clone back-branch info to original head 7.208 // and remove original head's loop entry and 7.209 // clone head's back-branch 7.210 - _igvn.hash_delete(head); 7.211 - _igvn.hash_delete(head_clone); 7.212 - head->set_req(LoopNode::EntryControl, head_clone->in(LoopNode::LoopBackControl)); 7.213 + _igvn.rehash_node_delayed(head); // Multiple edge updates 7.214 + head->set_req(LoopNode::EntryControl, head_clone->in(LoopNode::LoopBackControl)); 7.215 head->set_req(LoopNode::LoopBackControl, C->top()); 7.216 - head_clone->set_req(LoopNode::LoopBackControl, C->top()); 7.217 - _igvn._worklist.push(head); 7.218 - _igvn._worklist.push(head_clone); 7.219 + _igvn.replace_input_of(head_clone, LoopNode::LoopBackControl, C->top()); 7.220 7.221 // Similarly modify the phis 7.222 for (DUIterator_Fast kmax, k = head->fast_outs(kmax); k < kmax; k++) { 7.223 Node* use = head->fast_out(k); 7.224 if (use->is_Phi() && use->outcnt() > 0) { 7.225 Node* use_clone = old_new[use->_idx]; 7.226 - _igvn.hash_delete(use); 7.227 - _igvn.hash_delete(use_clone); 7.228 - use->set_req(LoopNode::EntryControl, use_clone->in(LoopNode::LoopBackControl)); 7.229 + _igvn.rehash_node_delayed(use); // Multiple edge updates 7.230 + use->set_req(LoopNode::EntryControl, use_clone->in(LoopNode::LoopBackControl)); 7.231 use->set_req(LoopNode::LoopBackControl, C->top()); 7.232 - use_clone->set_req(LoopNode::LoopBackControl, C->top()); 7.233 - _igvn._worklist.push(use); 7.234 - _igvn._worklist.push(use_clone); 7.235 + _igvn.replace_input_of(use_clone, LoopNode::LoopBackControl, C->top()); 7.236 } 7.237 } 7.238 7.239 @@ -2792,8 +2752,7 @@ 7.240 set_ctrl(neg_stride, C->root()); 7.241 Node *post = new (C, 3) AddINode( opaq, neg_stride); 7.242 register_new_node( post, u_ctrl ); 7.243 - _igvn.hash_delete(use); 7.244 - _igvn._worklist.push(use); 7.245 + _igvn.rehash_node_delayed(use); 7.246 for (uint j = 1; j < use->req(); j++) { 7.247 if (use->in(j) == phi) 7.248 use->set_req(j, post);
8.1 --- a/src/share/vm/opto/macro.cpp Tue Jun 12 14:31:44 2012 -0700 8.2 +++ b/src/share/vm/opto/macro.cpp Tue Jun 12 16:23:31 2012 -0700 8.3 @@ -1447,9 +1447,8 @@ 8.4 if (!always_slow && _memproj_fallthrough != NULL) { 8.5 for (DUIterator_Fast imax, i = _memproj_fallthrough->fast_outs(imax); i < imax; i++) { 8.6 Node *use = _memproj_fallthrough->fast_out(i); 8.7 - _igvn.hash_delete(use); 8.8 + _igvn.rehash_node_delayed(use); 8.9 imax -= replace_input(use, _memproj_fallthrough, result_phi_rawmem); 8.10 - _igvn._worklist.push(use); 8.11 // back up iterator 8.12 --i; 8.13 } 8.14 @@ -1463,9 +1462,8 @@ 8.15 } 8.16 for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) { 8.17 Node *use = _memproj_catchall->fast_out(i); 8.18 - _igvn.hash_delete(use); 8.19 + _igvn.rehash_node_delayed(use); 8.20 imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough); 8.21 - _igvn._worklist.push(use); 8.22 // back up iterator 8.23 --i; 8.24 } 8.25 @@ -1481,9 +1479,8 @@ 8.26 if (_ioproj_fallthrough != NULL) { 8.27 for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) { 8.28 Node *use = _ioproj_fallthrough->fast_out(i); 8.29 - _igvn.hash_delete(use); 8.30 + _igvn.rehash_node_delayed(use); 8.31 imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o); 8.32 - _igvn._worklist.push(use); 8.33 // back up iterator 8.34 --i; 8.35 } 8.36 @@ -1497,9 +1494,8 @@ 8.37 } 8.38 for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) { 8.39 Node *use = _ioproj_catchall->fast_out(i); 8.40 - _igvn.hash_delete(use); 8.41 + _igvn.rehash_node_delayed(use); 8.42 imax -= replace_input(use, _ioproj_catchall, _ioproj_fallthrough); 8.43 - _igvn._worklist.push(use); 8.44 // back up iterator 8.45 --i; 8.46 } 8.47 @@ -1857,18 +1853,16 @@ 8.48 if (alock->box_node() == oldbox && alock->obj_node()->eqv_uncast(obj)) { 8.49 // Replace Box and mark eliminated all related locks and unlocks. 8.50 alock->set_non_esc_obj(); 8.51 - _igvn.hash_delete(alock); 8.52 + _igvn.rehash_node_delayed(alock); 8.53 alock->set_box_node(newbox); 8.54 - _igvn._worklist.push(alock); 8.55 next_edge = false; 8.56 } 8.57 } 8.58 if (u->is_FastLock() && u->as_FastLock()->obj_node()->eqv_uncast(obj)) { 8.59 FastLockNode* flock = u->as_FastLock(); 8.60 assert(flock->box_node() == oldbox, "sanity"); 8.61 - _igvn.hash_delete(flock); 8.62 + _igvn.rehash_node_delayed(flock); 8.63 flock->set_box_node(newbox); 8.64 - _igvn._worklist.push(flock); 8.65 next_edge = false; 8.66 } 8.67 8.68 @@ -1886,9 +1880,7 @@ 8.69 Node* box_node = sfn->monitor_box(jvms, idx); 8.70 if (box_node == oldbox && obj_node->eqv_uncast(obj)) { 8.71 int j = jvms->monitor_box_offset(idx); 8.72 - _igvn.hash_delete(u); 8.73 - u->set_req(j, newbox); 8.74 - _igvn._worklist.push(u); 8.75 + _igvn.replace_input_of(u, j, newbox); 8.76 next_edge = false; 8.77 } 8.78 }
9.1 --- a/src/share/vm/opto/phaseX.hpp Tue Jun 12 14:31:44 2012 -0700 9.2 +++ b/src/share/vm/opto/phaseX.hpp Tue Jun 12 16:23:31 2012 -0700 9.3 @@ -460,6 +460,25 @@ 9.4 subsume_node(old, nn); 9.5 } 9.6 9.7 + // Delayed node rehash: remove a node from the hash table and rehash it during 9.8 + // next optimizing pass 9.9 + void rehash_node_delayed(Node* n) { 9.10 + hash_delete(n); 9.11 + _worklist.push(n); 9.12 + } 9.13 + 9.14 + // Replace ith edge of "n" with "in" 9.15 + void replace_input_of(Node* n, int i, Node* in) { 9.16 + rehash_node_delayed(n); 9.17 + n->set_req(i, in); 9.18 + } 9.19 + 9.20 + // Delete ith edge of "n" 9.21 + void delete_input_of(Node* n, int i) { 9.22 + rehash_node_delayed(n); 9.23 + n->del_req(i); 9.24 + } 9.25 + 9.26 bool delay_transform() const { return _delay_transform; } 9.27 9.28 void set_delay_transform(bool delay) {
10.1 --- a/src/share/vm/opto/split_if.cpp Tue Jun 12 14:31:44 2012 -0700 10.2 +++ b/src/share/vm/opto/split_if.cpp Tue Jun 12 16:23:31 2012 -0700 10.3 @@ -137,9 +137,7 @@ 10.4 Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff); 10.5 Node *x = bol->clone(); 10.6 register_new_node(x, iff_ctrl); 10.7 - _igvn.hash_delete(iff); 10.8 - iff->set_req(1, x); 10.9 - _igvn._worklist.push(iff); 10.10 + _igvn.replace_input_of(iff, 1, x); 10.11 } 10.12 _igvn.remove_dead_node( bol ); 10.13 --i; 10.14 @@ -151,9 +149,7 @@ 10.15 assert( bol->in(1) == n, "" ); 10.16 Node *x = n->clone(); 10.17 register_new_node(x, get_ctrl(bol)); 10.18 - _igvn.hash_delete(bol); 10.19 - bol->set_req(1, x); 10.20 - _igvn._worklist.push(bol); 10.21 + _igvn.replace_input_of(bol, 1, x); 10.22 } 10.23 _igvn.remove_dead_node( n ); 10.24 10.25 @@ -387,9 +383,7 @@ 10.26 if( use->in(i) == def ) 10.27 break; 10.28 assert( i < use->req(), "def should be among use's inputs" ); 10.29 - _igvn.hash_delete(use); 10.30 - use->set_req(i, new_def); 10.31 - _igvn._worklist.push(use); 10.32 + _igvn.replace_input_of(use, i, new_def); 10.33 } 10.34 10.35 //------------------------------do_split_if------------------------------------
11.1 --- a/src/share/vm/opto/superword.cpp Tue Jun 12 14:31:44 2012 -0700 11.2 +++ b/src/share/vm/opto/superword.cpp Tue Jun 12 16:23:31 2012 -0700 11.3 @@ -944,7 +944,7 @@ 11.4 void SuperWord::remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip, 11.5 Node *uip, Unique_Node_List &sched_before) { 11.6 Node* my_mem = current->in(MemNode::Memory); 11.7 - _igvn.hash_delete(current); 11.8 + _igvn.rehash_node_delayed(current); 11.9 _igvn.hash_delete(my_mem); 11.10 11.11 //remove current_store from its current position in the memmory graph 11.12 @@ -952,7 +952,7 @@ 11.13 Node* use = current->out(i); 11.14 if (use->is_Mem()) { 11.15 assert(use->in(MemNode::Memory) == current, "must be"); 11.16 - _igvn.hash_delete(use); 11.17 + _igvn.rehash_node_delayed(use); 11.18 if (use == prev) { // connect prev to my_mem 11.19 use->set_req(MemNode::Memory, my_mem); 11.20 } else if (sched_before.member(use)) { 11.21 @@ -962,7 +962,6 @@ 11.22 _igvn.hash_delete(lip); 11.23 use->set_req(MemNode::Memory, lip); 11.24 } 11.25 - _igvn._worklist.push(use); 11.26 --i; //deleted this edge; rescan position 11.27 } 11.28 } 11.29 @@ -976,25 +975,20 @@ 11.30 Node* use = insert_pt->out(i); 11.31 if (use->is_Mem()) { 11.32 assert(use->in(MemNode::Memory) == insert_pt, "must be"); 11.33 - _igvn.hash_delete(use); 11.34 - use->set_req(MemNode::Memory, current); 11.35 - _igvn._worklist.push(use); 11.36 + _igvn.replace_input_of(use, MemNode::Memory, current); 11.37 --i; //deleted this edge; rescan position 11.38 } else if (!sched_up && use->is_Phi() && use->bottom_type() == Type::MEMORY) { 11.39 uint pos; //lip (lower insert point) must be the last one in the memory slice 11.40 - _igvn.hash_delete(use); 11.41 for (pos=1; pos < use->req(); pos++) { 11.42 if (use->in(pos) == insert_pt) break; 11.43 } 11.44 - use->set_req(pos, current); 11.45 - _igvn._worklist.push(use); 11.46 + _igvn.replace_input_of(use, pos, current); 11.47 --i; 11.48 } 11.49 } 11.50 11.51 //connect current to insert_pt 11.52 current->set_req(MemNode::Memory, insert_pt); 11.53 - _igvn._worklist.push(current); 11.54 } 11.55 11.56 //------------------------------co_locate_pack---------------------------------- 11.57 @@ -1077,15 +1071,13 @@ 11.58 Node* use = current->out(i); 11.59 if (use->is_Mem() && use != previous) { 11.60 assert(use->in(MemNode::Memory) == current, "must be"); 11.61 - _igvn.hash_delete(use); 11.62 if (schedule_before_pack.member(use)) { 11.63 _igvn.hash_delete(upper_insert_pt); 11.64 - use->set_req(MemNode::Memory, upper_insert_pt); 11.65 + _igvn.replace_input_of(use, MemNode::Memory, upper_insert_pt); 11.66 } else { 11.67 _igvn.hash_delete(lower_insert_pt); 11.68 - use->set_req(MemNode::Memory, lower_insert_pt); 11.69 + _igvn.replace_input_of(use, MemNode::Memory, lower_insert_pt); 11.70 } 11.71 - _igvn._worklist.push(use); 11.72 --i; // deleted this edge; rescan position 11.73 } 11.74 } 11.75 @@ -1122,9 +1114,7 @@ 11.76 // Give each load the same memory state 11.77 for (uint i = 0; i < pk->size(); i++) { 11.78 LoadNode* ld = pk->at(i)->as_Load(); 11.79 - _igvn.hash_delete(ld); 11.80 - ld->set_req(MemNode::Memory, mem_input); 11.81 - _igvn._worklist.push(ld); 11.82 + _igvn.replace_input_of(ld, MemNode::Memory, mem_input); 11.83 } 11.84 } 11.85 } 11.86 @@ -1282,16 +1272,14 @@ 11.87 11.88 // Insert extract operation 11.89 _igvn.hash_delete(def); 11.90 - _igvn.hash_delete(use); 11.91 int def_pos = alignment(def) / data_size(def); 11.92 const Type* def_t = velt_type(def); 11.93 11.94 Node* ex = ExtractNode::make(_phase->C, def, def_pos, def_t); 11.95 _phase->_igvn.register_new_node_with_optimizer(ex); 11.96 _phase->set_ctrl(ex, _phase->get_ctrl(def)); 11.97 - use->set_req(idx, ex); 11.98 + _igvn.replace_input_of(use, idx, ex); 11.99 _igvn._worklist.push(def); 11.100 - _igvn._worklist.push(use); 11.101 11.102 bb_insert_after(ex, bb_idx(def)); 11.103 set_velt_type(ex, def_t);