1.1 --- a/src/share/vm/opto/node.cpp Thu Apr 10 15:49:29 2008 -0400 1.2 +++ b/src/share/vm/opto/node.cpp Tue Apr 15 10:49:32 2008 -0700 1.3 @@ -1017,6 +1017,101 @@ 1.4 return false; 1.5 }; 1.6 1.7 +//--------------------------find_exact_control--------------------------------- 1.8 +// Skip Proj and CatchProj nodes chains. Check for Null and Top. 1.9 +Node* Node::find_exact_control(Node* ctrl) { 1.10 + if (ctrl == NULL && this->is_Region()) 1.11 + ctrl = this->as_Region()->is_copy(); 1.12 + 1.13 + if (ctrl != NULL && ctrl->is_CatchProj()) { 1.14 + if (ctrl->as_CatchProj()->_con == CatchProjNode::fall_through_index) 1.15 + ctrl = ctrl->in(0); 1.16 + if (ctrl != NULL && !ctrl->is_top()) 1.17 + ctrl = ctrl->in(0); 1.18 + } 1.19 + 1.20 + if (ctrl != NULL && ctrl->is_Proj()) 1.21 + ctrl = ctrl->in(0); 1.22 + 1.23 + return ctrl; 1.24 +} 1.25 + 1.26 +//--------------------------dominates------------------------------------------ 1.27 +// Helper function for MemNode::all_controls_dominate(). 1.28 +// Check if 'this' control node dominates or equal to 'sub' control node. 1.29 +bool Node::dominates(Node* sub, Node_List &nlist) { 1.30 + assert(this->is_CFG(), "expecting control"); 1.31 + assert(sub != NULL && sub->is_CFG(), "expecting control"); 1.32 + 1.33 + Node* orig_sub = sub; 1.34 + nlist.clear(); 1.35 + bool this_dominates = false; 1.36 + uint region_input = 0; 1.37 + while (sub != NULL) { // walk 'sub' up the chain to 'this' 1.38 + if (sub == this) { 1.39 + if (nlist.size() == 0) { 1.40 + // No Region nodes except loops were visited before and the EntryControl 1.41 + // path was taken for loops: it did not walk in a cycle. 1.42 + return true; 1.43 + } else if (!this_dominates) { 1.44 + // Region nodes were visited. Continue walk up to Start or Root 1.45 + // to make sure that it did not walk in a cycle. 1.46 + this_dominates = true; // first time meet 1.47 + } else { 1.48 + return false; // already met before: walk in a cycle 1.49 + } 1.50 + } 1.51 + if (sub->is_Start() || sub->is_Root()) 1.52 + return this_dominates; 1.53 + 1.54 + Node* up = sub->find_exact_control(sub->in(0)); 1.55 + if (up == NULL || up->is_top()) 1.56 + return false; // Conservative answer for dead code 1.57 + 1.58 + if (sub == up && sub->is_Loop()) { 1.59 + up = sub->in(0); // in(LoopNode::EntryControl); 1.60 + } else if (sub == up && sub->is_Region()) { 1.61 + uint i = 1; 1.62 + if (nlist.size() == 0) { 1.63 + // No Region nodes (except Loops) were visited before. 1.64 + // Take first valid path on the way up to 'this'. 1.65 + } else if (nlist.at(nlist.size() - 1) == sub) { 1.66 + // This Region node was just visited. Take other path. 1.67 + i = region_input + 1; 1.68 + nlist.pop(); 1.69 + } else { 1.70 + // Was this Region node visited before? 1.71 + uint size = nlist.size(); 1.72 + for (uint j = 0; j < size; j++) { 1.73 + if (nlist.at(j) == sub) { 1.74 + return false; // The Region node was visited before. Give up. 1.75 + } 1.76 + } 1.77 + // The Region node was not visited before. 1.78 + // Take first valid path on the way up to 'this'. 1.79 + } 1.80 + for (; i < sub->req(); i++) { 1.81 + Node* in = sub->in(i); 1.82 + if (in != NULL && !in->is_top() && in != sub) { 1.83 + break; 1.84 + } 1.85 + } 1.86 + if (i < sub->req()) { 1.87 + nlist.push(sub); 1.88 + up = sub->in(i); 1.89 + region_input = i; 1.90 + } 1.91 + } 1.92 + if (sub == up) 1.93 + return false; // some kind of tight cycle 1.94 + if (orig_sub == up) 1.95 + return false; // walk in a cycle 1.96 + 1.97 + sub = up; 1.98 + } 1.99 + return false; 1.100 +} 1.101 + 1.102 //------------------------------remove_dead_region----------------------------- 1.103 // This control node is dead. Follow the subgraph below it making everything 1.104 // using it dead as well. This will happen normally via the usual IterGVN