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);