comparison src/share/vm/opto/domgraph.cpp @ 14412:e2722a66aba7

Merge
author kvn
date Thu, 05 Sep 2013 11:04:39 -0700
parents adb9a7d94cb5
children 650868c062a9
comparison
equal deleted inserted replaced
14411:bdd155477289 14412:e2722a66aba7
30 #include "opto/phaseX.hpp" 30 #include "opto/phaseX.hpp"
31 #include "opto/rootnode.hpp" 31 #include "opto/rootnode.hpp"
32 32
33 // Portions of code courtesy of Clifford Click 33 // Portions of code courtesy of Clifford Click
34 34
35 // Optimization - Graph Style
36
37 //------------------------------Tarjan-----------------------------------------
38 // A data structure that holds all the information needed to find dominators. 35 // A data structure that holds all the information needed to find dominators.
39 struct Tarjan { 36 struct Tarjan {
40 Block *_block; // Basic block for this info 37 Block *_block; // Basic block for this info
41 38
42 uint _semi; // Semi-dominators 39 uint _semi; // Semi-dominators
58 55
59 void setdepth( uint size ); 56 void setdepth( uint size );
60 57
61 }; 58 };
62 59
63 //------------------------------Dominator--------------------------------------
64 // Compute the dominator tree of the CFG. The CFG must already have been 60 // Compute the dominator tree of the CFG. The CFG must already have been
65 // constructed. This is the Lengauer & Tarjan O(E-alpha(E,V)) algorithm. 61 // constructed. This is the Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
66 void PhaseCFG::Dominators( ) { 62 void PhaseCFG::build_dominator_tree() {
67 // Pre-grow the blocks array, prior to the ResourceMark kicking in 63 // Pre-grow the blocks array, prior to the ResourceMark kicking in
68 _blocks.map(_num_blocks,0); 64 _blocks.map(number_of_blocks(), 0);
69 65
70 ResourceMark rm; 66 ResourceMark rm;
71 // Setup mappings from my Graph to Tarjan's stuff and back 67 // Setup mappings from my Graph to Tarjan's stuff and back
72 // Note: Tarjan uses 1-based arrays 68 // Note: Tarjan uses 1-based arrays
73 Tarjan *tarjan = NEW_RESOURCE_ARRAY(Tarjan,_num_blocks+1); 69 Tarjan* tarjan = NEW_RESOURCE_ARRAY(Tarjan, number_of_blocks() + 1);
74 70
75 // Tarjan's algorithm, almost verbatim: 71 // Tarjan's algorithm, almost verbatim:
76 // Step 1: 72 // Step 1:
77 _rpo_ctr = _num_blocks; 73 uint dfsnum = do_DFS(tarjan, number_of_blocks());
78 uint dfsnum = DFS( tarjan ); 74 if (dfsnum - 1 != number_of_blocks()) { // Check for unreachable loops!
79 if( dfsnum-1 != _num_blocks ) {// Check for unreachable loops!
80 // If the returned dfsnum does not match the number of blocks, then we 75 // If the returned dfsnum does not match the number of blocks, then we
81 // must have some unreachable loops. These can be made at any time by 76 // must have some unreachable loops. These can be made at any time by
82 // IterGVN. They are cleaned up by CCP or the loop opts, but the last 77 // IterGVN. They are cleaned up by CCP or the loop opts, but the last
83 // IterGVN can always make more that are not cleaned up. Highly unlikely 78 // IterGVN can always make more that are not cleaned up. Highly unlikely
84 // except in ZKM.jar, where endless irreducible loops cause the loop opts 79 // except in ZKM.jar, where endless irreducible loops cause the loop opts
91 // Since this situation is so unlikely, instead I've decided to bail out. 86 // Since this situation is so unlikely, instead I've decided to bail out.
92 // CNC 7/24/2001 87 // CNC 7/24/2001
93 C->record_method_not_compilable("unreachable loop"); 88 C->record_method_not_compilable("unreachable loop");
94 return; 89 return;
95 } 90 }
96 _blocks._cnt = _num_blocks; 91 _blocks._cnt = number_of_blocks();
97 92
98 // Tarjan is using 1-based arrays, so these are some initialize flags 93 // Tarjan is using 1-based arrays, so these are some initialize flags
99 tarjan[0]._size = tarjan[0]._semi = 0; 94 tarjan[0]._size = tarjan[0]._semi = 0;
100 tarjan[0]._label = &tarjan[0]; 95 tarjan[0]._label = &tarjan[0];
101 96
102 uint i; 97 for (uint i = number_of_blocks(); i >= 2; i--) { // For all vertices in DFS order
103 for( i=_num_blocks; i>=2; i-- ) { // For all vertices in DFS order
104 Tarjan *w = &tarjan[i]; // Get vertex from DFS 98 Tarjan *w = &tarjan[i]; // Get vertex from DFS
105 99
106 // Step 2: 100 // Step 2:
107 Node *whead = w->_block->head(); 101 Node *whead = w->_block->head();
108 for( uint j=1; j < whead->req(); j++ ) { 102 for (uint j = 1; j < whead->req(); j++) {
109 Block *b = _bbs[whead->in(j)->_idx]; 103 Block* b = get_block_for_node(whead->in(j));
110 Tarjan *vx = &tarjan[b->_pre_order]; 104 Tarjan *vx = &tarjan[b->_pre_order];
111 Tarjan *u = vx->EVAL(); 105 Tarjan *u = vx->EVAL();
112 if( u->_semi < w->_semi ) 106 if( u->_semi < w->_semi )
113 w->_semi = u->_semi; 107 w->_semi = u->_semi;
114 } 108 }
128 vx->_dom = (u->_semi < vx->_semi) ? u : w->_parent; 122 vx->_dom = (u->_semi < vx->_semi) ? u : w->_parent;
129 } 123 }
130 } 124 }
131 125
132 // Step 4: 126 // Step 4:
133 for( i=2; i <= _num_blocks; i++ ) { 127 for (uint i = 2; i <= number_of_blocks(); i++) {
134 Tarjan *w = &tarjan[i]; 128 Tarjan *w = &tarjan[i];
135 if( w->_dom != &tarjan[w->_semi] ) 129 if( w->_dom != &tarjan[w->_semi] )
136 w->_dom = w->_dom->_dom; 130 w->_dom = w->_dom->_dom;
137 w->_dom_next = w->_dom_child = NULL; // Initialize for building tree later 131 w->_dom_next = w->_dom_child = NULL; // Initialize for building tree later
138 } 132 }
139 // No immediate dominator for the root 133 // No immediate dominator for the root
140 Tarjan *w = &tarjan[_broot->_pre_order]; 134 Tarjan *w = &tarjan[get_root_block()->_pre_order];
141 w->_dom = NULL; 135 w->_dom = NULL;
142 w->_dom_next = w->_dom_child = NULL; // Initialize for building tree later 136 w->_dom_next = w->_dom_child = NULL; // Initialize for building tree later
143 137
144 // Convert the dominator tree array into my kind of graph 138 // Convert the dominator tree array into my kind of graph
145 for( i=1; i<=_num_blocks;i++){// For all Tarjan vertices 139 for(uint i = 1; i <= number_of_blocks(); i++){ // For all Tarjan vertices
146 Tarjan *t = &tarjan[i]; // Handy access 140 Tarjan *t = &tarjan[i]; // Handy access
147 Tarjan *tdom = t->_dom; // Handy access to immediate dominator 141 Tarjan *tdom = t->_dom; // Handy access to immediate dominator
148 if( tdom ) { // Root has no immediate dominator 142 if( tdom ) { // Root has no immediate dominator
149 t->_block->_idom = tdom->_block; // Set immediate dominator 143 t->_block->_idom = tdom->_block; // Set immediate dominator
150 t->_dom_next = tdom->_dom_child; // Make me a sibling of parent's child 144 t->_dom_next = tdom->_dom_child; // Make me a sibling of parent's child
151 tdom->_dom_child = t; // Make me a child of my parent 145 tdom->_dom_child = t; // Make me a child of my parent
152 } else 146 } else
153 t->_block->_idom = NULL; // Root 147 t->_block->_idom = NULL; // Root
154 } 148 }
155 w->setdepth( _num_blocks+1 ); // Set depth in dominator tree 149 w->setdepth(number_of_blocks() + 1); // Set depth in dominator tree
156 150
157 } 151 }
158 152
159 //----------------------------Block_Stack--------------------------------------
160 class Block_Stack { 153 class Block_Stack {
161 private: 154 private:
162 struct Block_Descr { 155 struct Block_Descr {
163 Block *block; // Block 156 Block *block; // Block
164 int index; // Index of block's successor pushed on stack 157 int index; // Index of block's successor pushed on stack
212 _stack_top->index = i; 205 _stack_top->index = i;
213 return _stack_top->block->_succs[ i ]; 206 return _stack_top->block->_succs[ i ];
214 } 207 }
215 }; 208 };
216 209
217 //-------------------------most_frequent_successor-----------------------------
218 // Find the index into the b->succs[] array of the most frequent successor. 210 // Find the index into the b->succs[] array of the most frequent successor.
219 uint Block_Stack::most_frequent_successor( Block *b ) { 211 uint Block_Stack::most_frequent_successor( Block *b ) {
220 uint freq_idx = 0; 212 uint freq_idx = 0;
221 int eidx = b->end_idx(); 213 int eidx = b->end_idx();
222 Node *n = b->_nodes[eidx]; 214 Node *n = b->_nodes[eidx];
256 ShouldNotReachHere(); 248 ShouldNotReachHere();
257 } 249 }
258 return freq_idx; 250 return freq_idx;
259 } 251 }
260 252
261 //------------------------------DFS--------------------------------------------
262 // Perform DFS search. Setup 'vertex' as DFS to vertex mapping. Setup 253 // Perform DFS search. Setup 'vertex' as DFS to vertex mapping. Setup
263 // 'semi' as vertex to DFS mapping. Set 'parent' to DFS parent. 254 // 'semi' as vertex to DFS mapping. Set 'parent' to DFS parent.
264 uint PhaseCFG::DFS( Tarjan *tarjan ) { 255 uint PhaseCFG::do_DFS(Tarjan *tarjan, uint rpo_counter) {
265 Block *b = _broot; 256 Block* root_block = get_root_block();
266 uint pre_order = 1; 257 uint pre_order = 1;
267 // Allocate stack of size _num_blocks+1 to avoid frequent realloc 258 // Allocate stack of size number_of_blocks() + 1 to avoid frequent realloc
268 Block_Stack bstack(tarjan, _num_blocks+1); 259 Block_Stack bstack(tarjan, number_of_blocks() + 1);
269 260
270 // Push on stack the state for the first block 261 // Push on stack the state for the first block
271 bstack.push(pre_order, b); 262 bstack.push(pre_order, root_block);
272 ++pre_order; 263 ++pre_order;
273 264
274 while (bstack.is_nonempty()) { 265 while (bstack.is_nonempty()) {
275 if (!bstack.last_successor()) { 266 if (!bstack.last_successor()) {
276 // Walk over all successors in pre-order (DFS). 267 // Walk over all successors in pre-order (DFS).
277 Block *s = bstack.next_successor(); 268 Block* next_block = bstack.next_successor();
278 if (s->_pre_order == 0) { // Check for no-pre-order, not-visited 269 if (next_block->_pre_order == 0) { // Check for no-pre-order, not-visited
279 // Push on stack the state of successor 270 // Push on stack the state of successor
280 bstack.push(pre_order, s); 271 bstack.push(pre_order, next_block);
281 ++pre_order; 272 ++pre_order;
282 } 273 }
283 } 274 }
284 else { 275 else {
285 // Build a reverse post-order in the CFG _blocks array 276 // Build a reverse post-order in the CFG _blocks array
286 Block *stack_top = bstack.pop(); 277 Block *stack_top = bstack.pop();
287 stack_top->_rpo = --_rpo_ctr; 278 stack_top->_rpo = --rpo_counter;
288 _blocks.map(stack_top->_rpo, stack_top); 279 _blocks.map(stack_top->_rpo, stack_top);
289 } 280 }
290 } 281 }
291 return pre_order; 282 return pre_order;
292 } 283 }
293 284
294 //------------------------------COMPRESS---------------------------------------
295 void Tarjan::COMPRESS() 285 void Tarjan::COMPRESS()
296 { 286 {
297 assert( _ancestor != 0, "" ); 287 assert( _ancestor != 0, "" );
298 if( _ancestor->_ancestor != 0 ) { 288 if( _ancestor->_ancestor != 0 ) {
299 _ancestor->COMPRESS( ); 289 _ancestor->COMPRESS( );
301 _label = _ancestor->_label; 291 _label = _ancestor->_label;
302 _ancestor = _ancestor->_ancestor; 292 _ancestor = _ancestor->_ancestor;
303 } 293 }
304 } 294 }
305 295
306 //------------------------------EVAL-------------------------------------------
307 Tarjan *Tarjan::EVAL() { 296 Tarjan *Tarjan::EVAL() {
308 if( !_ancestor ) return _label; 297 if( !_ancestor ) return _label;
309 COMPRESS(); 298 COMPRESS();
310 return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label; 299 return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label;
311 } 300 }
312 301
313 //------------------------------LINK-------------------------------------------
314 void Tarjan::LINK( Tarjan *w, Tarjan *tarjan0 ) { 302 void Tarjan::LINK( Tarjan *w, Tarjan *tarjan0 ) {
315 Tarjan *s = w; 303 Tarjan *s = w;
316 while( w->_label->_semi < s->_child->_label->_semi ) { 304 while( w->_label->_semi < s->_child->_label->_semi ) {
317 if( s->_size + s->_child->_child->_size >= (s->_child->_size << 1) ) { 305 if( s->_size + s->_child->_child->_size >= (s->_child->_size << 1) ) {
318 s->_child->_ancestor = s; 306 s->_child->_ancestor = s;
331 s->_ancestor = this; 319 s->_ancestor = this;
332 s = s->_child; 320 s = s->_child;
333 } 321 }
334 } 322 }
335 323
336 //------------------------------setdepth---------------------------------------
337 void Tarjan::setdepth( uint stack_size ) { 324 void Tarjan::setdepth( uint stack_size ) {
338 Tarjan **top = NEW_RESOURCE_ARRAY(Tarjan*, stack_size); 325 Tarjan **top = NEW_RESOURCE_ARRAY(Tarjan*, stack_size);
339 Tarjan **next = top; 326 Tarjan **next = top;
340 Tarjan **last; 327 Tarjan **last;
341 uint depth = 0; 328 uint depth = 0;
360 } while (t != NULL); 347 } while (t != NULL);
361 } while (next < last); 348 } while (next < last);
362 } while (last < top); 349 } while (last < top);
363 } 350 }
364 351
365 //*********************** DOMINATORS ON THE SEA OF NODES*********************** 352 // Compute dominators on the Sea of Nodes form
366 //------------------------------NTarjan----------------------------------------
367 // A data structure that holds all the information needed to find dominators. 353 // A data structure that holds all the information needed to find dominators.
368 struct NTarjan { 354 struct NTarjan {
369 Node *_control; // Control node associated with this info 355 Node *_control; // Control node associated with this info
370 356
371 uint _semi; // Semi-dominators 357 uint _semi; // Semi-dominators
394 #ifndef PRODUCT 380 #ifndef PRODUCT
395 void dump(int offset) const; 381 void dump(int offset) const;
396 #endif 382 #endif
397 }; 383 };
398 384
399 //------------------------------Dominator--------------------------------------
400 // Compute the dominator tree of the sea of nodes. This version walks all CFG 385 // Compute the dominator tree of the sea of nodes. This version walks all CFG
401 // nodes (using the is_CFG() call) and places them in a dominator tree. Thus, 386 // nodes (using the is_CFG() call) and places them in a dominator tree. Thus,
402 // it needs a count of the CFG nodes for the mapping table. This is the 387 // it needs a count of the CFG nodes for the mapping table. This is the
403 // Lengauer & Tarjan O(E-alpha(E,V)) algorithm. 388 // Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
404 void PhaseIdealLoop::Dominators() { 389 void PhaseIdealLoop::Dominators() {
515 w->dump(0); 500 w->dump(0);
516 #endif 501 #endif
517 } 502 }
518 } 503 }
519 504
520 //------------------------------DFS--------------------------------------------
521 // Perform DFS search. Setup 'vertex' as DFS to vertex mapping. Setup 505 // Perform DFS search. Setup 'vertex' as DFS to vertex mapping. Setup
522 // 'semi' as vertex to DFS mapping. Set 'parent' to DFS parent. 506 // 'semi' as vertex to DFS mapping. Set 'parent' to DFS parent.
523 int NTarjan::DFS( NTarjan *ntarjan, VectorSet &visited, PhaseIdealLoop *pil, uint *dfsorder) { 507 int NTarjan::DFS( NTarjan *ntarjan, VectorSet &visited, PhaseIdealLoop *pil, uint *dfsorder) {
524 // Allocate stack of size C->unique()/8 to avoid frequent realloc 508 // Allocate stack of size C->unique()/8 to avoid frequent realloc
525 GrowableArray <Node *> dfstack(pil->C->unique() >> 3); 509 GrowableArray <Node *> dfstack(pil->C->unique() >> 3);
558 } 542 }
559 543
560 return dfsnum; 544 return dfsnum;
561 } 545 }
562 546
563 //------------------------------COMPRESS---------------------------------------
564 void NTarjan::COMPRESS() 547 void NTarjan::COMPRESS()
565 { 548 {
566 assert( _ancestor != 0, "" ); 549 assert( _ancestor != 0, "" );
567 if( _ancestor->_ancestor != 0 ) { 550 if( _ancestor->_ancestor != 0 ) {
568 _ancestor->COMPRESS( ); 551 _ancestor->COMPRESS( );
570 _label = _ancestor->_label; 553 _label = _ancestor->_label;
571 _ancestor = _ancestor->_ancestor; 554 _ancestor = _ancestor->_ancestor;
572 } 555 }
573 } 556 }
574 557
575 //------------------------------EVAL-------------------------------------------
576 NTarjan *NTarjan::EVAL() { 558 NTarjan *NTarjan::EVAL() {
577 if( !_ancestor ) return _label; 559 if( !_ancestor ) return _label;
578 COMPRESS(); 560 COMPRESS();
579 return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label; 561 return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label;
580 } 562 }
581 563
582 //------------------------------LINK-------------------------------------------
583 void NTarjan::LINK( NTarjan *w, NTarjan *ntarjan0 ) { 564 void NTarjan::LINK( NTarjan *w, NTarjan *ntarjan0 ) {
584 NTarjan *s = w; 565 NTarjan *s = w;
585 while( w->_label->_semi < s->_child->_label->_semi ) { 566 while( w->_label->_semi < s->_child->_label->_semi ) {
586 if( s->_size + s->_child->_child->_size >= (s->_child->_size << 1) ) { 567 if( s->_size + s->_child->_child->_size >= (s->_child->_size << 1) ) {
587 s->_child->_ancestor = s; 568 s->_child->_ancestor = s;
600 s->_ancestor = this; 581 s->_ancestor = this;
601 s = s->_child; 582 s = s->_child;
602 } 583 }
603 } 584 }
604 585
605 //------------------------------setdepth---------------------------------------
606 void NTarjan::setdepth( uint stack_size, uint *dom_depth ) { 586 void NTarjan::setdepth( uint stack_size, uint *dom_depth ) {
607 NTarjan **top = NEW_RESOURCE_ARRAY(NTarjan*, stack_size); 587 NTarjan **top = NEW_RESOURCE_ARRAY(NTarjan*, stack_size);
608 NTarjan **next = top; 588 NTarjan **next = top;
609 NTarjan **last; 589 NTarjan **last;
610 uint depth = 0; 590 uint depth = 0;
629 } while (t != NULL); 609 } while (t != NULL);
630 } while (next < last); 610 } while (next < last);
631 } while (last < top); 611 } while (last < top);
632 } 612 }
633 613
634 //------------------------------dump-------------------------------------------
635 #ifndef PRODUCT 614 #ifndef PRODUCT
636 void NTarjan::dump(int offset) const { 615 void NTarjan::dump(int offset) const {
637 // Dump the data from this node 616 // Dump the data from this node
638 int i; 617 int i;
639 for(i = offset; i >0; i--) // Use indenting for tree structure 618 for(i = offset; i >0; i--) // Use indenting for tree structure