domgraph.cpp revision 3718:b9a9ed0f8eeb
1100894Srwatson/*
2100894Srwatson * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3100894Srwatson * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4100894Srwatson *
5100894Srwatson * This code is free software; you can redistribute it and/or modify it
6100894Srwatson * under the terms of the GNU General Public License version 2 only, as
7100894Srwatson * published by the Free Software Foundation.
8100894Srwatson *
9100894Srwatson * This code is distributed in the hope that it will be useful, but WITHOUT
10100894Srwatson * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11100894Srwatson * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12100894Srwatson * version 2 for more details (a copy is included in the LICENSE file that
13100894Srwatson * accompanied this code).
14100894Srwatson *
15100894Srwatson * You should have received a copy of the GNU General Public License version
16100894Srwatson * 2 along with this work; if not, write to the Free Software Foundation,
17100894Srwatson * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18100894Srwatson *
19100894Srwatson * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20100894Srwatson * or visit www.oracle.com if you need additional information or have any
21100894Srwatson * questions.
22100894Srwatson *
23100894Srwatson */
24100894Srwatson
25100894Srwatson#include "precompiled.hpp"
26100894Srwatson#include "libadt/vectset.hpp"
27100894Srwatson#include "memory/allocation.hpp"
28100894Srwatson#include "opto/block.hpp"
29100894Srwatson#include "opto/machnode.hpp"
30100894Srwatson#include "opto/phaseX.hpp"
31100894Srwatson#include "opto/rootnode.hpp"
32100894Srwatson
33100894Srwatson// Portions of code courtesy of Clifford Click
34100894Srwatson
35100894Srwatson// Optimization - Graph Style
36100894Srwatson
37100894Srwatson//------------------------------Tarjan-----------------------------------------
38100894Srwatson// A data structure that holds all the information needed to find dominators.
39100894Srwatsonstruct Tarjan {
40100894Srwatson  Block *_block;                // Basic block for this info
41100894Srwatson
42100894Srwatson  uint _semi;                   // Semi-dominators
43100894Srwatson  uint _size;                   // Used for faster LINK and EVAL
44100894Srwatson  Tarjan *_parent;              // Parent in DFS
45100894Srwatson  Tarjan *_label;               // Used for LINK and EVAL
46100894Srwatson  Tarjan *_ancestor;            // Used for LINK and EVAL
47100894Srwatson  Tarjan *_child;               // Used for faster LINK and EVAL
48100894Srwatson  Tarjan *_dom;                 // Parent in dominator tree (immediate dom)
49104300Sphk  Tarjan *_bucket;              // Set of vertices with given semidominator
50101173Srwatson
51100894Srwatson  Tarjan *_dom_child;           // Child in dominator tree
52100979Srwatson  Tarjan *_dom_next;            // Next in dominator tree
53100979Srwatson
54100979Srwatson  // Fast union-find work
55102949Sbde  void COMPRESS();
56100979Srwatson  Tarjan *EVAL(void);
57100979Srwatson  void LINK( Tarjan *w, Tarjan *tarjan0 );
58101712Srwatson
59100979Srwatson  void setdepth( uint size );
60100979Srwatson
61100894Srwatson};
62100894Srwatson
63100979Srwatson//------------------------------Dominator--------------------------------------
64100979Srwatson// Compute the dominator tree of the CFG.  The CFG must already have been
65100979Srwatson// constructed.  This is the Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
66100979Srwatsonvoid PhaseCFG::Dominators( ) {
67100979Srwatson  // Pre-grow the blocks array, prior to the ResourceMark kicking in
68100979Srwatson  _blocks.map(_num_blocks,0);
69100979Srwatson
70100979Srwatson  ResourceMark rm;
71100894Srwatson  // Setup mappings from my Graph to Tarjan's stuff and back
72100979Srwatson  // Note: Tarjan uses 1-based arrays
73100979Srwatson  Tarjan *tarjan = NEW_RESOURCE_ARRAY(Tarjan,_num_blocks+1);
74100979Srwatson
75100979Srwatson  // Tarjan's algorithm, almost verbatim:
76100979Srwatson  // Step 1:
77100979Srwatson  _rpo_ctr = _num_blocks;
78100979Srwatson  uint dfsnum = DFS( tarjan );
79100979Srwatson  if( dfsnum-1 != _num_blocks ) {// Check for unreachable loops!
80100979Srwatson    // If the returned dfsnum does not match the number of blocks, then we
81100979Srwatson    // must have some unreachable loops.  These can be made at any time by
82100979Srwatson    // IterGVN.  They are cleaned up by CCP or the loop opts, but the last
83100979Srwatson    // IterGVN can always make more that are not cleaned up.  Highly unlikely
84100979Srwatson    // except in ZKM.jar, where endless irreducible loops cause the loop opts
85100979Srwatson    // to not get run.
86100979Srwatson    //
87100979Srwatson    // Having found unreachable loops, we have made a bad RPO _block layout.
88100979Srwatson    // We can re-run the above DFS pass with the correct number of blocks,
89100979Srwatson    // and hack the Tarjan algorithm below to be robust in the presence of
90101712Srwatson    // such dead loops (as was done for the NTarjan code farther below).
91101712Srwatson    // Since this situation is so unlikely, instead I've decided to bail out.
92101712Srwatson    // CNC 7/24/2001
93101712Srwatson    C->record_method_not_compilable("unreachable loop");
94101712Srwatson    return;
95101712Srwatson  }
96101712Srwatson  _blocks._cnt = _num_blocks;
97100979Srwatson
98100979Srwatson  // Tarjan is using 1-based arrays, so these are some initialize flags
99100979Srwatson  tarjan[0]._size = tarjan[0]._semi = 0;
100100979Srwatson  tarjan[0]._label = &tarjan[0];
101100979Srwatson
102100979Srwatson  uint i;
103100979Srwatson  for( i=_num_blocks; i>=2; i-- ) { // For all vertices in DFS order
104100979Srwatson    Tarjan *w = &tarjan[i];     // Get vertex from DFS
105100979Srwatson
106100979Srwatson    // Step 2:
107100979Srwatson    Node *whead = w->_block->head();
108100979Srwatson    for( uint j=1; j < whead->req(); j++ ) {
109100979Srwatson      Block *b = _bbs[whead->in(j)->_idx];
110100979Srwatson      Tarjan *vx = &tarjan[b->_pre_order];
111100979Srwatson      Tarjan *u = vx->EVAL();
112100979Srwatson      if( u->_semi < w->_semi )
113100979Srwatson        w->_semi = u->_semi;
114100979Srwatson    }
115100979Srwatson
116100979Srwatson    // w is added to a bucket here, and only here.
117100979Srwatson    // Thus w is in at most one bucket and the sum of all bucket sizes is O(n).
118100979Srwatson    // Thus bucket can be a linked list.
119100979Srwatson    // Thus we do not need a small integer name for each Block.
120100979Srwatson    w->_bucket = tarjan[w->_semi]._bucket;
121100979Srwatson    tarjan[w->_semi]._bucket = w;
122100979Srwatson
123100979Srwatson    w->_parent->LINK( w, &tarjan[0] );
124103513Srwatson
125103513Srwatson    // Step 3:
126103513Srwatson    for( Tarjan *vx = w->_parent->_bucket; vx; vx = vx->_bucket ) {
127104236Srwatson      Tarjan *u = vx->EVAL();
128103513Srwatson      vx->_dom = (u->_semi < vx->_semi) ? u : w->_parent;
129100979Srwatson    }
130100979Srwatson  }
131100979Srwatson
132100979Srwatson  // Step 4:
133100979Srwatson  for( i=2; i <= _num_blocks; i++ ) {
134100979Srwatson    Tarjan *w = &tarjan[i];
135100979Srwatson    if( w->_dom != &tarjan[w->_semi] )
136100979Srwatson      w->_dom = w->_dom->_dom;
137100979Srwatson    w->_dom_next = w->_dom_child = NULL;  // Initialize for building tree later
138100979Srwatson  }
139103514Srwatson  // No immediate dominator for the root
140103514Srwatson  Tarjan *w = &tarjan[_broot->_pre_order];
141103514Srwatson  w->_dom = NULL;
142104236Srwatson  w->_dom_next = w->_dom_child = NULL;  // Initialize for building tree later
143103514Srwatson
144100979Srwatson  // Convert the dominator tree array into my kind of graph
145100979Srwatson  for( i=1; i<=_num_blocks;i++){// For all Tarjan vertices
146100979Srwatson    Tarjan *t = &tarjan[i];     // Handy access
147100979Srwatson    Tarjan *tdom = t->_dom;     // Handy access to immediate dominator
148100979Srwatson    if( tdom )  {               // Root has no immediate dominator
149100979Srwatson      t->_block->_idom = tdom->_block; // Set immediate dominator
150100979Srwatson      t->_dom_next = tdom->_dom_child; // Make me a sibling of parent's child
151100979Srwatson      tdom->_dom_child = t;     // Make me a child of my parent
152100979Srwatson    } else
153100979Srwatson      t->_block->_idom = NULL;  // Root
154100979Srwatson  }
155100979Srwatson  w->setdepth( _num_blocks+1 ); // Set depth in dominator tree
156100979Srwatson
157100979Srwatson}
158100979Srwatson
159100979Srwatson//----------------------------Block_Stack--------------------------------------
160103136Srwatsonclass Block_Stack {
161103136Srwatson  private:
162103136Srwatson    struct Block_Descr {
163103136Srwatson      Block  *block;     // Block
164103136Srwatson      int    index;      // Index of block's successor pushed on stack
165101892Srwatson      int    freq_idx;   // Index of block's most frequent successor
166100979Srwatson    };
167100979Srwatson    Block_Descr *_stack_top;
168100979Srwatson    Block_Descr *_stack_max;
169100979Srwatson    Block_Descr *_stack;
170101988Srwatson    Tarjan *_tarjan;
171104268Srwatson    uint most_frequent_successor( Block *b );
172104268Srwatson  public:
173104268Srwatson    Block_Stack(Tarjan *tarjan, int size) : _tarjan(tarjan) {
174104268Srwatson      _stack = NEW_RESOURCE_ARRAY(Block_Descr, size);
175104268Srwatson      _stack_max = _stack + size;
176104268Srwatson      _stack_top = _stack - 1; // stack is empty
177104268Srwatson    }
178104268Srwatson    void push(uint pre_order, Block *b) {
179104268Srwatson      Tarjan *t = &_tarjan[pre_order]; // Fast local access
180104268Srwatson      b->_pre_order = pre_order;    // Flag as visited
181100979Srwatson      t->_block = b;                // Save actual block
182100979Srwatson      t->_semi = pre_order;         // Block to DFS map
183100979Srwatson      t->_label = t;                // DFS to vertex map
184100979Srwatson      t->_ancestor = NULL;          // Fast LINK & EVAL setup
185100979Srwatson      t->_child = &_tarjan[0];      // Sentenial
186100979Srwatson      t->_size = 1;
187100979Srwatson      t->_bucket = NULL;
188100979Srwatson      if (pre_order == 1)
189100979Srwatson        t->_parent = NULL;          // first block doesn't have parent
190100979Srwatson      else {
191100979Srwatson        // Save parent (current top block on stack) in DFS
192100979Srwatson        t->_parent = &_tarjan[_stack_top->block->_pre_order];
193100979Srwatson      }
194100979Srwatson      // Now put this block on stack
195100979Srwatson      ++_stack_top;
196100979Srwatson      assert(_stack_top < _stack_max, ""); // assert if stack have to grow
197100979Srwatson      _stack_top->block  = b;
198100979Srwatson      _stack_top->index  = -1;
199100979Srwatson      // Find the index into b->succs[] array of the most frequent successor.
200100979Srwatson      _stack_top->freq_idx = most_frequent_successor(b); // freq_idx >= 0
201100979Srwatson    }
202100979Srwatson    Block* pop() { Block* b = _stack_top->block; _stack_top--; return b; }
203100979Srwatson    bool is_nonempty() { return (_stack_top >= _stack); }
204100979Srwatson    bool last_successor() { return (_stack_top->index == _stack_top->freq_idx); }
205100979Srwatson    Block* next_successor()  {
206101988Srwatson      int i = _stack_top->index;
207100979Srwatson      i++;
208100979Srwatson      if (i == _stack_top->freq_idx) i++;
209100979Srwatson      if (i >= (int)(_stack_top->block->_num_succs)) {
210100979Srwatson        i = _stack_top->freq_idx;   // process most frequent successor last
211100979Srwatson      }
212100979Srwatson      _stack_top->index = i;
213100979Srwatson      return _stack_top->block->_succs[ i ];
214100979Srwatson    }
215100979Srwatson};
216100979Srwatson
217100979Srwatson//-------------------------most_frequent_successor-----------------------------
218100979Srwatson// Find the index into the b->succs[] array of the most frequent successor.
219100979Srwatsonuint Block_Stack::most_frequent_successor( Block *b ) {
220100979Srwatson  uint freq_idx = 0;
221100979Srwatson  int eidx = b->end_idx();
222100979Srwatson  Node *n = b->_nodes[eidx];
223100979Srwatson  int op = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : n->Opcode();
224100979Srwatson  switch( op ) {
225100979Srwatson  case Op_CountedLoopEnd:
226100979Srwatson  case Op_If: {               // Split frequency amongst children
227100979Srwatson    float prob = n->as_MachIf()->_prob;
228100979Srwatson    // Is succ[0] the TRUE branch or the FALSE branch?
229100979Srwatson    if( b->_nodes[eidx+1]->Opcode() == Op_IfFalse )
230100979Srwatson      prob = 1.0f - prob;
231100979Srwatson    freq_idx = prob < PROB_FAIR;      // freq=1 for succ[0] < 0.5 prob
232100979Srwatson    break;
233100979Srwatson  }
234100979Srwatson  case Op_Catch:                // Split frequency amongst children
235100979Srwatson    for( freq_idx = 0; freq_idx < b->_num_succs; freq_idx++ )
236100979Srwatson      if( b->_nodes[eidx+1+freq_idx]->as_CatchProj()->_con == CatchProjNode::fall_through_index )
237100979Srwatson        break;
238100979Srwatson    // Handle case of no fall-thru (e.g., check-cast MUST throw an exception)
239100979Srwatson    if( freq_idx == b->_num_succs ) freq_idx = 0;
240100979Srwatson    break;
241100979Srwatson    // Currently there is no support for finding out the most
242100979Srwatson    // frequent successor for jumps, so lets just make it the first one
243100979Srwatson  case Op_Jump:
244100979Srwatson  case Op_Root:
245100979Srwatson  case Op_Goto:
246100979Srwatson  case Op_NeverBranch:
247100979Srwatson    freq_idx = 0;               // fall thru
248100979Srwatson    break;
249100979Srwatson  case Op_TailCall:
250100979Srwatson  case Op_TailJump:
251100979Srwatson  case Op_Return:
252100979Srwatson  case Op_Halt:
253100979Srwatson  case Op_Rethrow:
254100979Srwatson    break;
255100979Srwatson  default:
256100979Srwatson    ShouldNotReachHere();
257100979Srwatson  }
258100979Srwatson  return freq_idx;
259100979Srwatson}
260100979Srwatson
261100979Srwatson//------------------------------DFS--------------------------------------------
262100979Srwatson// Perform DFS search.  Setup 'vertex' as DFS to vertex mapping.  Setup
263100979Srwatson// 'semi' as vertex to DFS mapping.  Set 'parent' to DFS parent.
264100979Srwatsonuint PhaseCFG::DFS( Tarjan *tarjan ) {
265100979Srwatson  Block *b = _broot;
266100979Srwatson  uint pre_order = 1;
267100979Srwatson  // Allocate stack of size _num_blocks+1 to avoid frequent realloc
268100979Srwatson  Block_Stack bstack(tarjan, _num_blocks+1);
269100979Srwatson
270100979Srwatson  // Push on stack the state for the first block
271100979Srwatson  bstack.push(pre_order, b);
272100979Srwatson  ++pre_order;
273100979Srwatson
274100979Srwatson  while (bstack.is_nonempty()) {
275100979Srwatson    if (!bstack.last_successor()) {
276100979Srwatson      // Walk over all successors in pre-order (DFS).
277100979Srwatson      Block *s = bstack.next_successor();
278100979Srwatson      if (s->_pre_order == 0) { // Check for no-pre-order, not-visited
279100979Srwatson        // Push on stack the state of successor
280100979Srwatson        bstack.push(pre_order, s);
281100979Srwatson        ++pre_order;
282100979Srwatson      }
283100979Srwatson    }
284100979Srwatson    else {
285100979Srwatson      // Build a reverse post-order in the CFG _blocks array
286100979Srwatson      Block *stack_top = bstack.pop();
287100979Srwatson      stack_top->_rpo = --_rpo_ctr;
288100979Srwatson      _blocks.map(stack_top->_rpo, stack_top);
289100979Srwatson    }
290100979Srwatson  }
291100979Srwatson  return pre_order;
292100979Srwatson}
293100979Srwatson
294100979Srwatson//------------------------------COMPRESS---------------------------------------
295100979Srwatsonvoid Tarjan::COMPRESS()
296100979Srwatson{
297100979Srwatson  assert( _ancestor != 0, "" );
298100979Srwatson  if( _ancestor->_ancestor != 0 ) {
299100979Srwatson    _ancestor->COMPRESS( );
300100979Srwatson    if( _ancestor->_label->_semi < _label->_semi )
301100979Srwatson      _label = _ancestor->_label;
302100979Srwatson    _ancestor = _ancestor->_ancestor;
303100979Srwatson  }
304100979Srwatson}
305100979Srwatson
306100979Srwatson//------------------------------EVAL-------------------------------------------
307100979SrwatsonTarjan *Tarjan::EVAL() {
308100979Srwatson  if( !_ancestor ) return _label;
309100979Srwatson  COMPRESS();
310100979Srwatson  return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label;
311100979Srwatson}
312100979Srwatson
313100979Srwatson//------------------------------LINK-------------------------------------------
314100979Srwatsonvoid Tarjan::LINK( Tarjan *w, Tarjan *tarjan0 ) {
315100979Srwatson  Tarjan *s = w;
316100979Srwatson  while( w->_label->_semi < s->_child->_label->_semi ) {
317100979Srwatson    if( s->_size + s->_child->_child->_size >= (s->_child->_size << 1) ) {
318100979Srwatson      s->_child->_ancestor = s;
319100979Srwatson      s->_child = s->_child->_child;
320100979Srwatson    } else {
321100979Srwatson      s->_child->_size = s->_size;
322100979Srwatson      s = s->_ancestor = s->_child;
323100979Srwatson    }
324100979Srwatson  }
325100979Srwatson  s->_label = w->_label;
326100979Srwatson  _size += w->_size;
327100979Srwatson  if( _size < (w->_size << 1) ) {
328100979Srwatson    Tarjan *tmp = s; s = _child; _child = tmp;
329100979Srwatson  }
330100979Srwatson  while( s != tarjan0 ) {
331100979Srwatson    s->_ancestor = this;
332100979Srwatson    s = s->_child;
333100894Srwatson  }
334100979Srwatson}
335100979Srwatson
336100979Srwatson//------------------------------setdepth---------------------------------------
337100979Srwatsonvoid Tarjan::setdepth( uint stack_size ) {
338100979Srwatson  Tarjan **top  = NEW_RESOURCE_ARRAY(Tarjan*, stack_size);
339100979Srwatson  Tarjan **next = top;
340100979Srwatson  Tarjan **last;
341100979Srwatson  uint depth = 0;
342100979Srwatson  *top = this;
343100979Srwatson  ++top;
344100979Srwatson  do {
345100979Srwatson    // next level
346100979Srwatson    ++depth;
347100979Srwatson    last = top;
348100979Srwatson    do {
349100979Srwatson      // Set current depth for all tarjans on this level
350100979Srwatson      Tarjan *t = *next;     // next tarjan from stack
351100979Srwatson      ++next;
352100979Srwatson      do {
353100979Srwatson        t->_block->_dom_depth = depth; // Set depth in dominator tree
354100979Srwatson        Tarjan *dom_child = t->_dom_child;
355100979Srwatson        t = t->_dom_next;    // next tarjan
356100979Srwatson        if (dom_child != NULL) {
357100979Srwatson          *top = dom_child;  // save child on stack
358100979Srwatson          ++top;
359100979Srwatson        }
360100979Srwatson      } while (t != NULL);
361100979Srwatson    } while (next < last);
362100979Srwatson  } while (last < top);
363100979Srwatson}
364100979Srwatson
365100979Srwatson//*********************** DOMINATORS ON THE SEA OF NODES***********************
366100979Srwatson//------------------------------NTarjan----------------------------------------
367100979Srwatson// A data structure that holds all the information needed to find dominators.
368100979Srwatsonstruct NTarjan {
369100979Srwatson  Node *_control;               // Control node associated with this info
370100979Srwatson
371100979Srwatson  uint _semi;                   // Semi-dominators
372100979Srwatson  uint _size;                   // Used for faster LINK and EVAL
373100979Srwatson  NTarjan *_parent;             // Parent in DFS
374100979Srwatson  NTarjan *_label;              // Used for LINK and EVAL
375103570Srwatson  NTarjan *_ancestor;           // Used for LINK and EVAL
376103570Srwatson  NTarjan *_child;              // Used for faster LINK and EVAL
377100979Srwatson  NTarjan *_dom;                // Parent in dominator tree (immediate dom)
378100979Srwatson  NTarjan *_bucket;             // Set of vertices with given semidominator
379100979Srwatson
380100979Srwatson  NTarjan *_dom_child;          // Child in dominator tree
381100979Srwatson  NTarjan *_dom_next;           // Next in dominator tree
382100979Srwatson
383100979Srwatson  // Perform DFS search.
384100979Srwatson  // Setup 'vertex' as DFS to vertex mapping.
385100979Srwatson  // Setup 'semi' as vertex to DFS mapping.
386100979Srwatson  // Set 'parent' to DFS parent.
387100979Srwatson  static int DFS( NTarjan *ntarjan, VectorSet &visited, PhaseIdealLoop *pil, uint *dfsorder );
388100979Srwatson  void setdepth( uint size, uint *dom_depth );
389100979Srwatson
390100979Srwatson  // Fast union-find work
391100979Srwatson  void COMPRESS();
392100979Srwatson  NTarjan *EVAL(void);
393102123Srwatson  void LINK( NTarjan *w, NTarjan *ntarjan0 );
394102123Srwatson#ifndef PRODUCT
395102123Srwatson  void dump(int offset) const;
396102123Srwatson#endif
397104514Srwatson};
398104514Srwatson
399100979Srwatson//------------------------------Dominator--------------------------------------
400100979Srwatson// Compute the dominator tree of the sea of nodes.  This version walks all CFG
401104514Srwatson// nodes (using the is_CFG() call) and places them in a dominator tree.  Thus,
402104514Srwatson// it needs a count of the CFG nodes for the mapping table. This is the
403100979Srwatson// Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
404100979Srwatsonvoid PhaseIdealLoop::Dominators() {
405104514Srwatson  ResourceMark rm;
406104514Srwatson  // Setup mappings from my Graph to Tarjan's stuff and back
407100979Srwatson  // Note: Tarjan uses 1-based arrays
408100979Srwatson  NTarjan *ntarjan = NEW_RESOURCE_ARRAY(NTarjan,C->unique()+1);
409104514Srwatson  // Initialize _control field for fast reference
410104514Srwatson  int i;
411100979Srwatson  for( i= C->unique()-1; i>=0; i-- )
412100979Srwatson    ntarjan[i]._control = NULL;
413104514Srwatson
414104514Srwatson  // Store the DFS order for the main loop
415100979Srwatson  uint *dfsorder = NEW_RESOURCE_ARRAY(uint,C->unique()+1);
416100979Srwatson  memset(dfsorder, max_uint, (C->unique()+1) * sizeof(uint));
417104514Srwatson
418104514Srwatson  // Tarjan's algorithm, almost verbatim:
419100979Srwatson  // Step 1:
420100979Srwatson  VectorSet visited(Thread::current()->resource_area());
421104514Srwatson  int dfsnum = NTarjan::DFS( ntarjan, visited, this, dfsorder);
422104514Srwatson
423100979Srwatson  // Tarjan is using 1-based arrays, so these are some initialize flags
424100979Srwatson  ntarjan[0]._size = ntarjan[0]._semi = 0;
425104514Srwatson  ntarjan[0]._label = &ntarjan[0];
426104514Srwatson
427100979Srwatson  for( i = dfsnum-1; i>1; i-- ) {        // For all nodes in reverse DFS order
428100979Srwatson    NTarjan *w = &ntarjan[i];            // Get Node from DFS
429104514Srwatson    assert(w->_control != NULL,"bad DFS walk");
430104514Srwatson
431100979Srwatson    // Step 2:
432100979Srwatson    Node *whead = w->_control;
433104514Srwatson    for( uint j=0; j < whead->req(); j++ ) { // For each predecessor
434104514Srwatson      if( whead->in(j) == NULL || !whead->in(j)->is_CFG() )
435100979Srwatson        continue;                            // Only process control nodes
436100979Srwatson      uint b = dfsorder[whead->in(j)->_idx];
437104514Srwatson      if(b == max_uint) continue;
438104514Srwatson      NTarjan *vx = &ntarjan[b];
439100979Srwatson      NTarjan *u = vx->EVAL();
440100979Srwatson      if( u->_semi < w->_semi )
441104514Srwatson        w->_semi = u->_semi;
442104514Srwatson    }
443100979Srwatson
444100979Srwatson    // w is added to a bucket here, and only here.
445104514Srwatson    // Thus w is in at most one bucket and the sum of all bucket sizes is O(n).
446104514Srwatson    // Thus bucket can be a linked list.
447100979Srwatson    w->_bucket = ntarjan[w->_semi]._bucket;
448100979Srwatson    ntarjan[w->_semi]._bucket = w;
449104514Srwatson
450104514Srwatson    w->_parent->LINK( w, &ntarjan[0] );
451100979Srwatson
452100979Srwatson    // Step 3:
453104514Srwatson    for( NTarjan *vx = w->_parent->_bucket; vx; vx = vx->_bucket ) {
454104514Srwatson      NTarjan *u = vx->EVAL();
455100979Srwatson      vx->_dom = (u->_semi < vx->_semi) ? u : w->_parent;
456100979Srwatson    }
457104514Srwatson
458104514Srwatson    // Cleanup any unreachable loops now.  Unreachable loops are loops that
459100979Srwatson    // flow into the main graph (and hence into ROOT) but are not reachable
460100979Srwatson    // from above.  Such code is dead, but requires a global pass to detect
461104514Srwatson    // it; this global pass was the 'build_loop_tree' pass run just prior.
462104514Srwatson    if( !_verify_only && whead->is_Region() ) {
463100979Srwatson      for( uint i = 1; i < whead->req(); i++ ) {
464100979Srwatson        if (!has_node(whead->in(i))) {
465104514Srwatson          // Kill dead input path
466104514Srwatson          assert( !visited.test(whead->in(i)->_idx),
467100979Srwatson                  "input with no loop must be dead" );
468100979Srwatson          _igvn.delete_input_of(whead, i);
469104514Srwatson          for (DUIterator_Fast jmax, j = whead->fast_outs(jmax); j < jmax; j++) {
470104514Srwatson            Node* p = whead->fast_out(j);
471100979Srwatson            if( p->is_Phi() ) {
472100979Srwatson              _igvn.delete_input_of(p, i);
473104514Srwatson            }
474104514Srwatson          }
475100979Srwatson          i--;                  // Rerun same iteration
476100979Srwatson        } // End of if dead input path
477104514Srwatson      } // End of for all input paths
478104514Srwatson    } // End if if whead is a Region
479100979Srwatson  } // End of for all Nodes in reverse DFS order
480100979Srwatson
481104514Srwatson  // Step 4:
482104514Srwatson  for( i=2; i < dfsnum; i++ ) { // DFS order
483100979Srwatson    NTarjan *w = &ntarjan[i];
484100979Srwatson    assert(w->_control != NULL,"Bad DFS walk");
485104514Srwatson    if( w->_dom != &ntarjan[w->_semi] )
486104514Srwatson      w->_dom = w->_dom->_dom;
487104514Srwatson    w->_dom_next = w->_dom_child = NULL;  // Initialize for building tree later
488104514Srwatson  }
489104514Srwatson  // No immediate dominator for the root
490104514Srwatson  NTarjan *w = &ntarjan[dfsorder[C->root()->_idx]];
491104514Srwatson  w->_dom = NULL;
492104514Srwatson  w->_parent = NULL;
493104514Srwatson  w->_dom_next = w->_dom_child = NULL;  // Initialize for building tree later
494104514Srwatson
495104514Srwatson  // Convert the dominator tree array into my kind of graph
496104514Srwatson  for( i=1; i<dfsnum; i++ ) {          // For all Tarjan vertices
497104514Srwatson    NTarjan *t = &ntarjan[i];          // Handy access
498104514Srwatson    assert(t->_control != NULL,"Bad DFS walk");
499104514Srwatson    NTarjan *tdom = t->_dom;           // Handy access to immediate dominator
500104514Srwatson    if( tdom )  {                      // Root has no immediate dominator
501100979Srwatson      _idom[t->_control->_idx] = tdom->_control; // Set immediate dominator
502100979Srwatson      t->_dom_next = tdom->_dom_child; // Make me a sibling of parent's child
503100979Srwatson      tdom->_dom_child = t;            // Make me a child of my parent
504100979Srwatson    } else
505100979Srwatson      _idom[C->root()->_idx] = NULL; // Root
506100979Srwatson  }
507100979Srwatson  w->setdepth( C->unique()+1, _dom_depth ); // Set depth in dominator tree
508100979Srwatson  // Pick up the 'top' node as well
509100979Srwatson  _idom     [C->top()->_idx] = C->root();
510100979Srwatson  _dom_depth[C->top()->_idx] = 1;
511100979Srwatson
512100979Srwatson  // Debug Print of Dominator tree
513100979Srwatson  if( PrintDominators ) {
514100979Srwatson#ifndef PRODUCT
515100979Srwatson    w->dump(0);
516100979Srwatson#endif
517100979Srwatson  }
518100979Srwatson}
519100979Srwatson
520100979Srwatson//------------------------------DFS--------------------------------------------
521100979Srwatson// Perform DFS search.  Setup 'vertex' as DFS to vertex mapping.  Setup
522100979Srwatson// 'semi' as vertex to DFS mapping.  Set 'parent' to DFS parent.
523100979Srwatsonint NTarjan::DFS( NTarjan *ntarjan, VectorSet &visited, PhaseIdealLoop *pil, uint *dfsorder) {
524100979Srwatson  // Allocate stack of size C->unique()/8 to avoid frequent realloc
525100979Srwatson  GrowableArray <Node *> dfstack(pil->C->unique() >> 3);
526100979Srwatson  Node *b = pil->C->root();
527100979Srwatson  int dfsnum = 1;
528100979Srwatson  dfsorder[b->_idx] = dfsnum; // Cache parent's dfsnum for a later use
529100979Srwatson  dfstack.push(b);
530100979Srwatson
531100979Srwatson  while (dfstack.is_nonempty()) {
532100979Srwatson    b = dfstack.pop();
533100979Srwatson    if( !visited.test_set(b->_idx) ) { // Test node and flag it as visited
534100979Srwatson      NTarjan *w = &ntarjan[dfsnum];
535100979Srwatson      // Only fully process control nodes
536100979Srwatson      w->_control = b;                 // Save actual node
537100979Srwatson      // Use parent's cached dfsnum to identify "Parent in DFS"
538100979Srwatson      w->_parent = &ntarjan[dfsorder[b->_idx]];
539100979Srwatson      dfsorder[b->_idx] = dfsnum;      // Save DFS order info
540100979Srwatson      w->_semi = dfsnum;               // Node to DFS map
541100979Srwatson      w->_label = w;                   // DFS to vertex map
542100979Srwatson      w->_ancestor = NULL;             // Fast LINK & EVAL setup
543100979Srwatson      w->_child = &ntarjan[0];         // Sentinal
544100979Srwatson      w->_size = 1;
545100979Srwatson      w->_bucket = NULL;
546100979Srwatson
547100979Srwatson      // Need DEF-USE info for this pass
548100979Srwatson      for ( int i = b->outcnt(); i-- > 0; ) { // Put on stack backwards
549100979Srwatson        Node* s = b->raw_out(i);       // Get a use
550100979Srwatson        // CFG nodes only and not dead stuff
551100979Srwatson        if( s->is_CFG() && pil->has_node(s) && !visited.test(s->_idx) ) {
552100979Srwatson          dfsorder[s->_idx] = dfsnum;  // Cache parent's dfsnum for a later use
553100979Srwatson          dfstack.push(s);
554100979Srwatson        }
555100979Srwatson      }
556100979Srwatson      dfsnum++;  // update after parent's dfsnum has been cached.
557100979Srwatson    }
558100979Srwatson  }
559100979Srwatson
560100979Srwatson  return dfsnum;
561100979Srwatson}
562100979Srwatson
563100979Srwatson//------------------------------COMPRESS---------------------------------------
564100979Srwatsonvoid NTarjan::COMPRESS()
565100979Srwatson{
566100979Srwatson  assert( _ancestor != 0, "" );
567100979Srwatson  if( _ancestor->_ancestor != 0 ) {
568100979Srwatson    _ancestor->COMPRESS( );
569100979Srwatson    if( _ancestor->_label->_semi < _label->_semi )
570100979Srwatson      _label = _ancestor->_label;
571100979Srwatson    _ancestor = _ancestor->_ancestor;
572100979Srwatson  }
573100979Srwatson}
574100979Srwatson
575100979Srwatson//------------------------------EVAL-------------------------------------------
576100979SrwatsonNTarjan *NTarjan::EVAL() {
577100979Srwatson  if( !_ancestor ) return _label;
578100979Srwatson  COMPRESS();
579100979Srwatson  return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label;
580100979Srwatson}
581100979Srwatson
582100979Srwatson//------------------------------LINK-------------------------------------------
583100979Srwatsonvoid NTarjan::LINK( NTarjan *w, NTarjan *ntarjan0 ) {
584100979Srwatson  NTarjan *s = w;
585100979Srwatson  while( w->_label->_semi < s->_child->_label->_semi ) {
586100979Srwatson    if( s->_size + s->_child->_child->_size >= (s->_child->_size << 1) ) {
587100979Srwatson      s->_child->_ancestor = s;
588100979Srwatson      s->_child = s->_child->_child;
589100979Srwatson    } else {
590100979Srwatson      s->_child->_size = s->_size;
591100979Srwatson      s = s->_ancestor = s->_child;
592100979Srwatson    }
593100979Srwatson  }
594100979Srwatson  s->_label = w->_label;
595100979Srwatson  _size += w->_size;
596100979Srwatson  if( _size < (w->_size << 1) ) {
597100979Srwatson    NTarjan *tmp = s; s = _child; _child = tmp;
598100979Srwatson  }
599100979Srwatson  while( s != ntarjan0 ) {
600100979Srwatson    s->_ancestor = this;
601100979Srwatson    s = s->_child;
602100979Srwatson  }
603100979Srwatson}
604100979Srwatson
605100979Srwatson//------------------------------setdepth---------------------------------------
606100979Srwatsonvoid NTarjan::setdepth( uint stack_size, uint *dom_depth ) {
607100979Srwatson  NTarjan **top  = NEW_RESOURCE_ARRAY(NTarjan*, stack_size);
608100979Srwatson  NTarjan **next = top;
609100979Srwatson  NTarjan **last;
610100979Srwatson  uint depth = 0;
611100979Srwatson  *top = this;
612100979Srwatson  ++top;
613100979Srwatson  do {
614100979Srwatson    // next level
615100979Srwatson    ++depth;
616100979Srwatson    last = top;
617100979Srwatson    do {
618100979Srwatson      // Set current depth for all tarjans on this level
619100979Srwatson      NTarjan *t = *next;    // next tarjan from stack
620100979Srwatson      ++next;
621100979Srwatson      do {
622100979Srwatson        dom_depth[t->_control->_idx] = depth; // Set depth in dominator tree
623100979Srwatson        NTarjan *dom_child = t->_dom_child;
624100979Srwatson        t = t->_dom_next;    // next tarjan
625100979Srwatson        if (dom_child != NULL) {
626100979Srwatson          *top = dom_child;  // save child on stack
627100979Srwatson          ++top;
628100979Srwatson        }
629100979Srwatson      } while (t != NULL);
630100979Srwatson    } while (next < last);
631100979Srwatson  } while (last < top);
632100979Srwatson}
633100979Srwatson
634100979Srwatson//------------------------------dump-------------------------------------------
635100979Srwatson#ifndef PRODUCT
636100979Srwatsonvoid NTarjan::dump(int offset) const {
637100979Srwatson  // Dump the data from this node
638100979Srwatson  int i;
639100979Srwatson  for(i = offset; i >0; i--)  // Use indenting for tree structure
640100979Srwatson    tty->print("  ");
641100979Srwatson  tty->print("Dominator Node: ");
642100979Srwatson  _control->dump();               // Control node for this dom node
643100979Srwatson  tty->print("\n");
644100979Srwatson  for(i = offset; i >0; i--)      // Use indenting for tree structure
645100979Srwatson    tty->print("  ");
646100979Srwatson  tty->print("semi:%d, size:%d\n",_semi, _size);
647100979Srwatson  for(i = offset; i >0; i--)      // Use indenting for tree structure
648100979Srwatson    tty->print("  ");
649100979Srwatson  tty->print("DFS Parent: ");
650100979Srwatson  if(_parent != NULL)
651100979Srwatson    _parent->_control->dump();    // Parent in DFS
652100979Srwatson  tty->print("\n");
653100979Srwatson  for(i = offset; i >0; i--)      // Use indenting for tree structure
654100979Srwatson    tty->print("  ");
655100979Srwatson  tty->print("Dom Parent: ");
656100979Srwatson  if(_dom != NULL)
657100979Srwatson    _dom->_control->dump();       // Parent in Dominator Tree
658100979Srwatson  tty->print("\n");
659100979Srwatson
660100979Srwatson  // Recurse over remaining tree
661100979Srwatson  if( _dom_child ) _dom_child->dump(offset+2);   // Children in dominator tree
662100979Srwatson  if( _dom_next  ) _dom_next ->dump(offset  );   // Siblings in dominator tree
663100979Srwatson
664100979Srwatson}
665100979Srwatson#endif
666100979Srwatson