src/share/vm/opto/loopnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/loopnode.cpp Wed Aug 12 15:10:32 2009
--- new/src/share/vm/opto/loopnode.cpp Wed Aug 12 15:10:31 2009
*** 1418,1434 ****
--- 1418,1433 ----
if( loop->_next ) log_loop_tree(root, loop->_next, log);
}
}
//=============================================================================
! //------------------------------PhaseIdealLoop---------------------------------
! //----------------------------build_and_optimize-------------------------------
// Create a PhaseLoop. Build the ideal Loop tree. Map each Ideal Node to
// its corresponding LoopNode. If 'optimize' is true, do some loop cleanups.
PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify_me, bool do_split_ifs )
: PhaseTransform(Ideal_Loop),
_igvn(igvn),
_dom_lca_tags(C->comp_arena()) {
+ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs) {
+ int old_progress = C->major_progress();
+
// Reset major-progress flag for the driver's heuristics
C->clear_major_progress();
#ifndef PRODUCT
// Capture for later assert
*** 1463,1494 ****
--- 1462,1495 ----
if (C->failing()) {
return;
}
// No loops after all
! if( !_ltree_root->_child && !_verify_only ) C->set_has_loops(false);
// There should always be an outer loop containing the Root and Return nodes.
// If not, we have a degenerate empty program. Bail out in this case.
if (!has_node(C->root())) {
+ if (!_verify_only) {
C->clear_major_progress();
C->record_method_not_compilable("empty program detected during loop optimization");
+ }
return;
}
// Nothing to do, so get out
! if( !C->has_loops() && !do_split_ifs && !_verify_me && !_verify_only ) {
_igvn.optimize(); // Cleanup NeverBranches
return;
}
// Set loop nesting depth
_ltree_root->set_nest( 0 );
// Split shared headers and insert loop landing pads.
// Do not bother doing this on the Root loop of course.
! if( !_verify_me && !_verify_only && _ltree_root->_child ) {
if( _ltree_root->_child->beautify_loops( this ) ) {
// Re-build loop tree!
_ltree_root->_child = NULL;
_nodes.clear();
reallocate_preorders();
*** 1513,1522 ****
--- 1514,1524 ----
_dom_stk = NULL; // Allocated on demand in recompute_dom_depth
memset( _dom_depth, 0, _idom_size * sizeof(uint) );
Dominators();
+ if (!_verify_only) {
// As a side effect, Dominators removed any unreachable CFG paths
// into RegionNodes. It doesn't do this test against Root, so
// we do it here.
for( uint i = 1; i < C->root()->req(); i++ ) {
if( !_nodes[C->root()->in(i)->_idx] ) { // Dead path into Root?
*** 1530,1539 ****
--- 1532,1542 ----
// Given dominators, try to find inner loops with calls that must
// always be executed (call dominates loop tail). These loops do
// not need a separate safepoint.
Node_List cisstack(a);
_ltree_root->check_safepts(visited, cisstack);
+ }
// Walk the DATA nodes and place into loops. Find earliest control
// node. For CFG nodes, the _nodes array starts out and remains
// holding the associated IdealLoopTree pointer. For DATA nodes, the
// _nodes array holds the earliest legal controlling CFG node.
*** 1546,1579 ****
--- 1549,1591 ----
Node_List worklist(a);
// Don't need C->root() on worklist since
// it will be processed among C->top() inputs
worklist.push( C->top() );
visited.set( C->top()->_idx ); // Set C->top() as visited now
- build_loop_early( visited, worklist, nstack, verify_me );
// Given early legal placement, try finding counted loops. This placement
// is good enough to discover most loop invariants.
! if( !_verify_me && !_verify_only )
_ltree_root->counted_loop( this );
// Find latest loop placement. Find ideal loop placement.
visited.Clear();
init_dom_lca_tags();
// Need C->root() on worklist when processing outs
worklist.push( C->root() );
NOT_PRODUCT( C->verify_graph_edges(); )
worklist.push( C->top() );
- build_loop_late( visited, worklist, nstack, verify_me );
+ if (_verify_only) {
+ // restore major progress flag
+ for (int i = 0; i < old_progress; i++)
+ C->set_major_progress();
+ assert(C->unique() == unique, "verification mode made Nodes? ? ?");
+ assert(_igvn._worklist.size() == 0, "shouldn't push anything");
+ return;
+ }
+
// clear out the dead code
while(_deadlist.size()) {
! _igvn.remove_globally_dead_node(_deadlist.pop());
}
#ifndef PRODUCT
C->verify_graph_edges();
! if( _verify_me ) { // Nested verify pass?
// Check to see if the verify mode is broken
assert(C->unique() == unique, "non-optimize mode made Nodes? ? ?");
return;
}
if( VerifyLoopOptimizations ) verify();
*** 1676,1686 ****
--- 1688,1698 ----
// Build a verify-only PhaseIdealLoop, and see that it agrees with me.
static int fail; // debug only, so its multi-thread dont care
void PhaseIdealLoop::verify() const {
int old_progress = C->major_progress();
ResourceMark rm;
- PhaseIdealLoop loop_verify( _igvn, this, false );
VectorSet visited(Thread::current()->resource_area());
fail = 0;
verify_compare( C->root(), &loop_verify, visited );
assert( fail == 0, "verify loops failed" );
*** 2136,2145 ****
--- 2148,2158 ----
// new loop exit. This would make the infinite loop a first-class
// loop and it would then get properly optimized. What's the use of
// optimizing an infinite loop?
l = _ltree_root; // Oops, found infinite loop
+ if (!_verify_only) {
// Insert the NeverBranch between 'm' and it's control user.
NeverBranchNode *iff = new (C, 1) NeverBranchNode( m );
_igvn.register_new_node_with_optimizer(iff);
set_loop(iff, l);
Node *if_t = new (C, 1) CProjNode( iff, 0 );
*** 2169,2184 ****
--- 2182,2199 ----
// Halt & Catch Fire
Node *halt = new (C, TypeFunc::Parms) HaltNode( if_f, frame );
_igvn.register_new_node_with_optimizer(halt);
set_loop(halt, l);
C->root()->add_req(halt);
+ }
set_loop(C->root(), _ltree_root);
}
}
// Weeny check for irreducible. This child was already visited (this
// IS the post-work phase). Is this child's loop header post-visited
// as well? If so, then I found another entry into the loop.
+ if (!_verify_only) {
while( is_postvisited(l->_head) ) {
// found irreducible
l->_irreducible = 1; // = true
l = l->_parent;
_has_irreducible_loops = true;
*** 2186,2195 ****
--- 2201,2211 ----
if (l == NULL) {
C->record_method_not_compilable("unhandled CFG detected during loop optimization");
return pre_order;
}
}
+ }
// This Node might be a decision point for loops. It is only if
// it's children belong to several different loops. The sort call
// does a trivial amount of work if there is only 1 child or all
// children belong to the same loop. If however, the children
*** 2251,2261 ****
--- 2267,2277 ----
//------------------------------build_loop_early-------------------------------
// Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
// First pass computes the earliest controlling node possible. This is the
// controlling input with the deepest dominating depth.
- void PhaseIdealLoop::build_loop_early( VectorSet &visited, Node_List &worklist, Node_Stack &nstack, const PhaseIdealLoop *verify_me ) {
while (worklist.size() != 0) {
// Use local variables nstack_top_n & nstack_top_i to cache values
// on nstack's top.
Node *nstack_top_n = worklist.pop();
uint nstack_top_i = 0;
*** 2283,2293 ****
--- 2299,2309 ----
}
// Remove safepoints ONLY if I've already seen I don't need one.
// (the old code here would yank a 2nd safepoint after seeing a
// first one, even though the 1st did not dominate in the loop body
// and thus could be avoided indefinitely)
! if( !_verify_only && !_verify_me && ilt->_has_sfpt && n->Opcode() == Op_SafePoint &&
is_deleteable_safept(n)) {
Node *in = n->in(TypeFunc::Control);
lazy_replace(n,in); // Pull safepoint now
// Carry on with the recursion "as if" we are walking
// only the control input
*** 2406,2440 ****
--- 2422,2494 ----
LCA = dom_lca( LCA, region->in(i) );
}
return LCA;
}
//------------------------------get_late_ctrl----------------------------------
// Compute latest legal control.
Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) {
assert(early != NULL, "early control should not be NULL");
+ bool PhaseIdealLoop::verify_dominance(Node* n, Node* use, Node* LCA, Node* early) {
+ bool had_error = false;
+ #ifdef ASSERT
+ if (early != C->root()) {
+ // Make sure that there's a dominance path from use to LCA
+ Node* d = use;
+ while (d != LCA) {
+ d = idom(d);
+ if (d == C->root()) {
+ tty->print_cr("*** Use %d isn't dominated by def %s", use->_idx, n->_idx);
+ n->dump();
+ use->dump();
+ had_error = true;
+ break;
+ }
+ }
+ }
+ #endif
+ return had_error;
+ }
+
+ Node* PhaseIdealLoop::compute_lca_of_uses(Node* n, Node* early, bool verify) {
// Compute LCA over list of uses
+ bool had_error = false;
Node *LCA = NULL;
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && LCA != early; i++) {
Node* c = n->fast_out(i);
if (_nodes[c->_idx] == NULL)
continue; // Skip the occasional dead node
if( c->is_Phi() ) { // For Phis, we must land above on the path
for( uint j=1; j<c->req(); j++ ) {// For all inputs
if( c->in(j) == n ) { // Found matching input?
Node *use = c->in(0)->in(j);
+ if (_verify_only && use->is_top()) continue;
LCA = dom_lca_for_get_late_ctrl( LCA, use, n );
+ if (verify) had_error = verify_dominance(n, use, LCA, early) || had_error;
}
}
} else {
// For CFG data-users, use is in the block just prior
Node *use = has_ctrl(c) ? get_ctrl(c) : c->in(0);
LCA = dom_lca_for_get_late_ctrl( LCA, use, n );
+ if (verify) had_error = verify_dominance(n, use, LCA, early) || had_error;
}
}
+ assert(!had_error, "bad dominance");
+ return LCA;
+ }
+ //------------------------------get_late_ctrl----------------------------------
+ // Compute latest legal control.
+ Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) {
+ assert(early != NULL, "early control should not be NULL");
+
+ Node* LCA = compute_lca_of_uses(n, early);
+ #ifdef ASSERT
+ if (LCA == C->root() && LCA != early) {
+ // def doesn't dominate uses so print some useful debugging output
+ compute_lca_of_uses(n, early, true);
+ }
+ #endif
+
// if this is a load, check for anti-dependent stores
// We use a conservative algorithm to identify potential interfering
// instructions and for rescheduling the load. The users of the memory
// input of this load are examined. Any use which is not a load and is
// dominated by early is considered a potentially interfering store.
*** 2574,2584 ****
--- 2628,2638 ----
}
//------------------------------build_loop_late--------------------------------
// Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
// Second pass finds latest legal placement, and ideal loop placement.
- void PhaseIdealLoop::build_loop_late( VectorSet &visited, Node_List &worklist, Node_Stack &nstack, const PhaseIdealLoop *verify_me ) {
while (worklist.size() != 0) {
Node *n = worklist.pop();
// Only visit once
if (visited.test_set(n->_idx)) continue;
uint cnt = n->outcnt();
*** 2610,2620 ****
--- 2664,2674 ----
// push dead code onto a worklist
_deadlist.push(use);
}
} else {
// All of n's children have been processed, complete post-processing.
- build_loop_late_post(n, verify_me);
if (nstack.is_empty()) {
// Finished all nodes on stack.
// Process next node on the worklist.
break;
}
*** 2629,2641 ****
--- 2683,2695 ----
}
//------------------------------build_loop_late_post---------------------------
// Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
// Second pass finds latest legal placement, and ideal loop placement.
- void PhaseIdealLoop::build_loop_late_post( Node *n, const PhaseIdealLoop *verify_me ) {
! if (n->req() == 2 && n->Opcode() == Op_ConvI2L && !C->major_progress() && !_verify_only) {
_igvn._worklist.push(n); // Maybe we'll normalize it, if no more loops.
}
// CFG and pinned nodes already handled
if( n->in(0) ) {
*** 2712,2721 ****
--- 2766,2776 ----
legal = idom(legal); // Bump up the IDOM tree
// Check for lower nesting depth
if( get_loop(legal)->_nest < get_loop(least)->_nest )
least = legal;
}
+ assert(early == legal || legal != C->root(), "bad dominance of inputs");
// Try not to place code on a loop entry projection
// which can inhibit range check elimination.
if (least != early) {
Node* ctrl_out = least->unique_ctrl_out();
*** 2729,2740 ****
--- 2784,2795 ----
}
#ifdef ASSERT
// If verifying, verify that 'verify_me' has a legal location
// and choose it as our location.
! if( _verify_me ) {
! Node *v_ctrl = _verify_me->get_ctrl_no_update(n);
Node *legal = LCA;
while( early != legal ) { // While not at earliest legal
if( legal == v_ctrl ) break; // Check for prior good location
legal = idom(legal) ;// Bump up the IDOM tree
}
src/share/vm/opto/loopnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File