@@ -103,11 +103,14 @@ void PhaseCFG::replace_block_proj_ctrl( Node *n ) {
}
bool PhaseCFG::is_dominator (Node* dom_node, Node* node) {
assert (is_CFG (node) && is_CFG (dom_node), " node and dom_node must be CFG nodes" );
if (dom_node == node) {
return true ;
}
Block* d = get_block_for_node (dom_node);
Block* n = get_block_for_node (node);
Block* d = find_block_for_node (dom_node);
Block* n = find_block_for_node (node);
assert (n != NULL && d != NULL , " blocks must exist" );
if (d == n) {
if (dom_node->is_block_start ()) {
return true ;
@@ -121,21 +124,74 @@ bool PhaseCFG::is_dominator(Node* dom_node, Node* node) {
if (node->is_block_proj ()) {
return true ;
}
assert (is_control_proj_or_safepoint (node), " node must be control projection or safepoint" );
assert (is_control_proj_or_safepoint (dom_node), " dom_node must be control projection or safepoint" );
// Neither 'node' nor 'dom_node' is a block start or block projection.
// Check if 'dom_node' is above 'node' in the control graph.
if (is_dominating_control (dom_node, node)) {
return true ;
}
#ifdef ASSERT
node->dump ();
dom_node->dump ();
// If 'dom_node' does not dominate 'node' then 'node' has to dominate 'dom_node'
if (!is_dominating_control (node, dom_node)) {
node->dump ();
dom_node->dump ();
assert (false , " neither dom_node nor node dominates the other" );
}
#endif
fatal ( " unhandled " );
return false ;
}
return d->dom_lca (n) == d;
}
bool PhaseCFG::is_CFG (Node* n) {
return n->is_block_proj () || n->is_block_start () || is_control_proj_or_safepoint (n);
}
bool PhaseCFG::is_control_proj_or_safepoint (Node* n) {
bool result = (n->is_Mach () && n->as_Mach ()->ideal_Opcode () == Op_SafePoint) || (n->is_Proj () && n->as_Proj ()->bottom_type () == Type::CONTROL);
assert (!result || (n->is_Mach () && n->as_Mach ()->ideal_Opcode () == Op_SafePoint)
|| (n->is_Proj () && n->as_Proj ()->_con == 0 ), " If control projection, it must be projection 0" );
return result;
}
Block* PhaseCFG::find_block_for_node (Node* n) {
if (n->is_block_start () || n->is_block_proj ()) {
return get_block_for_node (n);
} else {
// Walk the control graph up if 'n' is not a block start nor a block projection. In this case 'n' must be
// an unmatched control projection or a not yet matched safepoint precedence edge in the middle of a block.
assert (is_control_proj_or_safepoint (n), " must be control projection or safepoint" );
Node* ctrl = n->in (0 );
while (!ctrl->is_block_start ()) {
ctrl = ctrl->in (0 );
}
return get_block_for_node (ctrl);
}
}
// Walk up the control graph from 'n' and check if 'dom_ctrl' is found.
bool PhaseCFG::is_dominating_control (Node* dom_ctrl, Node* n) {
Node* ctrl = n->in (0 );
while (!ctrl->is_block_start ()) {
if (ctrl == dom_ctrl) {
return true ;
}
ctrl = ctrl->in (0 );
}
return false ;
}
// ------------------------------schedule_pinned_nodes--------------------------
// Set the basic block for Nodes pinned into blocks
void PhaseCFG::schedule_pinned_nodes (VectorSet &visited) {
// Allocate node stack of size C->live_nodes()+8 to avoid frequent realloc
GrowableArray <Node *> spstack (C->live_nodes () + 8 );
GrowableArray <Node*> spstack (C->live_nodes () + 8 );
spstack.push (_root);
while (spstack.is_nonempty ()) {
Node* node = spstack.pop ();
@@ -160,20 +216,19 @@ void PhaseCFG::schedule_pinned_nodes(VectorSet &visited) {
for (uint i = node->len ()-1 ; i >= node->req (); i--) {
Node* m = node->in (i);
if (m == NULL ) continue ;
// Skip the precedence edge if the test that guarded a CastPP:
// - was optimized out during escape analysis
// (OptimizePtrCompare): the CastPP's control isn't an end of
// block.
// - is moved in the branch of a dominating If: the control of
// the CastPP is then a Region.
if (m->is_block_proj () || m->is_block_start ()) {
// Only process precedence edges that are CFG nodes. Safepoints and control projections can be in the middle of a block
if (is_CFG (m)) {
node->rm_prec (i);
if (n == NULL ) {
n = m;
} else {
assert (is_dominator (n, m) || is_dominator (m, n), " one must dominate the other" );
n = is_dominator (n, m) ? m : n;
}
} else {
assert (node->is_Mach (), " sanity" );
assert (node->as_Mach ()->ideal_Opcode () == Op_StoreCM, " must be StoreCM node" );
}
}
if (n != NULL ) {
@@ -185,7 +240,7 @@ void PhaseCFG::schedule_pinned_nodes(VectorSet &visited) {
}
// process all inputs that are non NULL
for (int i = node->req () - 1 ; i >= 0 ; --i) {
for (int i = node->req ()- 1 ; i >= 0 ; --i) {
if (node->in (i) != NULL ) {
spstack.push (node->in (i));
}