src/share/vm/opto/node.cpp

changeset 598
885ed790ecf0
parent 590
723be81c1212
child 628
44a553b2809d
     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-----------------------------

mercurial