src/share/vm/opto/node.cpp

changeset 520
f3b3fe64f59f
parent 500
99269dbf4ba8
child 557
ec73d88d5b43
     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

mercurial