Merge

Tue, 24 Jul 2012 13:16:26 -0400

author
jiangli
date
Tue, 24 Jul 2012 13:16:26 -0400
changeset 3948
a93a6d2c9e6c
parent 3944
aba91a731143
parent 3947
611e8a669a2c
child 3949
bcd1b9d98558

Merge

     1.1 --- a/src/share/vm/opto/phaseX.cpp	Mon Jul 23 13:04:59 2012 -0700
     1.2 +++ b/src/share/vm/opto/phaseX.cpp	Tue Jul 24 13:16:26 2012 -0400
     1.3 @@ -757,6 +757,7 @@
     1.4  //------------------------------PhaseIterGVN-----------------------------------
     1.5  // Initialize hash table to fresh and clean for +VerifyOpto
     1.6  PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn, const char *dummy ) : PhaseGVN(igvn,dummy), _worklist( ),
     1.7 +                                                                      _stack(C->unique() >> 1),
     1.8                                                                        _delay_transform(false) {
     1.9  }
    1.10  
    1.11 @@ -764,6 +765,7 @@
    1.12  // Initialize with previous PhaseIterGVN info; used by PhaseCCP
    1.13  PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn ) : PhaseGVN(igvn),
    1.14                                                     _worklist( igvn->_worklist ),
    1.15 +                                                   _stack( igvn->_stack ),
    1.16                                                     _delay_transform(igvn->_delay_transform)
    1.17  {
    1.18  }
    1.19 @@ -772,6 +774,7 @@
    1.20  // Initialize with previous PhaseGVN info from Parser
    1.21  PhaseIterGVN::PhaseIterGVN( PhaseGVN *gvn ) : PhaseGVN(gvn),
    1.22                                                _worklist(*C->for_igvn()),
    1.23 +                                              _stack(C->unique() >> 1),
    1.24                                                _delay_transform(false)
    1.25  {
    1.26    uint max;
    1.27 @@ -1138,51 +1141,77 @@
    1.28  // Kill a globally dead Node.  All uses are also globally dead and are
    1.29  // aggressively trimmed.
    1.30  void PhaseIterGVN::remove_globally_dead_node( Node *dead ) {
    1.31 -  assert(dead != C->root(), "killing root, eh?");
    1.32 -  if (dead->is_top())  return;
    1.33 -  NOT_PRODUCT( set_progress(); )
    1.34 -  // Remove from iterative worklist
    1.35 -  _worklist.remove(dead);
    1.36 -  if (!dead->is_Con()) { // Don't kill cons but uses
    1.37 -    // Remove from hash table
    1.38 -    _table.hash_delete( dead );
    1.39 -    // Smash all inputs to 'dead', isolating him completely
    1.40 -    for( uint i = 0; i < dead->req(); i++ ) {
    1.41 -      Node *in = dead->in(i);
    1.42 -      if( in ) {                 // Points to something?
    1.43 -        dead->set_req(i,NULL);  // Kill the edge
    1.44 -        if (in->outcnt() == 0 && in != C->top()) {// Made input go dead?
    1.45 -          remove_dead_node(in); // Recursively remove
    1.46 -        } else if (in->outcnt() == 1 &&
    1.47 -                   in->has_special_unique_user()) {
    1.48 -          _worklist.push(in->unique_out());
    1.49 -        } else if (in->outcnt() <= 2 && dead->is_Phi()) {
    1.50 -          if( in->Opcode() == Op_Region )
    1.51 -            _worklist.push(in);
    1.52 -          else if( in->is_Store() ) {
    1.53 -            DUIterator_Fast imax, i = in->fast_outs(imax);
    1.54 -            _worklist.push(in->fast_out(i));
    1.55 -            i++;
    1.56 -            if(in->outcnt() == 2) {
    1.57 -              _worklist.push(in->fast_out(i));
    1.58 -              i++;
    1.59 +  enum DeleteProgress {
    1.60 +    PROCESS_INPUTS,
    1.61 +    PROCESS_OUTPUTS
    1.62 +  };
    1.63 +  assert(_stack.is_empty(), "not empty");
    1.64 +  _stack.push(dead, PROCESS_INPUTS);
    1.65 +
    1.66 +  while (_stack.is_nonempty()) {
    1.67 +    dead = _stack.node();
    1.68 +    uint progress_state = _stack.index();
    1.69 +    assert(dead != C->root(), "killing root, eh?");
    1.70 +    assert(!dead->is_top(), "add check for top when pushing");
    1.71 +    NOT_PRODUCT( set_progress(); )
    1.72 +    if (progress_state == PROCESS_INPUTS) {
    1.73 +      // After following inputs, continue to outputs
    1.74 +      _stack.set_index(PROCESS_OUTPUTS);
    1.75 +      // Remove from iterative worklist
    1.76 +      _worklist.remove(dead);
    1.77 +      if (!dead->is_Con()) { // Don't kill cons but uses
    1.78 +        bool recurse = false;
    1.79 +        // Remove from hash table
    1.80 +        _table.hash_delete( dead );
    1.81 +        // Smash all inputs to 'dead', isolating him completely
    1.82 +        for( uint i = 0; i < dead->req(); i++ ) {
    1.83 +          Node *in = dead->in(i);
    1.84 +          if( in ) {                 // Points to something?
    1.85 +            dead->set_req(i,NULL);  // Kill the edge
    1.86 +            if (in->outcnt() == 0 && in != C->top()) {// Made input go dead?
    1.87 +              _stack.push(in, PROCESS_INPUTS); // Recursively remove
    1.88 +              recurse = true;
    1.89 +            } else if (in->outcnt() == 1 &&
    1.90 +                       in->has_special_unique_user()) {
    1.91 +              _worklist.push(in->unique_out());
    1.92 +            } else if (in->outcnt() <= 2 && dead->is_Phi()) {
    1.93 +              if( in->Opcode() == Op_Region )
    1.94 +                _worklist.push(in);
    1.95 +              else if( in->is_Store() ) {
    1.96 +                DUIterator_Fast imax, i = in->fast_outs(imax);
    1.97 +                _worklist.push(in->fast_out(i));
    1.98 +                i++;
    1.99 +                if(in->outcnt() == 2) {
   1.100 +                  _worklist.push(in->fast_out(i));
   1.101 +                  i++;
   1.102 +                }
   1.103 +                assert(!(i < imax), "sanity");
   1.104 +              }
   1.105              }
   1.106 -            assert(!(i < imax), "sanity");
   1.107            }
   1.108          }
   1.109 +
   1.110 +        if (dead->is_macro()) {
   1.111 +          C->remove_macro_node(dead);
   1.112 +        }
   1.113 +
   1.114 +        if (recurse) {
   1.115 +          continue;
   1.116 +        }
   1.117        }
   1.118      }
   1.119  
   1.120 -    if (dead->is_macro()) {
   1.121 -      C->remove_macro_node(dead);
   1.122 +    // Aggressively kill globally dead uses
   1.123 +    // (Rather than pushing all the outs at once, we push one at a time,
   1.124 +    // plus the parent to resume later, because of the indefinite number
   1.125 +    // of edge deletions per loop trip.)
   1.126 +    if (dead->outcnt() > 0) {
   1.127 +      // Recursively remove
   1.128 +      _stack.push(dead->raw_out(0), PROCESS_INPUTS);
   1.129 +    } else {
   1.130 +      _stack.pop();
   1.131      }
   1.132    }
   1.133 -  // Aggressively kill globally dead uses
   1.134 -  // (Cannot use DUIterator_Last because of the indefinite number
   1.135 -  // of edge deletions per loop trip.)
   1.136 -  while (dead->outcnt() > 0) {
   1.137 -    remove_globally_dead_node(dead->raw_out(0));
   1.138 -  }
   1.139  }
   1.140  
   1.141  //------------------------------subsume_node-----------------------------------
     2.1 --- a/src/share/vm/opto/phaseX.hpp	Mon Jul 23 13:04:59 2012 -0700
     2.2 +++ b/src/share/vm/opto/phaseX.hpp	Tue Jul 24 13:16:26 2012 -0400
     2.3 @@ -403,6 +403,8 @@
     2.4    // Subsume users of node 'old' into node 'nn'
     2.5    void subsume_node( Node *old, Node *nn );
     2.6  
     2.7 +  Node_Stack _stack;      // Stack used to avoid recursion
     2.8 +
     2.9  protected:
    2.10  
    2.11    // Idealize new Node 'n' with respect to its inputs and its value
    2.12 @@ -438,8 +440,8 @@
    2.13    // It is significant only for debugging and profiling.
    2.14    Node* register_new_node_with_optimizer(Node* n, Node* orig = NULL);
    2.15  
    2.16 -  // Kill a globally dead Node.   It is allowed to have uses which are
    2.17 -  // assumed dead and left 'in limbo'.
    2.18 +  // Kill a globally dead Node.  All uses are also globally dead and are
    2.19 +  // aggressively trimmed.
    2.20    void remove_globally_dead_node( Node *dead );
    2.21  
    2.22    // Kill all inputs to a dead node, recursively making more dead nodes.

mercurial