comparison src/share/vm/opto/loopTransform.cpp @ 2403:1927db75dd85

7024475: loop doesn't terminate when compiled Reviewed-by: kvn
author never
date Sun, 27 Mar 2011 00:00:14 -0700
parents 9dc311b8473e
children f9424955eb18
comparison
equal deleted inserted replaced
2402:244bf8afbbd3 2403:1927db75dd85
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() );