src/share/vm/opto/domgraph.cpp

changeset 5539
adb9a7d94cb5
parent 5509
d1034bd8cefc
child 5635
650868c062a9
     1.1 --- a/src/share/vm/opto/domgraph.cpp	Thu Aug 15 11:59:19 2013 -0700
     1.2 +++ b/src/share/vm/opto/domgraph.cpp	Fri Aug 16 10:23:55 2013 +0200
     1.3 @@ -32,9 +32,6 @@
     1.4  
     1.5  // Portions of code courtesy of Clifford Click
     1.6  
     1.7 -// Optimization - Graph Style
     1.8 -
     1.9 -//------------------------------Tarjan-----------------------------------------
    1.10  // A data structure that holds all the information needed to find dominators.
    1.11  struct Tarjan {
    1.12    Block *_block;                // Basic block for this info
    1.13 @@ -60,23 +57,21 @@
    1.14  
    1.15  };
    1.16  
    1.17 -//------------------------------Dominator--------------------------------------
    1.18  // Compute the dominator tree of the CFG.  The CFG must already have been
    1.19  // constructed.  This is the Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
    1.20 -void PhaseCFG::Dominators( ) {
    1.21 +void PhaseCFG::build_dominator_tree() {
    1.22    // Pre-grow the blocks array, prior to the ResourceMark kicking in
    1.23 -  _blocks.map(_num_blocks,0);
    1.24 +  _blocks.map(number_of_blocks(), 0);
    1.25  
    1.26    ResourceMark rm;
    1.27    // Setup mappings from my Graph to Tarjan's stuff and back
    1.28    // Note: Tarjan uses 1-based arrays
    1.29 -  Tarjan *tarjan = NEW_RESOURCE_ARRAY(Tarjan,_num_blocks+1);
    1.30 +  Tarjan* tarjan = NEW_RESOURCE_ARRAY(Tarjan, number_of_blocks() + 1);
    1.31  
    1.32    // Tarjan's algorithm, almost verbatim:
    1.33    // Step 1:
    1.34 -  _rpo_ctr = _num_blocks;
    1.35 -  uint dfsnum = DFS( tarjan );
    1.36 -  if( dfsnum-1 != _num_blocks ) {// Check for unreachable loops!
    1.37 +  uint dfsnum = do_DFS(tarjan, number_of_blocks());
    1.38 +  if (dfsnum - 1 != number_of_blocks()) { // Check for unreachable loops!
    1.39      // If the returned dfsnum does not match the number of blocks, then we
    1.40      // must have some unreachable loops.  These can be made at any time by
    1.41      // IterGVN.  They are cleaned up by CCP or the loop opts, but the last
    1.42 @@ -93,14 +88,13 @@
    1.43      C->record_method_not_compilable("unreachable loop");
    1.44      return;
    1.45    }
    1.46 -  _blocks._cnt = _num_blocks;
    1.47 +  _blocks._cnt = number_of_blocks();
    1.48  
    1.49    // Tarjan is using 1-based arrays, so these are some initialize flags
    1.50    tarjan[0]._size = tarjan[0]._semi = 0;
    1.51    tarjan[0]._label = &tarjan[0];
    1.52  
    1.53 -  uint i;
    1.54 -  for( i=_num_blocks; i>=2; i-- ) { // For all vertices in DFS order
    1.55 +  for (uint i = number_of_blocks(); i >= 2; i--) { // For all vertices in DFS order
    1.56      Tarjan *w = &tarjan[i];     // Get vertex from DFS
    1.57  
    1.58      // Step 2:
    1.59 @@ -130,19 +124,19 @@
    1.60    }
    1.61  
    1.62    // Step 4:
    1.63 -  for( i=2; i <= _num_blocks; i++ ) {
    1.64 +  for (uint i = 2; i <= number_of_blocks(); i++) {
    1.65      Tarjan *w = &tarjan[i];
    1.66      if( w->_dom != &tarjan[w->_semi] )
    1.67        w->_dom = w->_dom->_dom;
    1.68      w->_dom_next = w->_dom_child = NULL;  // Initialize for building tree later
    1.69    }
    1.70    // No immediate dominator for the root
    1.71 -  Tarjan *w = &tarjan[_broot->_pre_order];
    1.72 +  Tarjan *w = &tarjan[get_root_block()->_pre_order];
    1.73    w->_dom = NULL;
    1.74    w->_dom_next = w->_dom_child = NULL;  // Initialize for building tree later
    1.75  
    1.76    // Convert the dominator tree array into my kind of graph
    1.77 -  for( i=1; i<=_num_blocks;i++){// For all Tarjan vertices
    1.78 +  for(uint i = 1; i <= number_of_blocks(); i++){ // For all Tarjan vertices
    1.79      Tarjan *t = &tarjan[i];     // Handy access
    1.80      Tarjan *tdom = t->_dom;     // Handy access to immediate dominator
    1.81      if( tdom )  {               // Root has no immediate dominator
    1.82 @@ -152,11 +146,10 @@
    1.83      } else
    1.84        t->_block->_idom = NULL;  // Root
    1.85    }
    1.86 -  w->setdepth( _num_blocks+1 ); // Set depth in dominator tree
    1.87 +  w->setdepth(number_of_blocks() + 1); // Set depth in dominator tree
    1.88  
    1.89  }
    1.90  
    1.91 -//----------------------------Block_Stack--------------------------------------
    1.92  class Block_Stack {
    1.93    private:
    1.94      struct Block_Descr {
    1.95 @@ -214,7 +207,6 @@
    1.96      }
    1.97  };
    1.98  
    1.99 -//-------------------------most_frequent_successor-----------------------------
   1.100  // Find the index into the b->succs[] array of the most frequent successor.
   1.101  uint Block_Stack::most_frequent_successor( Block *b ) {
   1.102    uint freq_idx = 0;
   1.103 @@ -258,40 +250,38 @@
   1.104    return freq_idx;
   1.105  }
   1.106  
   1.107 -//------------------------------DFS--------------------------------------------
   1.108  // Perform DFS search.  Setup 'vertex' as DFS to vertex mapping.  Setup
   1.109  // 'semi' as vertex to DFS mapping.  Set 'parent' to DFS parent.
   1.110 -uint PhaseCFG::DFS( Tarjan *tarjan ) {
   1.111 -  Block *b = _broot;
   1.112 +uint PhaseCFG::do_DFS(Tarjan *tarjan, uint rpo_counter) {
   1.113 +  Block* root_block = get_root_block();
   1.114    uint pre_order = 1;
   1.115 -  // Allocate stack of size _num_blocks+1 to avoid frequent realloc
   1.116 -  Block_Stack bstack(tarjan, _num_blocks+1);
   1.117 +  // Allocate stack of size number_of_blocks() + 1 to avoid frequent realloc
   1.118 +  Block_Stack bstack(tarjan, number_of_blocks() + 1);
   1.119  
   1.120    // Push on stack the state for the first block
   1.121 -  bstack.push(pre_order, b);
   1.122 +  bstack.push(pre_order, root_block);
   1.123    ++pre_order;
   1.124  
   1.125    while (bstack.is_nonempty()) {
   1.126      if (!bstack.last_successor()) {
   1.127        // Walk over all successors in pre-order (DFS).
   1.128 -      Block *s = bstack.next_successor();
   1.129 -      if (s->_pre_order == 0) { // Check for no-pre-order, not-visited
   1.130 +      Block* next_block = bstack.next_successor();
   1.131 +      if (next_block->_pre_order == 0) { // Check for no-pre-order, not-visited
   1.132          // Push on stack the state of successor
   1.133 -        bstack.push(pre_order, s);
   1.134 +        bstack.push(pre_order, next_block);
   1.135          ++pre_order;
   1.136        }
   1.137      }
   1.138      else {
   1.139        // Build a reverse post-order in the CFG _blocks array
   1.140        Block *stack_top = bstack.pop();
   1.141 -      stack_top->_rpo = --_rpo_ctr;
   1.142 +      stack_top->_rpo = --rpo_counter;
   1.143        _blocks.map(stack_top->_rpo, stack_top);
   1.144      }
   1.145    }
   1.146    return pre_order;
   1.147  }
   1.148  
   1.149 -//------------------------------COMPRESS---------------------------------------
   1.150  void Tarjan::COMPRESS()
   1.151  {
   1.152    assert( _ancestor != 0, "" );
   1.153 @@ -303,14 +293,12 @@
   1.154    }
   1.155  }
   1.156  
   1.157 -//------------------------------EVAL-------------------------------------------
   1.158  Tarjan *Tarjan::EVAL() {
   1.159    if( !_ancestor ) return _label;
   1.160    COMPRESS();
   1.161    return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label;
   1.162  }
   1.163  
   1.164 -//------------------------------LINK-------------------------------------------
   1.165  void Tarjan::LINK( Tarjan *w, Tarjan *tarjan0 ) {
   1.166    Tarjan *s = w;
   1.167    while( w->_label->_semi < s->_child->_label->_semi ) {
   1.168 @@ -333,7 +321,6 @@
   1.169    }
   1.170  }
   1.171  
   1.172 -//------------------------------setdepth---------------------------------------
   1.173  void Tarjan::setdepth( uint stack_size ) {
   1.174    Tarjan **top  = NEW_RESOURCE_ARRAY(Tarjan*, stack_size);
   1.175    Tarjan **next = top;
   1.176 @@ -362,8 +349,7 @@
   1.177    } while (last < top);
   1.178  }
   1.179  
   1.180 -//*********************** DOMINATORS ON THE SEA OF NODES***********************
   1.181 -//------------------------------NTarjan----------------------------------------
   1.182 +// Compute dominators on the Sea of Nodes form
   1.183  // A data structure that holds all the information needed to find dominators.
   1.184  struct NTarjan {
   1.185    Node *_control;               // Control node associated with this info
   1.186 @@ -396,7 +382,6 @@
   1.187  #endif
   1.188  };
   1.189  
   1.190 -//------------------------------Dominator--------------------------------------
   1.191  // Compute the dominator tree of the sea of nodes.  This version walks all CFG
   1.192  // nodes (using the is_CFG() call) and places them in a dominator tree.  Thus,
   1.193  // it needs a count of the CFG nodes for the mapping table. This is the
   1.194 @@ -517,7 +502,6 @@
   1.195    }
   1.196  }
   1.197  
   1.198 -//------------------------------DFS--------------------------------------------
   1.199  // Perform DFS search.  Setup 'vertex' as DFS to vertex mapping.  Setup
   1.200  // 'semi' as vertex to DFS mapping.  Set 'parent' to DFS parent.
   1.201  int NTarjan::DFS( NTarjan *ntarjan, VectorSet &visited, PhaseIdealLoop *pil, uint *dfsorder) {
   1.202 @@ -560,7 +544,6 @@
   1.203    return dfsnum;
   1.204  }
   1.205  
   1.206 -//------------------------------COMPRESS---------------------------------------
   1.207  void NTarjan::COMPRESS()
   1.208  {
   1.209    assert( _ancestor != 0, "" );
   1.210 @@ -572,14 +555,12 @@
   1.211    }
   1.212  }
   1.213  
   1.214 -//------------------------------EVAL-------------------------------------------
   1.215  NTarjan *NTarjan::EVAL() {
   1.216    if( !_ancestor ) return _label;
   1.217    COMPRESS();
   1.218    return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label;
   1.219  }
   1.220  
   1.221 -//------------------------------LINK-------------------------------------------
   1.222  void NTarjan::LINK( NTarjan *w, NTarjan *ntarjan0 ) {
   1.223    NTarjan *s = w;
   1.224    while( w->_label->_semi < s->_child->_label->_semi ) {
   1.225 @@ -602,7 +583,6 @@
   1.226    }
   1.227  }
   1.228  
   1.229 -//------------------------------setdepth---------------------------------------
   1.230  void NTarjan::setdepth( uint stack_size, uint *dom_depth ) {
   1.231    NTarjan **top  = NEW_RESOURCE_ARRAY(NTarjan*, stack_size);
   1.232    NTarjan **next = top;
   1.233 @@ -631,7 +611,6 @@
   1.234    } while (last < top);
   1.235  }
   1.236  
   1.237 -//------------------------------dump-------------------------------------------
   1.238  #ifndef PRODUCT
   1.239  void NTarjan::dump(int offset) const {
   1.240    // Dump the data from this node

mercurial