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 Thu Jan 7 16:01:54 2010
--- new/src/share/vm/opto/loopnode.cpp Thu Jan 7 16:01:54 2010
*** 1418,1432 ****
--- 1418,1478 ----
log->tail("loop");
if( loop->_next ) log_loop_tree(root, loop->_next, log);
}
}
+ //---------------------collect_potentially_useful_predicates-----------------------
+ //Helper function to collect potentially useful predicates to prevent them from
+ //being eliminated by PhaseIdealLoop::eliminate_useless_predicates
+ void PhaseIdealLoop::collect_potentially_useful_predicates(
+ IdealLoopTree * loop, Unique_Node_List &useful_predicates) {
+ if (loop->_child) { // child
+ collect_potentially_useful_predicates(loop->_child, useful_predicates);
+ }
+
+ //self (only loops that we can apply loop predication may use their predicates)
+ if (loop->_head->is_Loop() &&
+ !loop->_irreducible &&
+ !loop->tail()->is_top()) {
+ LoopNode *lpn = loop->_head->as_Loop();
+ Node* entry = lpn->in(LoopNode::EntryControl);
+ ProjNode *predicate_proj = find_predicate_insertion_point(entry);
+ if (predicate_proj != NULL ) { //right pattern that can be used by loop predication
+ assert(entry->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
+ useful_predicates.push(entry->in(0)->in(1)->in(1)); //good one
+ }
+ }
+
+ if( loop->_next ) { // sibling
+ collect_potentially_useful_predicates(loop->_next, useful_predicates);
+ }
+ }
+
+ //------------------------eliminate_useless_predicates-----------------------------
+ // Eliminate all inserted predicates if they could not be used by loop predication.
+ void PhaseIdealLoop::eliminate_useless_predicates() {
+ if(C->predicate_count() == 0) return; //no predicate left
+
+ Unique_Node_List useful_predicates; //to store useful predicates
+ if( C->has_loops()) {
+ collect_potentially_useful_predicates(_ltree_root->_child, useful_predicates);
+ }
+
+ for (int i = C->predicate_count(); i > 0; i--) {
+ Node * n = C->predicate_opaque1_node(i-1);
+ assert(n->Opcode() == Op_Opaque1, "must be");
+ if(!useful_predicates.member(n)) { //not in the useful list
+ _igvn.replace_node(n, n->in(1));
+ }
+ }
+ }
+
//=============================================================================
//----------------------------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.
! void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool do_loop_pred) {
int old_progress = C->major_progress();
// Reset major-progress flag for the driver's heuristics
C->clear_major_progress();
*** 1575,1584 ****
--- 1621,1636 ----
assert(C->unique() == unique, "verification mode made Nodes? ? ?");
assert(_igvn._worklist.size() == 0, "shouldn't push anything");
return;
}
+ // some parser-inserted loop predicates could never be used by loop
+ // predication. Eliminate them before loop optimization
+ if(UseLoopPredicate) {
+ eliminate_useless_predicates();
+ }
+
// clear out the dead code
while(_deadlist.size()) {
_igvn.remove_globally_dead_node(_deadlist.pop());
}
*** 1617,1626 ****
--- 1669,1683 ----
visited.Clear();
split_if_with_blocks( visited, nstack );
NOT_PRODUCT( if( VerifyLoopOptimizations ) verify(); );
}
+ // Perform loop predication before iteration splitting
+ if(do_loop_pred && C->has_loops() && !C->major_progress()) {
+ _ltree_root->_child->loop_predication(this);
+ }
+
// Perform iteration-splitting on inner loops. Split iterations to avoid
// range checks or one-shot null checks.
// If split-if's didn't hack the graph too bad (no CFG changes)
// then do loop opts.
*** 2761,2770 ****
--- 2818,2843 ----
assert(LCA != NULL && !LCA->is_top(), "no dead nodes");
Node *legal = LCA; // Walk 'legal' up the IDOM chain
Node *least = legal; // Best legal position so far
while( early != legal ) { // While not at earliest legal
+ #ifdef ASSERT
+ if (legal->is_Start() && !early->is_Root()) {
+ // Bad graph. Print idom path and fail.
+ tty->print_cr( "Bad graph detected in build_loop_late");
+ tty->print("n: ");n->dump(); tty->cr();
+ tty->print("early: ");early->dump(); tty->cr();
+ int ct = 0;
+ Node *dbg_legal = LCA;
+ while(!dbg_legal->is_Start() && ct < 100) {
+ tty->print("idom[%d] ",ct); dbg_legal->dump(); tty->cr();
+ ct++;
+ dbg_legal = idom(dbg_legal);
+ }
+ assert(false, "Bad graph detected in build_loop_late");
+ }
+ #endif
// Find least loop nesting depth
legal = idom(legal); // Bump up the IDOM tree
// Check for lower nesting depth
if( get_loop(legal)->_nest < get_loop(least)->_nest )
least = legal;
src/share/vm/opto/loopnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File