7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable

Tue, 12 Jun 2012 16:23:31 -0700

author
kvn
date
Tue, 12 Jun 2012 16:23:31 -0700
changeset 3847
5e990493719e
parent 3846
8b0a4867acf0
child 3848
e2fe93124108

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

src/share/vm/opto/domgraph.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/ifnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/loopPredicate.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/loopTransform.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/loopUnswitch.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/loopnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/loopopts.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/macro.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/phaseX.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/split_if.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/superword.cpp file | annotate | diff | comparison | revisions
     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);

mercurial