diff src/share/vm/opto/loopnode.cpp @ 2445:08eb13460b3a

7004535: Clone loop predicate during loop unswitch Summary: Clone loop predicate for clonned loops Reviewed-by: never
author kvn
date Sat, 02 Apr 2011 10:54:15 -0700
parents 1927db75dd85
children 3af54845df98
line wrap: on
line diff
--- a/src/share/vm/opto/loopnode.cpp	Sat Apr 02 09:49:27 2011 -0700
+++ b/src/share/vm/opto/loopnode.cpp	Sat Apr 02 10:54:15 2011 -0700
@@ -341,7 +341,12 @@
   //
   assert(x->Opcode() == Op_Loop, "regular loops only");
   C->print_method("Before CountedLoop", 3);
-
+#ifndef PRODUCT
+  if (TraceLoopOpts) {
+    tty->print("Counted      ");
+    loop->dump_head();
+  }
+#endif
   // If compare points to incr, we are ok.  Otherwise the compare
   // can directly point to the phi; in this case adjust the compare so that
   // it points to the incr by adjusting the limit.
@@ -864,8 +869,10 @@
   Node *outer = new (phase->C, 3) LoopNode( ctl, _head->in(outer_idx) );
   outer = igvn.register_new_node_with_optimizer(outer, _head);
   phase->set_created_loop_node();
+
+  Node* pred = phase->clone_loop_predicates(ctl, outer);
   // Outermost loop falls into '_head' loop
-  _head->set_req(LoopNode::EntryControl, outer);
+  _head->set_req(LoopNode::EntryControl, pred);
   _head->del_req(outer_idx);
   // Split all the Phis up between '_head' loop and 'outer' loop.
   for (DUIterator_Fast jmax, j = _head->fast_outs(jmax); j < jmax; j++) {
@@ -1103,12 +1110,13 @@
   // backedges into a private merge point and use the merge point as
   // the one true backedge.
   if( _head->req() > 3 ) {
-    // Merge the many backedges into a single backedge.
+    // Merge the many backedges into a single backedge but leave
+    // the hottest backedge as separate edge for the following peel.
     merge_many_backedges( phase );
     result = true;
   }
 
-  // If I am a shared header (multiple backedges), peel off myself loop.
+  // If I have one hot backedge, peel off myself loop.
   // I better be the outermost loop.
   if( _head->req() > 3 ) {
     split_outer_loop( phase );
@@ -1433,9 +1441,9 @@
   tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
   if (_irreducible) tty->print(" IRREDUCIBLE");
   if (UseLoopPredicate) {
-    Node* entry = _head->in(LoopNode::EntryControl);
-    if (entry != NULL && entry->is_Proj() &&
-        PhaseIdealLoop::is_uncommon_trap_if_pattern(entry->as_Proj(), Deoptimization::Reason_predicate)) {
+    Node* entry = PhaseIdealLoop::find_predicate_insertion_point(_head->in(LoopNode::EntryControl),
+                                                                 Deoptimization::Reason_predicate);
+    if (entry != NULL) {
       tty->print(" predicated");
     }
   }
@@ -1541,7 +1549,7 @@
 //----------------------------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) {
+void PhaseIdealLoop::build_and_optimize(bool do_split_ifs) {
   ResourceMark rm;
 
   int old_progress = C->major_progress();
@@ -1573,6 +1581,13 @@
   // Do not need a safepoint at the top level
   _ltree_root->_has_sfpt = 1;
 
+  // Initialize Dominators.
+  // Checked in clone_loop_predicate() during beautify_loops().
+  _idom_size = 0;
+  _idom      = NULL;
+  _dom_depth = NULL;
+  _dom_stk   = NULL;
+
   // Empty pre-order array
   allocate_preorders();
 
@@ -1698,8 +1713,9 @@
     return;
   }
 
-  // some parser-inserted loop predicates could never be used by loop
-  // predication. Eliminate them before loop optimization
+  // Some parser-inserted loop predicates could never be used by loop
+  // predication or they were moved away from loop during some optimizations.
+  // For example, peeling. Eliminate them before next loop optimizations.
   if (UseLoopPredicate) {
     eliminate_useless_predicates();
   }
@@ -1750,7 +1766,7 @@
   }
 
   // Perform loop predication before iteration splitting
-  if (do_loop_pred && C->has_loops() && !C->major_progress()) {
+  if (C->has_loops() && !C->major_progress() && (C->predicate_count() > 0)) {
     _ltree_root->_child->loop_predication(this);
   }
 
@@ -1793,8 +1809,20 @@
     C->set_major_progress();
   }
 
-  // Convert scalar to superword operations
+  // Keep loop predicates and perform optimizations with them
+  // until no more loop optimizations could be done.
+  // After that switch predicates off and do more loop optimizations.
+  if (!C->major_progress() && (C->predicate_count() > 0)) {
+     C->cleanup_loop_predicates(_igvn);
+#ifndef PRODUCT
+     if (TraceLoopOpts) {
+       tty->print_cr("PredicatesOff");
+     }
+#endif
+     C->set_major_progress();
+  }
 
+  // Convert scalar to superword operations at the end of all loop opts.
   if (UseSuperWord && C->has_loops() && !C->major_progress()) {
     // SuperWord transform
     SuperWord sw(this);