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