hotspot/src/share/vm/opto/loopopts.cpp
changeset 8732 16fc1c68714b
parent 7397 5b173b4ca846
child 9101 ff58f9a8e31c
child 8921 14bfe81f2a9d
--- a/hotspot/src/share/vm/opto/loopopts.cpp	Mon Mar 21 02:30:49 2011 -0700
+++ b/hotspot/src/share/vm/opto/loopopts.cpp	Mon Mar 21 11:28:14 2011 -0700
@@ -42,13 +42,13 @@
     return NULL;
   }
   int wins = 0;
-  assert( !n->is_CFG(), "" );
-  assert( region->is_Region(), "" );
+  assert(!n->is_CFG(), "");
+  assert(region->is_Region(), "");
 
   const Type* type = n->bottom_type();
   const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr();
   Node *phi;
-  if( t_oop != NULL && t_oop->is_known_instance_field() ) {
+  if (t_oop != NULL && t_oop->is_known_instance_field()) {
     int iid    = t_oop->instance_id();
     int index  = C->get_alias_index(t_oop);
     int offset = t_oop->offset();
@@ -57,20 +57,20 @@
     phi = PhiNode::make_blank(region, n);
   }
   uint old_unique = C->unique();
-  for( uint i = 1; i < region->req(); i++ ) {
+  for (uint i = 1; i < region->req(); i++) {
     Node *x;
     Node* the_clone = NULL;
-    if( region->in(i) == C->top() ) {
+    if (region->in(i) == C->top()) {
       x = C->top();             // Dead path?  Use a dead data op
     } else {
       x = n->clone();           // Else clone up the data op
       the_clone = x;            // Remember for possible deletion.
       // Alter data node to use pre-phi inputs
-      if( n->in(0) == region )
+      if (n->in(0) == region)
         x->set_req( 0, region->in(i) );
-      for( uint j = 1; j < n->req(); j++ ) {
+      for (uint j = 1; j < n->req(); j++) {
         Node *in = n->in(j);
-        if( in->is_Phi() && in->in(0) == region )
+        if (in->is_Phi() && in->in(0) == region)
           x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone
       }
     }
@@ -85,7 +85,7 @@
     // happen if the singleton occurs on loop entry, as the elimination of
     // the PhiNode may cause the resulting node to migrate back to a previous
     // loop iteration.
-    if( singleton && t == Type::TOP ) {
+    if (singleton && t == Type::TOP) {
       // Is_Loop() == false does not confirm the absence of a loop (e.g., an
       // irreducible loop may not be indicated by an affirmative is_Loop());
       // therefore, the only top we can split thru a phi is on a backedge of
@@ -93,7 +93,7 @@
       singleton &= region->is_Loop() && (i != LoopNode::EntryControl);
     }
 
-    if( singleton ) {
+    if (singleton) {
       wins++;
       x = ((PhaseGVN&)_igvn).makecon(t);
     } else {
@@ -108,12 +108,12 @@
       // igvn->type(x) is set to x->Value() already.
       x->raise_bottom_type(t);
       Node *y = x->Identity(&_igvn);
-      if( y != x ) {
+      if (y != x) {
         wins++;
         x = y;
       } else {
         y = _igvn.hash_find(x);
-        if( y ) {
+        if (y) {
           wins++;
           x = y;
         } else {
@@ -129,7 +129,7 @@
     phi->set_req( i, x );
   }
   // Too few wins?
-  if( wins <= policy ) {
+  if (wins <= policy) {
     _igvn.remove_dead_node(phi);
     return NULL;
   }
@@ -137,7 +137,7 @@
   // Record Phi
   register_new_node( phi, region );
 
-  for( uint i2 = 1; i2 < phi->req(); i2++ ) {
+  for (uint i2 = 1; i2 < phi->req(); i2++) {
     Node *x = phi->in(i2);
     // If we commoned up the cloned 'x' with another existing Node,
     // the existing Node picks up a new use.  We need to make the
@@ -145,24 +145,44 @@
     Node *old_ctrl;
     IdealLoopTree *old_loop;
 
+    if (x->is_Con()) {
+      // Constant's control is always root.
+      set_ctrl(x, C->root());
+      continue;
+    }
     // The occasional new node
-    if( x->_idx >= old_unique ) {   // Found a new, unplaced node?
-      old_ctrl = x->is_Con() ? C->root() : NULL;
-      old_loop = NULL;              // Not in any prior loop
+    if (x->_idx >= old_unique) {     // Found a new, unplaced node?
+      old_ctrl = NULL;
+      old_loop = NULL;               // Not in any prior loop
     } else {
-      old_ctrl = x->is_Con() ? C->root() : get_ctrl(x);
+      old_ctrl = get_ctrl(x);
       old_loop = get_loop(old_ctrl); // Get prior loop
     }
     // New late point must dominate new use
-    Node *new_ctrl = dom_lca( old_ctrl, region->in(i2) );
+    Node *new_ctrl = dom_lca(old_ctrl, region->in(i2));
+    if (new_ctrl == old_ctrl) // Nothing is changed
+      continue;
+
+    IdealLoopTree *new_loop = get_loop(new_ctrl);
+
+    // Don't move x into a loop if its uses are
+    // outside of loop. Otherwise x will be cloned
+    // for each use outside of this loop.
+    IdealLoopTree *use_loop = get_loop(region);
+    if (!new_loop->is_member(use_loop) &&
+        (old_loop == NULL || !new_loop->is_member(old_loop))) {
+      // Take early control, later control will be recalculated
+      // during next iteration of loop optimizations.
+      new_ctrl = get_early_ctrl(x);
+      new_loop = get_loop(new_ctrl);
+    }
     // Set new location
     set_ctrl(x, new_ctrl);
-    IdealLoopTree *new_loop = get_loop( new_ctrl );
     // If changing loop bodies, see if we need to collect into new body
-    if( old_loop != new_loop ) {
-      if( old_loop && !old_loop->_child )
+    if (old_loop != new_loop) {
+      if (old_loop && !old_loop->_child)
         old_loop->_body.yank(x);
-      if( !new_loop->_child )
+      if (!new_loop->_child)
         new_loop->_body.push(x);  // Collect body info
     }
   }
@@ -174,9 +194,9 @@
 // Replace the dominated test with an obvious true or false.  Place it on the
 // IGVN worklist for later cleanup.  Move control-dependent data Nodes on the
 // live path up to the dominating control.
-void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff ) {
+void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip ) {
 #ifndef PRODUCT
-  if( VerifyLoopOptimizations && PrintOpto ) tty->print_cr("dominating test");
+  if (VerifyLoopOptimizations && PrintOpto) tty->print_cr("dominating test");
 #endif
 
 
@@ -185,6 +205,12 @@
   assert( iff->Opcode() == Op_If || iff->Opcode() == Op_CountedLoopEnd, "Check this code when new subtype is added");
   int pop = prevdom->Opcode();
   assert( pop == Op_IfFalse || pop == Op_IfTrue, "" );
+  if (flip) {
+    if (pop == Op_IfTrue)
+      pop = Op_IfFalse;
+    else
+      pop = Op_IfTrue;
+  }
   // 'con' is set to true or false to kill the dominated test.
   Node *con = _igvn.makecon(pop == Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO);
   set_ctrl(con, C->root()); // Constant gets a new use
@@ -197,7 +223,7 @@
   // I can assume this path reaches an infinite loop.  In this case it's not
   // important to optimize the data Nodes - either the whole compilation will
   // be tossed or this path (and all data Nodes) will go dead.
-  if( iff->outcnt() != 2 ) return;
+  if (iff->outcnt() != 2) return;
 
   // Make control-dependent data Nodes on the live path (path that will remain
   // once the dominated IF is removed) become control-dependent on the
@@ -207,16 +233,16 @@
 
   for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
     Node* cd = dp->fast_out(i); // Control-dependent node
-    if( cd->depends_only_on_test() ) {
-      assert( cd->in(0) == dp, "" );
-      _igvn.hash_delete( cd );
+    if (cd->depends_only_on_test()) {
+      assert(cd->in(0) == dp, "");
+      _igvn.hash_delete(cd);
       cd->set_req(0, prevdom);
-      set_early_ctrl( cd );
+      set_early_ctrl(cd);
       _igvn._worklist.push(cd);
       IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
-      if( old_loop != new_loop ) {
-        if( !old_loop->_child ) old_loop->_body.yank(cd);
-        if( !new_loop->_child ) new_loop->_body.push(cd);
+      if (old_loop != new_loop) {
+        if (!old_loop->_child) old_loop->_body.yank(cd);
+        if (!new_loop->_child) new_loop->_body.push(cd);
       }
       --i;
       --imax;
@@ -2338,6 +2364,11 @@
   }
 
 #if !defined(PRODUCT)
+  if (TraceLoopOpts) {
+    tty->print("PartialPeel  ");
+    loop->dump_head();
+  }
+
   if (TracePartialPeeling) {
     tty->print_cr("before partial peel one iteration");
     Node_List wl;
@@ -2481,6 +2512,7 @@
   // Create new loop head for new phis and to hang
   // the nodes being moved (sinked) from the peel region.
   LoopNode* new_head = new (C, 3) LoopNode(last_peel, last_peel);
+  new_head->set_unswitch_count(head->unswitch_count()); // Preserve
   _igvn.register_new_node_with_optimizer(new_head);
   assert(first_not_peeled->in(0) == last_peel, "last_peel <- first_not_peeled");
   first_not_peeled->set_req(0, new_head);
@@ -2651,24 +2683,23 @@
 // prevent loop-fallout uses of the pre-incremented trip counter (which are
 // then alive with the post-incremented trip counter forcing an extra
 // register move)
-void PhaseIdealLoop::reorg_offsets( IdealLoopTree *loop ) {
+void PhaseIdealLoop::reorg_offsets(IdealLoopTree *loop) {
+  // Perform it only for canonical counted loops.
+  // Loop's shape could be messed up by iteration_split_impl.
+  if (!loop->_head->is_CountedLoop())
+    return;
+  if (!loop->_head->as_Loop()->is_valid_counted_loop())
+    return;
 
   CountedLoopNode *cl = loop->_head->as_CountedLoop();
   CountedLoopEndNode *cle = cl->loopexit();
-  if( !cle ) return;            // The occasional dead loop
-  // Find loop exit control
   Node *exit = cle->proj_out(false);
-  assert( exit->Opcode() == Op_IfFalse, "" );
+  Node *phi = cl->phi();
 
   // Check for the special case of folks using the pre-incremented
   // trip-counter on the fall-out path (forces the pre-incremented
   // and post-incremented trip counter to be live at the same time).
   // Fix this by adjusting to use the post-increment trip counter.
-  Node *phi = cl->phi();
-  if( !phi ) return;            // Dead infinite loop
-
-  // Shape messed up, probably by iteration_split_impl
-  if (phi->in(LoopNode::LoopBackControl) != cl->incr()) return;
 
   bool progress = true;
   while (progress) {
@@ -2677,21 +2708,19 @@
       Node* use = phi->fast_out(i);   // User of trip-counter
       if (!has_ctrl(use))  continue;
       Node *u_ctrl = get_ctrl(use);
-      if( use->is_Phi() ) {
+      if (use->is_Phi()) {
         u_ctrl = NULL;
-        for( uint j = 1; j < use->req(); j++ )
-          if( use->in(j) == phi )
-            u_ctrl = dom_lca( u_ctrl, use->in(0)->in(j) );
+        for (uint j = 1; j < use->req(); j++)
+          if (use->in(j) == phi)
+            u_ctrl = dom_lca(u_ctrl, use->in(0)->in(j));
       }
       IdealLoopTree *u_loop = get_loop(u_ctrl);
       // Look for loop-invariant use
-      if( u_loop == loop ) continue;
-      if( loop->is_member( u_loop ) ) continue;
+      if (u_loop == loop) continue;
+      if (loop->is_member(u_loop)) continue;
       // Check that use is live out the bottom.  Assuming the trip-counter
       // update is right at the bottom, uses of of the loop middle are ok.
-      if( dom_lca( exit, u_ctrl ) != exit ) continue;
-      // protect against stride not being a constant
-      if( !cle->stride_is_con() ) continue;
+      if (dom_lca(exit, u_ctrl) != exit) continue;
       // Hit!  Refactor use to use the post-incremented tripcounter.
       // Compute a post-increment tripcounter.
       Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() );
@@ -2702,9 +2731,10 @@
       register_new_node( post, u_ctrl );
       _igvn.hash_delete(use);
       _igvn._worklist.push(use);
-      for( uint j = 1; j < use->req(); j++ )
-        if( use->in(j) == phi )
+      for (uint j = 1; j < use->req(); j++) {
+        if (use->in(j) == phi)
           use->set_req(j, post);
+      }
       // Since DU info changed, rerun loop
       progress = true;
       break;