src/share/vm/opto/domgraph.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/domgraph.cpp

Print this page




 380 #ifndef PRODUCT
 381   void dump(int offset) const;
 382 #endif
 383 };
 384 
 385 // Compute the dominator tree of the sea of nodes.  This version walks all CFG
 386 // nodes (using the is_CFG() call) and places them in a dominator tree.  Thus,
 387 // it needs a count of the CFG nodes for the mapping table. This is the
 388 // Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
 389 void PhaseIdealLoop::Dominators() {
 390   ResourceMark rm;
 391   // Setup mappings from my Graph to Tarjan's stuff and back
 392   // Note: Tarjan uses 1-based arrays
 393   NTarjan *ntarjan = NEW_RESOURCE_ARRAY(NTarjan,C->unique()+1);
 394   // Initialize _control field for fast reference
 395   int i;
 396   for( i= C->unique()-1; i>=0; i-- )
 397     ntarjan[i]._control = NULL;
 398 
 399   // Store the DFS order for the main loop

 400   uint *dfsorder = NEW_RESOURCE_ARRAY(uint,C->unique()+1);
 401   memset(dfsorder, max_uint, (C->unique()+1) * sizeof(uint));
 402 
 403   // Tarjan's algorithm, almost verbatim:
 404   // Step 1:
 405   VectorSet visited(Thread::current()->resource_area());
 406   int dfsnum = NTarjan::DFS( ntarjan, visited, this, dfsorder);
 407 
 408   // Tarjan is using 1-based arrays, so these are some initialize flags
 409   ntarjan[0]._size = ntarjan[0]._semi = 0;
 410   ntarjan[0]._label = &ntarjan[0];
 411 
 412   for( i = dfsnum-1; i>1; i-- ) {        // For all nodes in reverse DFS order
 413     NTarjan *w = &ntarjan[i];            // Get Node from DFS
 414     assert(w->_control != NULL,"bad DFS walk");
 415 
 416     // Step 2:
 417     Node *whead = w->_control;
 418     for( uint j=0; j < whead->req(); j++ ) { // For each predecessor
 419       if( whead->in(j) == NULL || !whead->in(j)->is_CFG() )
 420         continue;                            // Only process control nodes
 421       uint b = dfsorder[whead->in(j)->_idx];
 422       if(b == max_uint) continue;
 423       NTarjan *vx = &ntarjan[b];
 424       NTarjan *u = vx->EVAL();
 425       if( u->_semi < w->_semi )
 426         w->_semi = u->_semi;
 427     }
 428 
 429     // w is added to a bucket here, and only here.
 430     // Thus w is in at most one bucket and the sum of all bucket sizes is O(n).
 431     // Thus bucket can be a linked list.
 432     w->_bucket = ntarjan[w->_semi]._bucket;
 433     ntarjan[w->_semi]._bucket = w;
 434 
 435     w->_parent->LINK( w, &ntarjan[0] );
 436 
 437     // Step 3:
 438     for( NTarjan *vx = w->_parent->_bucket; vx; vx = vx->_bucket ) {
 439       NTarjan *u = vx->EVAL();
 440       vx->_dom = (u->_semi < vx->_semi) ? u : w->_parent;
 441     }
 442 




 380 #ifndef PRODUCT
 381   void dump(int offset) const;
 382 #endif
 383 };
 384 
 385 // Compute the dominator tree of the sea of nodes.  This version walks all CFG
 386 // nodes (using the is_CFG() call) and places them in a dominator tree.  Thus,
 387 // it needs a count of the CFG nodes for the mapping table. This is the
 388 // Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
 389 void PhaseIdealLoop::Dominators() {
 390   ResourceMark rm;
 391   // Setup mappings from my Graph to Tarjan's stuff and back
 392   // Note: Tarjan uses 1-based arrays
 393   NTarjan *ntarjan = NEW_RESOURCE_ARRAY(NTarjan,C->unique()+1);
 394   // Initialize _control field for fast reference
 395   int i;
 396   for( i= C->unique()-1; i>=0; i-- )
 397     ntarjan[i]._control = NULL;
 398 
 399   // Store the DFS order for the main loop
 400   const uint fill_value = (uint) -1;
 401   uint *dfsorder = NEW_RESOURCE_ARRAY(uint,C->unique()+1);
 402   memset(dfsorder, fill_value, (C->unique()+1) * sizeof(uint));
 403 
 404   // Tarjan's algorithm, almost verbatim:
 405   // Step 1:
 406   VectorSet visited(Thread::current()->resource_area());
 407   int dfsnum = NTarjan::DFS( ntarjan, visited, this, dfsorder);
 408 
 409   // Tarjan is using 1-based arrays, so these are some initialize flags
 410   ntarjan[0]._size = ntarjan[0]._semi = 0;
 411   ntarjan[0]._label = &ntarjan[0];
 412 
 413   for( i = dfsnum-1; i>1; i-- ) {        // For all nodes in reverse DFS order
 414     NTarjan *w = &ntarjan[i];            // Get Node from DFS
 415     assert(w->_control != NULL,"bad DFS walk");
 416 
 417     // Step 2:
 418     Node *whead = w->_control;
 419     for( uint j=0; j < whead->req(); j++ ) { // For each predecessor
 420       if( whead->in(j) == NULL || !whead->in(j)->is_CFG() )
 421         continue;                            // Only process control nodes
 422       uint b = dfsorder[whead->in(j)->_idx];
 423       if(b == fill_value) continue;
 424       NTarjan *vx = &ntarjan[b];
 425       NTarjan *u = vx->EVAL();
 426       if( u->_semi < w->_semi )
 427         w->_semi = u->_semi;
 428     }
 429 
 430     // w is added to a bucket here, and only here.
 431     // Thus w is in at most one bucket and the sum of all bucket sizes is O(n).
 432     // Thus bucket can be a linked list.
 433     w->_bucket = ntarjan[w->_semi]._bucket;
 434     ntarjan[w->_semi]._bucket = w;
 435 
 436     w->_parent->LINK( w, &ntarjan[0] );
 437 
 438     // Step 3:
 439     for( NTarjan *vx = w->_parent->_bucket; vx; vx = vx->_bucket ) {
 440       NTarjan *u = vx->EVAL();
 441       vx->_dom = (u->_semi < vx->_semi) ? u : w->_parent;
 442     }
 443 


src/share/vm/opto/domgraph.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File