diff -r 244bf8afbbd3 -r 1927db75dd85 src/share/vm/opto/loopTransform.cpp --- a/src/share/vm/opto/loopTransform.cpp Sat Mar 26 08:31:45 2011 -0700 +++ b/src/share/vm/opto/loopTransform.cpp Sun Mar 27 00:00:14 2011 -0700 @@ -1608,15 +1608,7 @@ return false; // Malformed loop if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue)))) return false; // Infinite loop -#ifndef PRODUCT - if (PrintOpto) { - tty->print("Removing empty loop"); - this->dump_head(); - } else if (TraceLoopOpts) { - tty->print("Empty "); - this->dump_head(); - } -#endif + #ifdef ASSERT // Ensure only one phi which is the iv. Node* iv = NULL; @@ -1629,6 +1621,43 @@ } assert(iv == cl->phi(), "Wrong phi" ); #endif + + // main and post loops have explicitly created zero trip guard + bool needs_guard = !cl->is_main_loop() && !cl->is_post_loop(); + if (needs_guard) { + // Check for an obvious zero trip guard. + Node* inctrl = cl->in(LoopNode::EntryControl); + if (inctrl->Opcode() == Op_IfTrue) { + // The test should look like just the backedge of a CountedLoop + Node* iff = inctrl->in(0); + if (iff->is_If()) { + Node* bol = iff->in(1); + if (bol->is_Bool() && bol->as_Bool()->_test._test == cl->loopexit()->test_trip()) { + Node* cmp = bol->in(1); + if (cmp->is_Cmp() && cmp->in(1) == cl->init_trip() && cmp->in(2) == cl->limit()) { + needs_guard = false; + } + } + } + } + } + +#ifndef PRODUCT + if (PrintOpto) { + tty->print("Removing empty loop with%s zero trip guard", needs_guard ? "out" : ""); + this->dump_head(); + } else if (TraceLoopOpts) { + tty->print("Empty with%s zero trip guard ", needs_guard ? "out" : ""); + this->dump_head(); + } +#endif + + if (needs_guard) { + // Peel the loop to ensure there's a zero trip guard + Node_List old_new; + phase->do_peeling(this, old_new); + } + // Replace the phi at loop head with the final value of the last // iteration. Then the CountedLoopEnd will collapse (backedge never // taken) and all loop-invariant uses of the exit values will be correct.