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