1.1 --- a/src/share/vm/opto/gcm.cpp Mon Mar 09 13:34:00 2009 -0700 1.2 +++ b/src/share/vm/opto/gcm.cpp Thu Mar 12 18:16:36 2009 -0700 1.3 @@ -57,6 +57,37 @@ 1.4 } 1.5 } 1.6 1.7 +//----------------------------replace_block_proj_ctrl------------------------- 1.8 +// Nodes that have is_block_proj() nodes as their control need to use 1.9 +// the appropriate Region for their actual block as their control since 1.10 +// the projection will be in a predecessor block. 1.11 +void PhaseCFG::replace_block_proj_ctrl( Node *n ) { 1.12 + const Node *in0 = n->in(0); 1.13 + assert(in0 != NULL, "Only control-dependent"); 1.14 + const Node *p = in0->is_block_proj(); 1.15 + if (p != NULL && p != n) { // Control from a block projection? 1.16 + assert(!n->pinned() || n->is_SafePointScalarObject(), "only SafePointScalarObject pinned node is expected here"); 1.17 + // Find trailing Region 1.18 + Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block 1.19 + uint j = 0; 1.20 + if (pb->_num_succs != 1) { // More then 1 successor? 1.21 + // Search for successor 1.22 + uint max = pb->_nodes.size(); 1.23 + assert( max > 1, "" ); 1.24 + uint start = max - pb->_num_succs; 1.25 + // Find which output path belongs to projection 1.26 + for (j = start; j < max; j++) { 1.27 + if( pb->_nodes[j] == in0 ) 1.28 + break; 1.29 + } 1.30 + assert( j < max, "must find" ); 1.31 + // Change control to match head of successor basic block 1.32 + j -= start; 1.33 + } 1.34 + n->set_req(0, pb->_succs[j]->head()); 1.35 + } 1.36 +} 1.37 + 1.38 1.39 //------------------------------schedule_pinned_nodes-------------------------- 1.40 // Set the basic block for Nodes pinned into blocks 1.41 @@ -68,8 +99,10 @@ 1.42 Node *n = spstack.pop(); 1.43 if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited 1.44 if( n->pinned() && !_bbs.lookup(n->_idx) ) { // Pinned? Nail it down! 1.45 + assert( n->in(0), "pinned Node must have Control" ); 1.46 + // Before setting block replace block_proj control edge 1.47 + replace_block_proj_ctrl(n); 1.48 Node *input = n->in(0); 1.49 - assert( input, "pinned Node must have Control" ); 1.50 while( !input->is_block_start() ) 1.51 input = input->in(0); 1.52 Block *b = _bbs[input->_idx]; // Basic block of controlling input 1.53 @@ -158,34 +191,12 @@ 1.54 uint i = nstack_top_i; 1.55 1.56 if (i == 0) { 1.57 - // Special control input processing. 1.58 - // While I am here, go ahead and look for Nodes which are taking control 1.59 - // from a is_block_proj Node. After I inserted RegionNodes to make proper 1.60 - // blocks, the control at a is_block_proj more properly comes from the 1.61 - // Region being controlled by the block_proj Node. 1.62 + // Fixup some control. Constants without control get attached 1.63 + // to root and nodes that use is_block_proj() nodes should be attached 1.64 + // to the region that starts their block. 1.65 const Node *in0 = n->in(0); 1.66 if (in0 != NULL) { // Control-dependent? 1.67 - const Node *p = in0->is_block_proj(); 1.68 - if (p != NULL && p != n) { // Control from a block projection? 1.69 - // Find trailing Region 1.70 - Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block 1.71 - uint j = 0; 1.72 - if (pb->_num_succs != 1) { // More then 1 successor? 1.73 - // Search for successor 1.74 - uint max = pb->_nodes.size(); 1.75 - assert( max > 1, "" ); 1.76 - uint start = max - pb->_num_succs; 1.77 - // Find which output path belongs to projection 1.78 - for (j = start; j < max; j++) { 1.79 - if( pb->_nodes[j] == in0 ) 1.80 - break; 1.81 - } 1.82 - assert( j < max, "must find" ); 1.83 - // Change control to match head of successor basic block 1.84 - j -= start; 1.85 - } 1.86 - n->set_req(0, pb->_succs[j]->head()); 1.87 - } 1.88 + replace_block_proj_ctrl(n); 1.89 } else { // n->in(0) == NULL 1.90 if (n->req() == 1) { // This guy is a constant with NO inputs? 1.91 n->set_req(0, _root); 1.92 @@ -226,6 +237,8 @@ 1.93 if (!n->pinned()) { 1.94 // Set earliest legal block. 1.95 _bbs.map(n->_idx, find_deepest_input(n, _bbs)); 1.96 + } else { 1.97 + assert(_bbs[n->_idx] == _bbs[n->in(0)->_idx], "Pinned Node should be at the same block as its control edge"); 1.98 } 1.99 1.100 if (nstack.is_empty()) { 1.101 @@ -593,7 +606,7 @@ 1.102 if (pred_block != early) { 1.103 // If any predecessor of the Phi matches the load's "early block", 1.104 // we do not need a precedence edge between the Phi and 'load' 1.105 - // since the load will be forced into a block preceeding the Phi. 1.106 + // since the load will be forced into a block preceding the Phi. 1.107 pred_block->set_raise_LCA_mark(load_index); 1.108 assert(!LCA_orig->dominates(pred_block) || 1.109 early->dominates(pred_block), "early is high enough"); 1.110 @@ -1386,7 +1399,7 @@ 1.111 #ifdef ASSERT 1.112 for (uint i = 0; i < _num_blocks; i++ ) { 1.113 Block *b = _blocks[i]; 1.114 - assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requiers meaningful block frequency"); 1.115 + assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requires meaningful block frequency"); 1.116 } 1.117 #endif 1.118 1.119 @@ -1639,7 +1652,7 @@ 1.120 // successor blocks. 1.121 assert(_num_succs == 2, "expecting 2 successors of a null check"); 1.122 // If either successor has only one predecessor, then the 1.123 - // probabiltity estimate can be derived using the 1.124 + // probability estimate can be derived using the 1.125 // relative frequency of the successor and this block. 1.126 if (_succs[i]->num_preds() == 2) { 1.127 return _succs[i]->_freq / _freq; 1.128 @@ -1841,7 +1854,7 @@ 1.129 } 1.130 1.131 //------------------------------update_succ_freq------------------------------- 1.132 -// Update the appropriate frequency associated with block 'b', a succesor of 1.133 +// Update the appropriate frequency associated with block 'b', a successor of 1.134 // a block in this loop. 1.135 void CFGLoop::update_succ_freq(Block* b, float freq) { 1.136 if (b->_loop == this) { 1.137 @@ -1888,7 +1901,8 @@ 1.138 for (int i = 0; i < _members.length(); i++) { 1.139 CFGElement* s = _members.at(i); 1.140 float block_freq = s->_freq * loop_freq; 1.141 - if (block_freq < MIN_BLOCK_FREQUENCY) block_freq = MIN_BLOCK_FREQUENCY; 1.142 + if (g_isnan(block_freq) || block_freq < MIN_BLOCK_FREQUENCY) 1.143 + block_freq = MIN_BLOCK_FREQUENCY; 1.144 s->_freq = block_freq; 1.145 } 1.146 CFGLoop* ch = _child;