src/share/vm/opto/cfgnode.cpp

changeset 4409
d092d1b31229
parent 4357
ad5dd04754ee
child 4944
886d1fd67dc3
     1.1 --- a/src/share/vm/opto/cfgnode.cpp	Fri Dec 21 10:27:49 2012 -0800
     1.2 +++ b/src/share/vm/opto/cfgnode.cpp	Sun Dec 23 17:08:22 2012 +0100
     1.3 @@ -363,6 +363,49 @@
     1.4    return true; // The Region node is unreachable - it is dead.
     1.5  }
     1.6  
     1.7 +bool RegionNode::try_clean_mem_phi(PhaseGVN *phase) {
     1.8 +  // Incremental inlining + PhaseStringOpts sometimes produce:
     1.9 +  //
    1.10 +  // cmpP with 1 top input
    1.11 +  //           |
    1.12 +  //          If
    1.13 +  //         /  \
    1.14 +  //   IfFalse  IfTrue  /- Some Node
    1.15 +  //         \  /      /    /
    1.16 +  //        Region    / /-MergeMem
    1.17 +  //             \---Phi
    1.18 +  //
    1.19 +  //
    1.20 +  // It's expected by PhaseStringOpts that the Region goes away and is
    1.21 +  // replaced by If's control input but because there's still a Phi,
    1.22 +  // the Region stays in the graph. The top input from the cmpP is
    1.23 +  // propagated forward and a subgraph that is useful goes away. The
    1.24 +  // code below replaces the Phi with the MergeMem so that the Region
    1.25 +  // is simplified.
    1.26 +
    1.27 +  PhiNode* phi = has_unique_phi();
    1.28 +  if (phi && phi->type() == Type::MEMORY && req() == 3 && phi->is_diamond_phi(true)) {
    1.29 +    MergeMemNode* m = NULL;
    1.30 +    assert(phi->req() == 3, "same as region");
    1.31 +    for (uint i = 1; i < 3; ++i) {
    1.32 +      Node *mem = phi->in(i);
    1.33 +      if (mem && mem->is_MergeMem() && in(i)->outcnt() == 1) {
    1.34 +        // Nothing is control-dependent on path #i except the region itself.
    1.35 +        m = mem->as_MergeMem();
    1.36 +        uint j = 3 - i;
    1.37 +        Node* other = phi->in(j);
    1.38 +        if (other && other == m->base_memory()) {
    1.39 +          // m is a successor memory to other, and is not pinned inside the diamond, so push it out.
    1.40 +          // This will allow the diamond to collapse completely.
    1.41 +          phase->is_IterGVN()->replace_node(phi, m);
    1.42 +          return true;
    1.43 +        }
    1.44 +      }
    1.45 +    }
    1.46 +  }
    1.47 +  return false;
    1.48 +}
    1.49 +
    1.50  //------------------------------Ideal------------------------------------------
    1.51  // Return a node which is more "ideal" than the current node.  Must preserve
    1.52  // the CFG, but we can still strip out dead paths.
    1.53 @@ -375,6 +418,10 @@
    1.54    bool has_phis = false;
    1.55    if (can_reshape) {            // Need DU info to check for Phi users
    1.56      has_phis = (has_phi() != NULL);       // Cache result
    1.57 +    if (has_phis && try_clean_mem_phi(phase)) {
    1.58 +      has_phis = false;
    1.59 +    }
    1.60 +
    1.61      if (!has_phis) {            // No Phi users?  Nothing merging?
    1.62        for (uint i = 1; i < req()-1; i++) {
    1.63          Node *if1 = in(i);
    1.64 @@ -1005,7 +1052,9 @@
    1.65  //------------------------------is_diamond_phi---------------------------------
    1.66  // Does this Phi represent a simple well-shaped diamond merge?  Return the
    1.67  // index of the true path or 0 otherwise.
    1.68 -int PhiNode::is_diamond_phi() const {
    1.69 +// If check_control_only is true, do not inspect the If node at the
    1.70 +// top, and return -1 (not an edge number) on success.
    1.71 +int PhiNode::is_diamond_phi(bool check_control_only) const {
    1.72    // Check for a 2-path merge
    1.73    Node *region = in(0);
    1.74    if( !region ) return 0;
    1.75 @@ -1018,6 +1067,7 @@
    1.76    Node *iff = ifp1->in(0);
    1.77    if( !iff || !iff->is_If() ) return 0;
    1.78    if( iff != ifp2->in(0) ) return 0;
    1.79 +  if (check_control_only)  return -1;
    1.80    // Check for a proper bool/cmp
    1.81    const Node *b = iff->in(1);
    1.82    if( !b->is_Bool() ) return 0;

mercurial