src/share/vm/opto/node.cpp

changeset 6657
3636afd5ec1a
parent 6507
752ba2e5f6d0
child 6680
78bbf4d43a14
     1.1 --- a/src/share/vm/opto/node.cpp	Tue Apr 29 12:20:53 2014 -0700
     1.2 +++ b/src/share/vm/opto/node.cpp	Fri May 02 16:44:54 2014 -0700
     1.3 @@ -27,6 +27,7 @@
     1.4  #include "memory/allocation.inline.hpp"
     1.5  #include "opto/cfgnode.hpp"
     1.6  #include "opto/connode.hpp"
     1.7 +#include "opto/loopnode.hpp"
     1.8  #include "opto/machnode.hpp"
     1.9  #include "opto/matcher.hpp"
    1.10  #include "opto/node.hpp"
    1.11 @@ -1255,6 +1256,7 @@
    1.12  
    1.13    Node *top = igvn->C->top();
    1.14    nstack.push(dead);
    1.15 +  bool has_irreducible_loop = igvn->C->has_irreducible_loop();
    1.16  
    1.17    while (nstack.size() > 0) {
    1.18      dead = nstack.pop();
    1.19 @@ -1269,13 +1271,31 @@
    1.20            assert (!use->is_Con(), "Control for Con node should be Root node.");
    1.21            use->set_req(0, top);       // Cut dead edge to prevent processing
    1.22            nstack.push(use);           // the dead node again.
    1.23 +        } else if (!has_irreducible_loop && // Backedge could be alive in irreducible loop
    1.24 +                   use->is_Loop() && !use->is_Root() &&       // Don't kill Root (RootNode extends LoopNode)
    1.25 +                   use->in(LoopNode::EntryControl) == dead) { // Dead loop if its entry is dead
    1.26 +          use->set_req(LoopNode::EntryControl, top);          // Cut dead edge to prevent processing
    1.27 +          use->set_req(0, top);       // Cut self edge
    1.28 +          nstack.push(use);
    1.29          } else {                      // Else found a not-dead user
    1.30 +          // Dead if all inputs are top or null
    1.31 +          bool dead_use = !use->is_Root(); // Keep empty graph alive
    1.32            for (uint j = 1; j < use->req(); j++) {
    1.33 -            if (use->in(j) == dead) { // Turn all dead inputs into TOP
    1.34 +            Node* in = use->in(j);
    1.35 +            if (in == dead) {         // Turn all dead inputs into TOP
    1.36                use->set_req(j, top);
    1.37 +            } else if (in != NULL && !in->is_top()) {
    1.38 +              dead_use = false;
    1.39              }
    1.40            }
    1.41 -          igvn->_worklist.push(use);
    1.42 +          if (dead_use) {
    1.43 +            if (use->is_Region()) {
    1.44 +              use->set_req(0, top);   // Cut self edge
    1.45 +            }
    1.46 +            nstack.push(use);
    1.47 +          } else {
    1.48 +            igvn->_worklist.push(use);
    1.49 +          }
    1.50          }
    1.51          // Refresh the iterator, since any number of kills might have happened.
    1.52          k = dead->last_outs(kmin);

mercurial