src/share/vm/opto/escape.cpp

changeset 1989
60a14ad85270
parent 1907
c18cbe5936b8
child 2170
5867d89c129b
     1.1 --- a/src/share/vm/opto/escape.cpp	Fri Jul 02 15:01:47 2010 -0700
     1.2 +++ b/src/share/vm/opto/escape.cpp	Fri Jul 02 17:30:30 2010 -0700
     1.3 @@ -81,18 +81,18 @@
     1.4  }
     1.5  #endif
     1.6  
     1.7 -ConnectionGraph::ConnectionGraph(Compile * C) :
     1.8 +ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
     1.9    _nodes(C->comp_arena(), C->unique(), C->unique(), PointsToNode()),
    1.10    _processed(C->comp_arena()),
    1.11    _collecting(true),
    1.12    _compile(C),
    1.13 +  _igvn(igvn),
    1.14    _node_map(C->comp_arena()) {
    1.15  
    1.16    _phantom_object = C->top()->_idx,
    1.17    add_node(C->top(), PointsToNode::JavaObject, PointsToNode::GlobalEscape,true);
    1.18  
    1.19    // Add ConP(#NULL) and ConN(#NULL) nodes.
    1.20 -  PhaseGVN* igvn = C->initial_gvn();
    1.21    Node* oop_null = igvn->zerocon(T_OBJECT);
    1.22    _oop_null = oop_null->_idx;
    1.23    assert(_oop_null < C->unique(), "should be created already");
    1.24 @@ -182,7 +182,7 @@
    1.25      _processed.set(n->_idx);
    1.26  }
    1.27  
    1.28 -PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n, PhaseTransform *phase) {
    1.29 +PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n) {
    1.30    uint idx = n->_idx;
    1.31    PointsToNode::EscapeState es;
    1.32  
    1.33 @@ -207,22 +207,26 @@
    1.34    if (n->uncast()->_idx >= nodes_size())
    1.35      return PointsToNode::UnknownEscape;
    1.36  
    1.37 +  PointsToNode::EscapeState orig_es = es;
    1.38 +
    1.39    // compute max escape state of anything this node could point to
    1.40    VectorSet ptset(Thread::current()->resource_area());
    1.41 -  PointsTo(ptset, n, phase);
    1.42 +  PointsTo(ptset, n);
    1.43    for(VectorSetI i(&ptset); i.test() && es != PointsToNode::GlobalEscape; ++i) {
    1.44      uint pt = i.elem;
    1.45      PointsToNode::EscapeState pes = ptnode_adr(pt)->escape_state();
    1.46      if (pes > es)
    1.47        es = pes;
    1.48    }
    1.49 -  // cache the computed escape state
    1.50 -  assert(es != PointsToNode::UnknownEscape, "should have computed an escape state");
    1.51 -  ptnode_adr(idx)->set_escape_state(es);
    1.52 +  if (orig_es != es) {
    1.53 +    // cache the computed escape state
    1.54 +    assert(es != PointsToNode::UnknownEscape, "should have computed an escape state");
    1.55 +    ptnode_adr(idx)->set_escape_state(es);
    1.56 +  } // orig_es could be PointsToNode::UnknownEscape
    1.57    return es;
    1.58  }
    1.59  
    1.60 -void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase) {
    1.61 +void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n) {
    1.62    VectorSet visited(Thread::current()->resource_area());
    1.63    GrowableArray<uint>  worklist;
    1.64  
    1.65 @@ -990,7 +994,7 @@
    1.66    GrowableArray<Node *>  memnode_worklist;
    1.67    GrowableArray<PhiNode *>  orig_phis;
    1.68  
    1.69 -  PhaseGVN  *igvn = _compile->initial_gvn();
    1.70 +  PhaseGVN  *igvn = _igvn;
    1.71    uint new_index_start = (uint) _compile->num_alias_types();
    1.72    Arena* arena = Thread::current()->resource_area();
    1.73    VectorSet visited(arena);
    1.74 @@ -1012,7 +1016,7 @@
    1.75        CallNode *alloc = n->as_Call();
    1.76        // copy escape information to call node
    1.77        PointsToNode* ptn = ptnode_adr(alloc->_idx);
    1.78 -      PointsToNode::EscapeState es = escape_state(alloc, igvn);
    1.79 +      PointsToNode::EscapeState es = escape_state(alloc);
    1.80        // We have an allocation or call which returns a Java object,
    1.81        // see if it is unescaped.
    1.82        if (es != PointsToNode::NoEscape || !ptn->_scalar_replaceable)
    1.83 @@ -1123,7 +1127,7 @@
    1.84        }
    1.85      } else if (n->is_AddP()) {
    1.86        ptset.Clear();
    1.87 -      PointsTo(ptset, get_addp_base(n), igvn);
    1.88 +      PointsTo(ptset, get_addp_base(n));
    1.89        assert(ptset.Size() == 1, "AddP address is unique");
    1.90        uint elem = ptset.getelem(); // Allocation node's index
    1.91        if (elem == _phantom_object) {
    1.92 @@ -1143,7 +1147,7 @@
    1.93          continue;  // already processed
    1.94        }
    1.95        ptset.Clear();
    1.96 -      PointsTo(ptset, n, igvn);
    1.97 +      PointsTo(ptset, n);
    1.98        if (ptset.Size() == 1) {
    1.99          uint elem = ptset.getelem(); // Allocation node's index
   1.100          if (elem == _phantom_object) {
   1.101 @@ -1478,6 +1482,26 @@
   1.102    return false;
   1.103  }
   1.104  
   1.105 +void ConnectionGraph::do_analysis(Compile *C, PhaseIterGVN *igvn) {
   1.106 +  // Add ConP#NULL and ConN#NULL nodes before ConnectionGraph construction
   1.107 +  // to create space for them in ConnectionGraph::_nodes[].
   1.108 +  Node* oop_null = igvn->zerocon(T_OBJECT);
   1.109 +  Node* noop_null = igvn->zerocon(T_NARROWOOP);
   1.110 +
   1.111 +  ConnectionGraph* congraph = new(C->comp_arena()) ConnectionGraph(C, igvn);
   1.112 +  // Perform escape analysis
   1.113 +  if (congraph->compute_escape()) {
   1.114 +    // There are non escaping objects.
   1.115 +    C->set_congraph(congraph);
   1.116 +  }
   1.117 +
   1.118 +  // Cleanup.
   1.119 +  if (oop_null->outcnt() == 0)
   1.120 +    igvn->hash_delete(oop_null);
   1.121 +  if (noop_null->outcnt() == 0)
   1.122 +    igvn->hash_delete(noop_null);
   1.123 +}
   1.124 +
   1.125  bool ConnectionGraph::compute_escape() {
   1.126    Compile* C = _compile;
   1.127  
   1.128 @@ -1492,7 +1516,7 @@
   1.129    }
   1.130  
   1.131    GrowableArray<int> cg_worklist;
   1.132 -  PhaseGVN* igvn = C->initial_gvn();
   1.133 +  PhaseGVN* igvn = _igvn;
   1.134    bool has_allocations = false;
   1.135  
   1.136    // Push all useful nodes onto CG list and set their type.
   1.137 @@ -1661,6 +1685,12 @@
   1.138    _collecting = false;
   1.139    assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build");
   1.140  
   1.141 +#ifndef PRODUCT
   1.142 +  if (PrintEscapeAnalysis) {
   1.143 +    dump(); // Dump ConnectionGraph
   1.144 +  }
   1.145 +#endif
   1.146 +
   1.147    bool has_scalar_replaceable_candidates = alloc_worklist.length() > 0;
   1.148    if ( has_scalar_replaceable_candidates &&
   1.149         C->AliasLevel() >= 3 && EliminateAllocations ) {
   1.150 @@ -1671,10 +1701,6 @@
   1.151  
   1.152      if (C->failing())  return false;
   1.153  
   1.154 -    // Clean up after split unique types.
   1.155 -    ResourceMark rm;
   1.156 -    PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn());
   1.157 -
   1.158      C->print_method("After Escape Analysis", 2);
   1.159  
   1.160  #ifdef ASSERT
   1.161 @@ -1711,7 +1737,7 @@
   1.162    int offset = ptn->offset();
   1.163    Node* base = get_addp_base(n);
   1.164    ptset.Clear();
   1.165 -  PointsTo(ptset, base, phase);
   1.166 +  PointsTo(ptset, base);
   1.167    int ptset_size = ptset.Size();
   1.168  
   1.169    // Check if a oop field's initializing value is recorded and add
   1.170 @@ -1889,7 +1915,7 @@
   1.171              arg = get_addp_base(arg);
   1.172            }
   1.173            ptset.Clear();
   1.174 -          PointsTo(ptset, arg, phase);
   1.175 +          PointsTo(ptset, arg);
   1.176            for( VectorSetI j(&ptset); j.test(); ++j ) {
   1.177              uint pt = j.elem;
   1.178              set_escape_state(pt, PointsToNode::ArgEscape);
   1.179 @@ -1934,7 +1960,7 @@
   1.180              }
   1.181  
   1.182              ptset.Clear();
   1.183 -            PointsTo(ptset, arg, phase);
   1.184 +            PointsTo(ptset, arg);
   1.185              for( VectorSetI j(&ptset); j.test(); ++j ) {
   1.186                uint pt = j.elem;
   1.187                if (global_escapes) {
   1.188 @@ -1970,7 +1996,7 @@
   1.189            Node *arg = call->in(i)->uncast();
   1.190            set_escape_state(arg->_idx, PointsToNode::GlobalEscape);
   1.191            ptset.Clear();
   1.192 -          PointsTo(ptset, arg, phase);
   1.193 +          PointsTo(ptset, arg);
   1.194            for( VectorSetI j(&ptset); j.test(); ++j ) {
   1.195              uint pt = j.elem;
   1.196              set_escape_state(pt, PointsToNode::GlobalEscape);
   1.197 @@ -2433,7 +2459,7 @@
   1.198        Node *base = get_addp_base(n);
   1.199        // Create a field edge to this node from everything base could point to.
   1.200        VectorSet ptset(Thread::current()->resource_area());
   1.201 -      PointsTo(ptset, base, phase);
   1.202 +      PointsTo(ptset, base);
   1.203        for( VectorSetI i(&ptset); i.test(); ++i ) {
   1.204          uint pt = i.elem;
   1.205          add_field_edge(pt, n_idx, address_offset(n, phase));
   1.206 @@ -2501,7 +2527,7 @@
   1.207        // For everything "adr_base" could point to, create a deferred edge from
   1.208        // this node to each field with the same offset.
   1.209        VectorSet ptset(Thread::current()->resource_area());
   1.210 -      PointsTo(ptset, adr_base, phase);
   1.211 +      PointsTo(ptset, adr_base);
   1.212        int offset = address_offset(adr, phase);
   1.213        for( VectorSetI i(&ptset); i.test(); ++i ) {
   1.214          uint pt = i.elem;
   1.215 @@ -2594,7 +2620,7 @@
   1.216        // For everything "adr_base" could point to, create a deferred edge
   1.217        // to "val" from each field with the same offset.
   1.218        VectorSet ptset(Thread::current()->resource_area());
   1.219 -      PointsTo(ptset, adr_base, phase);
   1.220 +      PointsTo(ptset, adr_base);
   1.221        for( VectorSetI i(&ptset); i.test(); ++i ) {
   1.222          uint pt = i.elem;
   1.223          add_edge_from_fields(pt, val->_idx, address_offset(adr, phase));
   1.224 @@ -2638,7 +2664,6 @@
   1.225  
   1.226  #ifndef PRODUCT
   1.227  void ConnectionGraph::dump() {
   1.228 -  PhaseGVN  *igvn = _compile->initial_gvn();
   1.229    bool first = true;
   1.230  
   1.231    uint size = nodes_size();
   1.232 @@ -2648,7 +2673,7 @@
   1.233  
   1.234      if (ptn_type != PointsToNode::JavaObject || ptn->_node == NULL)
   1.235        continue;
   1.236 -    PointsToNode::EscapeState es = escape_state(ptn->_node, igvn);
   1.237 +    PointsToNode::EscapeState es = escape_state(ptn->_node);
   1.238      if (ptn->_node->is_Allocate() && (es == PointsToNode::NoEscape || Verbose)) {
   1.239        if (first) {
   1.240          tty->cr();

mercurial