hotspot/src/share/vm/opto/loopTransform.cpp
changeset 8870 119881dc9d0b
parent 8732 16fc1c68714b
child 8879 e6ae9a7aa72a
equal deleted inserted replaced
8869:dd30e4318b8d 8870:119881dc9d0b
  1606   CountedLoopNode *cl = _head->as_CountedLoop();
  1606   CountedLoopNode *cl = _head->as_CountedLoop();
  1607   if (!cl->loopexit())
  1607   if (!cl->loopexit())
  1608     return false; // Malformed loop
  1608     return false; // Malformed loop
  1609   if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue))))
  1609   if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue))))
  1610     return false;             // Infinite loop
  1610     return false;             // Infinite loop
  1611 #ifndef PRODUCT
  1611 
  1612   if (PrintOpto) {
       
  1613     tty->print("Removing empty loop");
       
  1614     this->dump_head();
       
  1615   } else if (TraceLoopOpts) {
       
  1616     tty->print("Empty        ");
       
  1617     this->dump_head();
       
  1618   }
       
  1619 #endif
       
  1620 #ifdef ASSERT
  1612 #ifdef ASSERT
  1621   // Ensure only one phi which is the iv.
  1613   // Ensure only one phi which is the iv.
  1622   Node* iv = NULL;
  1614   Node* iv = NULL;
  1623   for (DUIterator_Fast imax, i = cl->fast_outs(imax); i < imax; i++) {
  1615   for (DUIterator_Fast imax, i = cl->fast_outs(imax); i < imax; i++) {
  1624     Node* n = cl->fast_out(i);
  1616     Node* n = cl->fast_out(i);
  1627       iv = n;
  1619       iv = n;
  1628     }
  1620     }
  1629   }
  1621   }
  1630   assert(iv == cl->phi(), "Wrong phi" );
  1622   assert(iv == cl->phi(), "Wrong phi" );
  1631 #endif
  1623 #endif
       
  1624 
       
  1625   // main and post loops have explicitly created zero trip guard
       
  1626   bool needs_guard = !cl->is_main_loop() && !cl->is_post_loop();
       
  1627   if (needs_guard) {
       
  1628     // Check for an obvious zero trip guard.
       
  1629     Node* inctrl = cl->in(LoopNode::EntryControl);
       
  1630     if (inctrl->Opcode() == Op_IfTrue) {
       
  1631       // The test should look like just the backedge of a CountedLoop
       
  1632       Node* iff = inctrl->in(0);
       
  1633       if (iff->is_If()) {
       
  1634         Node* bol = iff->in(1);
       
  1635         if (bol->is_Bool() && bol->as_Bool()->_test._test == cl->loopexit()->test_trip()) {
       
  1636           Node* cmp = bol->in(1);
       
  1637           if (cmp->is_Cmp() && cmp->in(1) == cl->init_trip() && cmp->in(2) == cl->limit()) {
       
  1638             needs_guard = false;
       
  1639           }
       
  1640         }
       
  1641       }
       
  1642     }
       
  1643   }
       
  1644 
       
  1645 #ifndef PRODUCT
       
  1646   if (PrintOpto) {
       
  1647     tty->print("Removing empty loop with%s zero trip guard", needs_guard ? "out" : "");
       
  1648     this->dump_head();
       
  1649   } else if (TraceLoopOpts) {
       
  1650     tty->print("Empty with%s zero trip guard   ", needs_guard ? "out" : "");
       
  1651     this->dump_head();
       
  1652   }
       
  1653 #endif
       
  1654 
       
  1655   if (needs_guard) {
       
  1656     // Peel the loop to ensure there's a zero trip guard
       
  1657     Node_List old_new;
       
  1658     phase->do_peeling(this, old_new);
       
  1659   }
       
  1660 
  1632   // Replace the phi at loop head with the final value of the last
  1661   // Replace the phi at loop head with the final value of the last
  1633   // iteration.  Then the CountedLoopEnd will collapse (backedge never
  1662   // iteration.  Then the CountedLoopEnd will collapse (backedge never
  1634   // taken) and all loop-invariant uses of the exit values will be correct.
  1663   // taken) and all loop-invariant uses of the exit values will be correct.
  1635   Node *phi = cl->phi();
  1664   Node *phi = cl->phi();
  1636   Node *final = new (phase->C, 3) SubINode( cl->limit(), cl->stride() );
  1665   Node *final = new (phase->C, 3) SubINode( cl->limit(), cl->stride() );