1.1 --- a/src/share/vm/opto/node.cpp Tue May 20 06:32:58 2008 -0700 1.2 +++ b/src/share/vm/opto/node.cpp Wed May 21 10:45:07 2008 -0700 1.3 @@ -1049,51 +1049,80 @@ 1.4 Node* orig_sub = sub; 1.5 nlist.clear(); 1.6 bool this_dominates = false; 1.7 - uint region_input = 0; 1.8 + bool result = false; // Conservative answer 1.9 + 1.10 while (sub != NULL) { // walk 'sub' up the chain to 'this' 1.11 if (sub == this) { 1.12 if (nlist.size() == 0) { 1.13 // No Region nodes except loops were visited before and the EntryControl 1.14 // path was taken for loops: it did not walk in a cycle. 1.15 - return true; 1.16 - } else if (!this_dominates) { 1.17 + result = true; 1.18 + break; 1.19 + } else if (this_dominates) { 1.20 + result = false; // already met before: walk in a cycle 1.21 + break; 1.22 + } else { 1.23 // Region nodes were visited. Continue walk up to Start or Root 1.24 // to make sure that it did not walk in a cycle. 1.25 this_dominates = true; // first time meet 1.26 iterations_without_region_limit = DominatorSearchLimit; // Reset 1.27 - } else { 1.28 - return false; // already met before: walk in a cycle 1.29 - } 1.30 + } 1.31 } 1.32 - if (sub->is_Start() || sub->is_Root()) 1.33 - return this_dominates; 1.34 + if (sub->is_Start() || sub->is_Root()) { 1.35 + result = this_dominates; 1.36 + break; 1.37 + } 1.38 + Node* up = sub->find_exact_control(sub->in(0)); 1.39 + if (up == NULL || up->is_top()) { 1.40 + result = false; // Conservative answer for dead code 1.41 + break; 1.42 + } 1.43 + if (sub == up && (sub->is_Loop() || sub->is_Region() && sub->req() != 3)) { 1.44 + // Take first valid path on the way up to 'this'. 1.45 + up = sub->in(1); // in(LoopNode::EntryControl); 1.46 + } else if (sub == up && sub->is_Region()) { 1.47 + assert(sub->req() == 3, "sanity"); 1.48 + iterations_without_region_limit = DominatorSearchLimit; // Reset 1.49 1.50 - Node* up = sub->find_exact_control(sub->in(0)); 1.51 - if (up == NULL || up->is_top()) 1.52 - return false; // Conservative answer for dead code 1.53 - 1.54 - if (sub == up && sub->is_Loop()) { 1.55 - up = sub->in(1); // in(LoopNode::EntryControl); 1.56 - } else if (sub == up && sub->is_Region() && sub->req() == 3) { 1.57 - iterations_without_region_limit = DominatorSearchLimit; // Reset 1.58 + // Try both paths for such Regions. 1.59 + // It is not accurate without regions dominating information. 1.60 + // With such information the other path should be checked for 1.61 + // the most dominating Region which was visited before. 1.62 + bool region_was_visited_before = false; 1.63 uint i = 1; 1.64 uint size = nlist.size(); 1.65 if (size == 0) { 1.66 - // No Region nodes (except Loops) were visited before. 1.67 + // No such Region nodes were visited before. 1.68 // Take first valid path on the way up to 'this'. 1.69 - } else if (nlist.at(size - 1) == sub) { 1.70 - // This Region node was just visited. Take other path. 1.71 - i = region_input + 1; 1.72 - nlist.pop(); 1.73 } else { 1.74 // Was this Region node visited before? 1.75 - for (uint j = 0; j < size; j++) { 1.76 - if (nlist.at(j) == sub) { 1.77 - return false; // The Region node was visited before. Give up. 1.78 + intptr_t ni; 1.79 + int j = size - 1; 1.80 + for (; j >= 0; j--) { 1.81 + ni = (intptr_t)nlist.at(j); 1.82 + if ((Node*)(ni & ~1) == sub) { 1.83 + if ((ni & 1) != 0) { 1.84 + break; // Visited 2 paths. Give up. 1.85 + } else { 1.86 + // The Region node was visited before only once. 1.87 + nlist.remove(j); 1.88 + region_was_visited_before = true; 1.89 + for (; i < sub->req(); i++) { 1.90 + Node* in = sub->in(i); 1.91 + if (in != NULL && !in->is_top() && in != sub) { 1.92 + break; 1.93 + } 1.94 + } 1.95 + i++; // Take other path. 1.96 + break; 1.97 + } 1.98 } 1.99 } 1.100 + if (j >= 0 && (ni & 1) != 0) { 1.101 + result = false; // Visited 2 paths. Give up. 1.102 + break; 1.103 + } 1.104 // The Region node was not visited before. 1.105 - // Take first valid path on the way up to 'this'. 1.106 } 1.107 for (; i < sub->req(); i++) { 1.108 Node* in = sub->in(i); 1.109 @@ -1102,20 +1131,26 @@ 1.110 } 1.111 } 1.112 if (i < sub->req()) { 1.113 - nlist.push(sub); 1.114 up = sub->in(i); 1.115 - region_input = i; 1.116 + if (region_was_visited_before && sub != up) { 1.117 + // Set 0 bit to indicate that both paths were taken. 1.118 + nlist.push((Node*)((intptr_t)sub + 1)); 1.119 + } else { 1.120 + nlist.push(sub); 1.121 + } 1.122 } 1.123 } 1.124 - if (sub == up) 1.125 - return false; // some kind of tight cycle 1.126 - 1.127 - if (--iterations_without_region_limit < 0) 1.128 - return false; // dead cycle 1.129 - 1.130 + if (sub == up) { 1.131 + result = false; // some kind of tight cycle 1.132 + break; 1.133 + } 1.134 + if (--iterations_without_region_limit < 0) { 1.135 + result = false; // dead cycle 1.136 + break; 1.137 + } 1.138 sub = up; 1.139 } 1.140 - return false; 1.141 + return result; 1.142 } 1.143 1.144 //------------------------------remove_dead_region-----------------------------