src/share/vm/opto/loopTransform.cpp

changeset 2685
1927db75dd85
parent 2665
9dc311b8473e
child 2694
f9424955eb18
     1.1 --- a/src/share/vm/opto/loopTransform.cpp	Sat Mar 26 08:31:45 2011 -0700
     1.2 +++ b/src/share/vm/opto/loopTransform.cpp	Sun Mar 27 00:00:14 2011 -0700
     1.3 @@ -1608,15 +1608,7 @@
     1.4      return false; // Malformed loop
     1.5    if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue))))
     1.6      return false;             // Infinite loop
     1.7 -#ifndef PRODUCT
     1.8 -  if (PrintOpto) {
     1.9 -    tty->print("Removing empty loop");
    1.10 -    this->dump_head();
    1.11 -  } else if (TraceLoopOpts) {
    1.12 -    tty->print("Empty        ");
    1.13 -    this->dump_head();
    1.14 -  }
    1.15 -#endif
    1.16 +
    1.17  #ifdef ASSERT
    1.18    // Ensure only one phi which is the iv.
    1.19    Node* iv = NULL;
    1.20 @@ -1629,6 +1621,43 @@
    1.21    }
    1.22    assert(iv == cl->phi(), "Wrong phi" );
    1.23  #endif
    1.24 +
    1.25 +  // main and post loops have explicitly created zero trip guard
    1.26 +  bool needs_guard = !cl->is_main_loop() && !cl->is_post_loop();
    1.27 +  if (needs_guard) {
    1.28 +    // Check for an obvious zero trip guard.
    1.29 +    Node* inctrl = cl->in(LoopNode::EntryControl);
    1.30 +    if (inctrl->Opcode() == Op_IfTrue) {
    1.31 +      // The test should look like just the backedge of a CountedLoop
    1.32 +      Node* iff = inctrl->in(0);
    1.33 +      if (iff->is_If()) {
    1.34 +        Node* bol = iff->in(1);
    1.35 +        if (bol->is_Bool() && bol->as_Bool()->_test._test == cl->loopexit()->test_trip()) {
    1.36 +          Node* cmp = bol->in(1);
    1.37 +          if (cmp->is_Cmp() && cmp->in(1) == cl->init_trip() && cmp->in(2) == cl->limit()) {
    1.38 +            needs_guard = false;
    1.39 +          }
    1.40 +        }
    1.41 +      }
    1.42 +    }
    1.43 +  }
    1.44 +
    1.45 +#ifndef PRODUCT
    1.46 +  if (PrintOpto) {
    1.47 +    tty->print("Removing empty loop with%s zero trip guard", needs_guard ? "out" : "");
    1.48 +    this->dump_head();
    1.49 +  } else if (TraceLoopOpts) {
    1.50 +    tty->print("Empty with%s zero trip guard   ", needs_guard ? "out" : "");
    1.51 +    this->dump_head();
    1.52 +  }
    1.53 +#endif
    1.54 +
    1.55 +  if (needs_guard) {
    1.56 +    // Peel the loop to ensure there's a zero trip guard
    1.57 +    Node_List old_new;
    1.58 +    phase->do_peeling(this, old_new);
    1.59 +  }
    1.60 +
    1.61    // Replace the phi at loop head with the final value of the last
    1.62    // iteration.  Then the CountedLoopEnd will collapse (backedge never
    1.63    // taken) and all loop-invariant uses of the exit values will be correct.

mercurial