--- a/hotspot/src/share/vm/opto/gcm.cpp Mon Mar 09 13:34:00 2009 -0700
+++ b/hotspot/src/share/vm/opto/gcm.cpp Thu Mar 12 18:16:36 2009 -0700
@@ -57,6 +57,37 @@
}
}
+//----------------------------replace_block_proj_ctrl-------------------------
+// Nodes that have is_block_proj() nodes as their control need to use
+// the appropriate Region for their actual block as their control since
+// the projection will be in a predecessor block.
+void PhaseCFG::replace_block_proj_ctrl( Node *n ) {
+ const Node *in0 = n->in(0);
+ assert(in0 != NULL, "Only control-dependent");
+ const Node *p = in0->is_block_proj();
+ if (p != NULL && p != n) { // Control from a block projection?
+ assert(!n->pinned() || n->is_SafePointScalarObject(), "only SafePointScalarObject pinned node is expected here");
+ // Find trailing Region
+ Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block
+ uint j = 0;
+ if (pb->_num_succs != 1) { // More then 1 successor?
+ // Search for successor
+ uint max = pb->_nodes.size();
+ assert( max > 1, "" );
+ uint start = max - pb->_num_succs;
+ // Find which output path belongs to projection
+ for (j = start; j < max; j++) {
+ if( pb->_nodes[j] == in0 )
+ break;
+ }
+ assert( j < max, "must find" );
+ // Change control to match head of successor basic block
+ j -= start;
+ }
+ n->set_req(0, pb->_succs[j]->head());
+ }
+}
+
//------------------------------schedule_pinned_nodes--------------------------
// Set the basic block for Nodes pinned into blocks
@@ -68,8 +99,10 @@
Node *n = spstack.pop();
if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited
if( n->pinned() && !_bbs.lookup(n->_idx) ) { // Pinned? Nail it down!
+ assert( n->in(0), "pinned Node must have Control" );
+ // Before setting block replace block_proj control edge
+ replace_block_proj_ctrl(n);
Node *input = n->in(0);
- assert( input, "pinned Node must have Control" );
while( !input->is_block_start() )
input = input->in(0);
Block *b = _bbs[input->_idx]; // Basic block of controlling input
@@ -158,34 +191,12 @@
uint i = nstack_top_i;
if (i == 0) {
- // Special control input processing.
- // While I am here, go ahead and look for Nodes which are taking control
- // from a is_block_proj Node. After I inserted RegionNodes to make proper
- // blocks, the control at a is_block_proj more properly comes from the
- // Region being controlled by the block_proj Node.
+ // Fixup some control. Constants without control get attached
+ // to root and nodes that use is_block_proj() nodes should be attached
+ // to the region that starts their block.
const Node *in0 = n->in(0);
if (in0 != NULL) { // Control-dependent?
- const Node *p = in0->is_block_proj();
- if (p != NULL && p != n) { // Control from a block projection?
- // Find trailing Region
- Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block
- uint j = 0;
- if (pb->_num_succs != 1) { // More then 1 successor?
- // Search for successor
- uint max = pb->_nodes.size();
- assert( max > 1, "" );
- uint start = max - pb->_num_succs;
- // Find which output path belongs to projection
- for (j = start; j < max; j++) {
- if( pb->_nodes[j] == in0 )
- break;
- }
- assert( j < max, "must find" );
- // Change control to match head of successor basic block
- j -= start;
- }
- n->set_req(0, pb->_succs[j]->head());
- }
+ replace_block_proj_ctrl(n);
} else { // n->in(0) == NULL
if (n->req() == 1) { // This guy is a constant with NO inputs?
n->set_req(0, _root);
@@ -226,6 +237,8 @@
if (!n->pinned()) {
// Set earliest legal block.
_bbs.map(n->_idx, find_deepest_input(n, _bbs));
+ } else {
+ assert(_bbs[n->_idx] == _bbs[n->in(0)->_idx], "Pinned Node should be at the same block as its control edge");
}
if (nstack.is_empty()) {
@@ -593,7 +606,7 @@
if (pred_block != early) {
// If any predecessor of the Phi matches the load's "early block",
// we do not need a precedence edge between the Phi and 'load'
- // since the load will be forced into a block preceeding the Phi.
+ // since the load will be forced into a block preceding the Phi.
pred_block->set_raise_LCA_mark(load_index);
assert(!LCA_orig->dominates(pred_block) ||
early->dominates(pred_block), "early is high enough");
@@ -1386,7 +1399,7 @@
#ifdef ASSERT
for (uint i = 0; i < _num_blocks; i++ ) {
Block *b = _blocks[i];
- assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requiers meaningful block frequency");
+ assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requires meaningful block frequency");
}
#endif
@@ -1639,7 +1652,7 @@
// successor blocks.
assert(_num_succs == 2, "expecting 2 successors of a null check");
// If either successor has only one predecessor, then the
- // probabiltity estimate can be derived using the
+ // probability estimate can be derived using the
// relative frequency of the successor and this block.
if (_succs[i]->num_preds() == 2) {
return _succs[i]->_freq / _freq;
@@ -1841,7 +1854,7 @@
}
//------------------------------update_succ_freq-------------------------------
-// Update the appropriate frequency associated with block 'b', a succesor of
+// Update the appropriate frequency associated with block 'b', a successor of
// a block in this loop.
void CFGLoop::update_succ_freq(Block* b, float freq) {
if (b->_loop == this) {
@@ -1888,7 +1901,8 @@
for (int i = 0; i < _members.length(); i++) {
CFGElement* s = _members.at(i);
float block_freq = s->_freq * loop_freq;
- if (block_freq < MIN_BLOCK_FREQUENCY) block_freq = MIN_BLOCK_FREQUENCY;
+ if (g_isnan(block_freq) || block_freq < MIN_BLOCK_FREQUENCY)
+ block_freq = MIN_BLOCK_FREQUENCY;
s->_freq = block_freq;
}
CFGLoop* ch = _child;