6890673: Eliminate allocations immediately after EA

Wed, 16 Nov 2011 09:13:57 -0800

author
kvn
date
Wed, 16 Nov 2011 09:13:57 -0800
changeset 3311
1bd45abaa507
parent 3310
6729bbc1fcd6
child 3312
973293defacd

6890673: Eliminate allocations immediately after EA
Summary: Try to eliminate allocations and related locks immediately after escape analysis.
Reviewed-by: never

src/share/vm/opto/block.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/callnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/callnode.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/compile.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/escape.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/gcm.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/loopnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/macro.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/macro.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/memnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/memnode.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/block.cpp	Wed Nov 16 01:39:50 2011 -0800
     1.2 +++ b/src/share/vm/opto/block.cpp	Wed Nov 16 09:13:57 2011 -0800
     1.3 @@ -898,45 +898,41 @@
     1.4  void PhaseCFG::verify( ) const {
     1.5  #ifdef ASSERT
     1.6    // Verify sane CFG
     1.7 -  for( uint i = 0; i < _num_blocks; i++ ) {
     1.8 +  for (uint i = 0; i < _num_blocks; i++) {
     1.9      Block *b = _blocks[i];
    1.10      uint cnt = b->_nodes.size();
    1.11      uint j;
    1.12 -    for( j = 0; j < cnt; j++ ) {
    1.13 +    for (j = 0; j < cnt; j++)  {
    1.14        Node *n = b->_nodes[j];
    1.15        assert( _bbs[n->_idx] == b, "" );
    1.16 -      if( j >= 1 && n->is_Mach() &&
    1.17 -          n->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
    1.18 -        assert( j == 1 || b->_nodes[j-1]->is_Phi(),
    1.19 -                "CreateEx must be first instruction in block" );
    1.20 +      if (j >= 1 && n->is_Mach() &&
    1.21 +          n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
    1.22 +        assert(j == 1 || b->_nodes[j-1]->is_Phi(),
    1.23 +               "CreateEx must be first instruction in block");
    1.24        }
    1.25 -      for( uint k = 0; k < n->req(); k++ ) {
    1.26 +      for (uint k = 0; k < n->req(); k++) {
    1.27          Node *def = n->in(k);
    1.28 -        if( def && def != n ) {
    1.29 -          assert( _bbs[def->_idx] || def->is_Con(),
    1.30 -                  "must have block; constants for debug info ok" );
    1.31 +        if (def && def != n) {
    1.32 +          assert(_bbs[def->_idx] || def->is_Con(),
    1.33 +                 "must have block; constants for debug info ok");
    1.34            // Verify that instructions in the block is in correct order.
    1.35            // Uses must follow their definition if they are at the same block.
    1.36            // Mostly done to check that MachSpillCopy nodes are placed correctly
    1.37            // when CreateEx node is moved in build_ifg_physical().
    1.38 -          if( _bbs[def->_idx] == b &&
    1.39 +          if (_bbs[def->_idx] == b &&
    1.40                !(b->head()->is_Loop() && n->is_Phi()) &&
    1.41                // See (+++) comment in reg_split.cpp
    1.42 -              !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) {
    1.43 +              !(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) {
    1.44              bool is_loop = false;
    1.45              if (n->is_Phi()) {
    1.46 -              for( uint l = 1; l < def->req(); l++ ) {
    1.47 +              for (uint l = 1; l < def->req(); l++) {
    1.48                  if (n == def->in(l)) {
    1.49                    is_loop = true;
    1.50                    break; // Some kind of loop
    1.51                  }
    1.52                }
    1.53              }
    1.54 -            assert( is_loop || b->find_node(def) < j, "uses must follow definitions" );
    1.55 -          }
    1.56 -          if( def->is_SafePointScalarObject() ) {
    1.57 -            assert(_bbs[def->_idx] == b, "SafePointScalarObject Node should be at the same block as its SafePoint node");
    1.58 -            assert(_bbs[def->_idx] == _bbs[def->in(0)->_idx], "SafePointScalarObject Node should be at the same block as its control edge");
    1.59 +            assert(is_loop || b->find_node(def) < j, "uses must follow definitions");
    1.60            }
    1.61          }
    1.62        }
    1.63 @@ -946,12 +942,11 @@
    1.64      Node *bp = (Node*)b->_nodes[b->_nodes.size()-1]->is_block_proj();
    1.65      assert( bp, "last instruction must be a block proj" );
    1.66      assert( bp == b->_nodes[j], "wrong number of successors for this block" );
    1.67 -    if( bp->is_Catch() ) {
    1.68 -      while( b->_nodes[--j]->is_MachProj() ) ;
    1.69 -      assert( b->_nodes[j]->is_MachCall(), "CatchProj must follow call" );
    1.70 -    }
    1.71 -    else if( bp->is_Mach() && bp->as_Mach()->ideal_Opcode() == Op_If ) {
    1.72 -      assert( b->_num_succs == 2, "Conditional branch must have two targets");
    1.73 +    if (bp->is_Catch()) {
    1.74 +      while (b->_nodes[--j]->is_MachProj()) ;
    1.75 +      assert(b->_nodes[j]->is_MachCall(), "CatchProj must follow call");
    1.76 +    } else if (bp->is_Mach() && bp->as_Mach()->ideal_Opcode() == Op_If) {
    1.77 +      assert(b->_num_succs == 2, "Conditional branch must have two targets");
    1.78      }
    1.79    }
    1.80  #endif
     2.1 --- a/src/share/vm/opto/callnode.cpp	Wed Nov 16 01:39:50 2011 -0800
     2.2 +++ b/src/share/vm/opto/callnode.cpp	Wed Nov 16 09:13:57 2011 -0800
     2.3 @@ -1071,8 +1071,11 @@
     2.4    init_class_id(Class_SafePointScalarObject);
     2.5  }
     2.6  
     2.7 -bool SafePointScalarObjectNode::pinned() const { return true; }
     2.8 -bool SafePointScalarObjectNode::depends_only_on_test() const { return false; }
     2.9 +// Do not allow value-numbering for SafePointScalarObject node.
    2.10 +uint SafePointScalarObjectNode::hash() const { return NO_HASH; }
    2.11 +uint SafePointScalarObjectNode::cmp( const Node &n ) const {
    2.12 +  return (&n == this); // Always fail except on self
    2.13 +}
    2.14  
    2.15  uint SafePointScalarObjectNode::ideal_reg() const {
    2.16    return 0; // No matching to machine instruction
    2.17 @@ -1096,7 +1099,6 @@
    2.18    if (cached != NULL) {
    2.19      return (SafePointScalarObjectNode*)cached;
    2.20    }
    2.21 -  Compile* C = Compile::current();
    2.22    SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone();
    2.23    res->_first_index += jvms_adj;
    2.24    sosn_map->Insert((void*)this, (void*)res);
    2.25 @@ -1142,6 +1144,8 @@
    2.26  
    2.27  Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
    2.28    if (remove_dead_region(phase, can_reshape))  return this;
    2.29 +  // Don't bother trying to transform a dead node
    2.30 +  if (in(0) && in(0)->is_top())  return NULL;
    2.31  
    2.32    const Type* type = phase->type(Ideal_length());
    2.33    if (type->isa_int() && type->is_int()->_hi < 0) {
    2.34 @@ -1522,13 +1526,16 @@
    2.35  
    2.36    // perform any generic optimizations first (returns 'this' or NULL)
    2.37    Node *result = SafePointNode::Ideal(phase, can_reshape);
    2.38 +  if (result != NULL)  return result;
    2.39 +  // Don't bother trying to transform a dead node
    2.40 +  if (in(0) && in(0)->is_top())  return NULL;
    2.41  
    2.42    // Now see if we can optimize away this lock.  We don't actually
    2.43    // remove the locking here, we simply set the _eliminate flag which
    2.44    // prevents macro expansion from expanding the lock.  Since we don't
    2.45    // modify the graph, the value returned from this function is the
    2.46    // one computed above.
    2.47 -  if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) {
    2.48 +  if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
    2.49      //
    2.50      // If we are locking an unescaped object, the lock/unlock is unnecessary
    2.51      //
    2.52 @@ -1537,8 +1544,16 @@
    2.53      if (cgr != NULL)
    2.54        es = cgr->escape_state(obj_node());
    2.55      if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
    2.56 -      // Mark it eliminated to update any counters
    2.57 -      this->set_eliminated();
    2.58 +      if (!is_eliminated()) {
    2.59 +        // Mark it eliminated to update any counters
    2.60 +        this->set_eliminated();
    2.61 +      } else {
    2.62 +        assert(is_coarsened(), "sanity");
    2.63 +        // The lock could be marked eliminated by lock coarsening
    2.64 +        // code during first IGVN before EA. Clear coarsened flag
    2.65 +        // to eliminate all associated locks/unlocks.
    2.66 +        this->clear_coarsened();
    2.67 +      }
    2.68        return result;
    2.69      }
    2.70  
    2.71 @@ -1546,7 +1561,7 @@
    2.72      // Try lock coarsening
    2.73      //
    2.74      PhaseIterGVN* iter = phase->is_IterGVN();
    2.75 -    if (iter != NULL) {
    2.76 +    if (iter != NULL && !is_eliminated()) {
    2.77  
    2.78        GrowableArray<AbstractLockNode*>   lock_ops;
    2.79  
    2.80 @@ -1602,7 +1617,7 @@
    2.81            lock->set_eliminated();
    2.82            lock->set_coarsened();
    2.83          }
    2.84 -      } else if (result != NULL && ctrl->is_Region() &&
    2.85 +      } else if (ctrl->is_Region() &&
    2.86                   iter->_worklist.member(ctrl)) {
    2.87          // We weren't able to find any opportunities but the region this
    2.88          // lock is control dependent on hasn't been processed yet so put
    2.89 @@ -1623,7 +1638,10 @@
    2.90  Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
    2.91  
    2.92    // perform any generic optimizations first (returns 'this' or NULL)
    2.93 -  Node * result = SafePointNode::Ideal(phase, can_reshape);
    2.94 +  Node *result = SafePointNode::Ideal(phase, can_reshape);
    2.95 +  if (result != NULL)  return result;
    2.96 +  // Don't bother trying to transform a dead node
    2.97 +  if (in(0) && in(0)->is_top())  return NULL;
    2.98  
    2.99    // Now see if we can optimize away this unlock.  We don't actually
   2.100    // remove the unlocking here, we simply set the _eliminate flag which
   2.101 @@ -1631,7 +1649,7 @@
   2.102    // modify the graph, the value returned from this function is the
   2.103    // one computed above.
   2.104    // Escape state is defined after Parse phase.
   2.105 -  if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) {
   2.106 +  if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
   2.107      //
   2.108      // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
   2.109      //
   2.110 @@ -1640,8 +1658,16 @@
   2.111      if (cgr != NULL)
   2.112        es = cgr->escape_state(obj_node());
   2.113      if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
   2.114 -      // Mark it eliminated to update any counters
   2.115 -      this->set_eliminated();
   2.116 +      if (!is_eliminated()) {
   2.117 +        // Mark it eliminated to update any counters
   2.118 +        this->set_eliminated();
   2.119 +      } else {
   2.120 +        assert(is_coarsened(), "sanity");
   2.121 +        // The lock could be marked eliminated by lock coarsening
   2.122 +        // code during first IGVN before EA. Clear coarsened flag
   2.123 +        // to eliminate all associated locks/unlocks.
   2.124 +        this->clear_coarsened();
   2.125 +      }
   2.126      }
   2.127    }
   2.128    return result;
     3.1 --- a/src/share/vm/opto/callnode.hpp	Wed Nov 16 01:39:50 2011 -0800
     3.2 +++ b/src/share/vm/opto/callnode.hpp	Wed Nov 16 09:13:57 2011 -0800
     3.3 @@ -440,6 +440,10 @@
     3.4                       // states of the scalarized object fields are collected.
     3.5    uint _n_fields;    // Number of non-static fields of the scalarized object.
     3.6    DEBUG_ONLY(AllocateNode* _alloc;)
     3.7 +
     3.8 +  virtual uint hash() const ; // { return NO_HASH; }
     3.9 +  virtual uint cmp( const Node &n ) const;
    3.10 +
    3.11  public:
    3.12    SafePointScalarObjectNode(const TypeOopPtr* tp,
    3.13  #ifdef ASSERT
    3.14 @@ -454,15 +458,10 @@
    3.15  
    3.16    uint first_index() const { return _first_index; }
    3.17    uint n_fields()    const { return _n_fields; }
    3.18 -  DEBUG_ONLY(AllocateNode* alloc() const { return _alloc; })
    3.19  
    3.20 -  // SafePointScalarObject should be always pinned to the control edge
    3.21 -  // of the SafePoint node for which it was generated.
    3.22 -  virtual bool pinned() const; // { return true; }
    3.23 -
    3.24 -  // SafePointScalarObject depends on the SafePoint node
    3.25 -  // for which it was generated.
    3.26 -  virtual bool depends_only_on_test() const; // { return false; }
    3.27 +#ifdef ASSERT
    3.28 +  AllocateNode* alloc() const { return _alloc; }
    3.29 +#endif
    3.30  
    3.31    virtual uint size_of() const { return sizeof(*this); }
    3.32  
    3.33 @@ -880,6 +879,7 @@
    3.34  
    3.35    bool is_coarsened()  { return _coarsened; }
    3.36    void set_coarsened() { _coarsened = true; }
    3.37 +  void clear_coarsened() { _coarsened = false; }
    3.38  
    3.39    // locking does not modify its arguments
    3.40    virtual bool        may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
     4.1 --- a/src/share/vm/opto/compile.cpp	Wed Nov 16 01:39:50 2011 -0800
     4.2 +++ b/src/share/vm/opto/compile.cpp	Wed Nov 16 09:13:57 2011 -0800
     4.3 @@ -1711,11 +1711,22 @@
     4.4  
     4.5      if (failing())  return;
     4.6  
     4.7 +    // Optimize out fields loads from scalar replaceable allocations.
     4.8      igvn.optimize();
     4.9      print_method("Iter GVN after EA", 2);
    4.10  
    4.11      if (failing())  return;
    4.12  
    4.13 +    if (congraph() != NULL && macro_count() > 0) {
    4.14 +      PhaseMacroExpand mexp(igvn);
    4.15 +      mexp.eliminate_macro_nodes();
    4.16 +      igvn.set_delay_transform(false);
    4.17 +
    4.18 +      igvn.optimize();
    4.19 +      print_method("Iter GVN after eliminating allocations and locks", 2);
    4.20 +
    4.21 +      if (failing())  return;
    4.22 +    }
    4.23    }
    4.24  
    4.25    // Loop transforms on the ideal graph.  Range Check Elimination,
     5.1 --- a/src/share/vm/opto/escape.cpp	Wed Nov 16 01:39:50 2011 -0800
     5.2 +++ b/src/share/vm/opto/escape.cpp	Wed Nov 16 09:13:57 2011 -0800
     5.3 @@ -1772,12 +1772,20 @@
     5.4        Node *n = C->macro_node(i);
     5.5        if (n->is_AbstractLock()) { // Lock and Unlock nodes
     5.6          AbstractLockNode* alock = n->as_AbstractLock();
     5.7 -        if (!alock->is_eliminated()) {
     5.8 +        if (!alock->is_eliminated() || alock->is_coarsened()) {
     5.9            PointsToNode::EscapeState es = escape_state(alock->obj_node());
    5.10            assert(es != PointsToNode::UnknownEscape, "should know");
    5.11            if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
    5.12 -            // Mark it eliminated
    5.13 -            alock->set_eliminated();
    5.14 +            if (!alock->is_eliminated()) {
    5.15 +              // Mark it eliminated to update any counters
    5.16 +              alock->set_eliminated();
    5.17 +            } else {
    5.18 +              // The lock could be marked eliminated by lock coarsening
    5.19 +              // code during first IGVN before EA. Clear coarsened flag
    5.20 +              // to eliminate all associated locks/unlocks and relock
    5.21 +              // during deoptimization.
    5.22 +              alock->clear_coarsened();
    5.23 +            }
    5.24            }
    5.25          }
    5.26        }
     6.1 --- a/src/share/vm/opto/gcm.cpp	Wed Nov 16 01:39:50 2011 -0800
     6.2 +++ b/src/share/vm/opto/gcm.cpp	Wed Nov 16 09:13:57 2011 -0800
     6.3 @@ -95,7 +95,7 @@
     6.4    assert(in0 != NULL, "Only control-dependent");
     6.5    const Node *p = in0->is_block_proj();
     6.6    if (p != NULL && p != n) {    // Control from a block projection?
     6.7 -    assert(!n->pinned() || n->is_MachConstantBase() || n->is_SafePointScalarObject(), "only pinned MachConstantBase or SafePointScalarObject node is expected here");
     6.8 +    assert(!n->pinned() || n->is_MachConstantBase(), "only pinned MachConstantBase node is expected here");
     6.9      // Find trailing Region
    6.10      Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block
    6.11      uint j = 0;
     7.1 --- a/src/share/vm/opto/loopnode.cpp	Wed Nov 16 01:39:50 2011 -0800
     7.2 +++ b/src/share/vm/opto/loopnode.cpp	Wed Nov 16 09:13:57 2011 -0800
     7.3 @@ -1946,7 +1946,7 @@
     7.4    }
     7.5  
     7.6    // Nothing to do, so get out
     7.7 -  if( !C->has_loops() && !do_split_ifs && !_verify_me && !_verify_only ) {
     7.8 +  if( !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only ) {
     7.9      _igvn.optimize();           // Cleanup NeverBranches
    7.10      return;
    7.11    }
     8.1 --- a/src/share/vm/opto/macro.cpp	Wed Nov 16 01:39:50 2011 -0800
     8.2 +++ b/src/share/vm/opto/macro.cpp	Wed Nov 16 09:13:57 2011 -0800
     8.3 @@ -81,7 +81,7 @@
     8.4        uint old_unique = C->unique();
     8.5        Node* new_in = old_sosn->clone(jvms_adj, sosn_map);
     8.6        if (old_unique != C->unique()) {
     8.7 -        new_in->set_req(0, newcall->in(0)); // reset control edge
     8.8 +        new_in->set_req(0, C->root()); // reset control edge
     8.9          new_in = transform_later(new_in); // Register new node.
    8.10        }
    8.11        old_in = new_in;
    8.12 @@ -565,7 +565,6 @@
    8.13    if (res == NULL) {
    8.14      // All users were eliminated.
    8.15    } else if (!res->is_CheckCastPP()) {
    8.16 -    alloc->_is_scalar_replaceable = false;  // don't try again
    8.17      NOT_PRODUCT(fail_eliminate = "Allocation does not have unique CheckCastPP";)
    8.18      can_eliminate = false;
    8.19    } else {
    8.20 @@ -719,7 +718,7 @@
    8.21                                                   alloc,
    8.22  #endif
    8.23                                                   first_ind, nfields);
    8.24 -    sobj->init_req(0, sfpt->in(TypeFunc::Control));
    8.25 +    sobj->init_req(0, C->root());
    8.26      transform_later(sobj);
    8.27  
    8.28      // Scan object's fields adding an input to the safepoint for each field.
    8.29 @@ -762,10 +761,10 @@
    8.30  
    8.31        Node *field_val = value_from_mem(mem, basic_elem_type, field_type, field_addr_type, alloc);
    8.32        if (field_val == NULL) {
    8.33 -        // we weren't able to find a value for this field,
    8.34 -        // give up on eliminating this allocation
    8.35 -        alloc->_is_scalar_replaceable = false;  // don't try again
    8.36 -        // remove any extra entries we added to the safepoint
    8.37 +        // We weren't able to find a value for this field,
    8.38 +        // give up on eliminating this allocation.
    8.39 +
    8.40 +        // Remove any extra entries we added to the safepoint.
    8.41          uint last = sfpt->req() - 1;
    8.42          for (int k = 0;  k < j; k++) {
    8.43            sfpt->del_req(last--);
    8.44 @@ -1804,9 +1803,9 @@
    8.45    #ifndef PRODUCT
    8.46    if (PrintEliminateLocks) {
    8.47      if (alock->is_Lock()) {
    8.48 -      tty->print_cr("++++ Eliminating: %d Lock", alock->_idx);
    8.49 +      tty->print_cr("++++ Eliminated: %d Lock", alock->_idx);
    8.50      } else {
    8.51 -      tty->print_cr("++++ Eliminating: %d Unlock", alock->_idx);
    8.52 +      tty->print_cr("++++ Eliminated: %d Unlock", alock->_idx);
    8.53      }
    8.54    }
    8.55    #endif
    8.56 @@ -2165,11 +2164,12 @@
    8.57    _igvn.replace_node(_memproj_fallthrough, mem_phi);
    8.58  }
    8.59  
    8.60 -//------------------------------expand_macro_nodes----------------------
    8.61 -//  Returns true if a failure occurred.
    8.62 -bool PhaseMacroExpand::expand_macro_nodes() {
    8.63 +//---------------------------eliminate_macro_nodes----------------------
    8.64 +// Eliminate scalar replaced allocations and associated locks.
    8.65 +void PhaseMacroExpand::eliminate_macro_nodes() {
    8.66    if (C->macro_count() == 0)
    8.67 -    return false;
    8.68 +    return;
    8.69 +
    8.70    // First, attempt to eliminate locks
    8.71    int cnt = C->macro_count();
    8.72    for (int i=0; i < cnt; i++) {
    8.73 @@ -2189,14 +2189,6 @@
    8.74        debug_only(int old_macro_count = C->macro_count(););
    8.75        if (n->is_AbstractLock()) {
    8.76          success = eliminate_locking_node(n->as_AbstractLock());
    8.77 -      } else if (n->Opcode() == Op_LoopLimit) {
    8.78 -        // Remove it from macro list and put on IGVN worklist to optimize.
    8.79 -        C->remove_macro_node(n);
    8.80 -        _igvn._worklist.push(n);
    8.81 -        success = true;
    8.82 -      } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
    8.83 -        _igvn.replace_node(n, n->in(1));
    8.84 -        success = true;
    8.85        }
    8.86        assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
    8.87        progress = progress || success;
    8.88 @@ -2220,18 +2212,50 @@
    8.89          assert(!n->as_AbstractLock()->is_eliminated(), "sanity");
    8.90          break;
    8.91        default:
    8.92 -        assert(false, "unknown node type in macro list");
    8.93 +        assert(n->Opcode() == Op_LoopLimit ||
    8.94 +               n->Opcode() == Op_Opaque1   ||
    8.95 +               n->Opcode() == Op_Opaque2, "unknown node type in macro list");
    8.96        }
    8.97        assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
    8.98        progress = progress || success;
    8.99      }
   8.100    }
   8.101 +}
   8.102 +
   8.103 +//------------------------------expand_macro_nodes----------------------
   8.104 +//  Returns true if a failure occurred.
   8.105 +bool PhaseMacroExpand::expand_macro_nodes() {
   8.106 +  // Last attempt to eliminate macro nodes.
   8.107 +  eliminate_macro_nodes();
   8.108 +
   8.109    // Make sure expansion will not cause node limit to be exceeded.
   8.110    // Worst case is a macro node gets expanded into about 50 nodes.
   8.111    // Allow 50% more for optimization.
   8.112    if (C->check_node_count(C->macro_count() * 75, "out of nodes before macro expansion" ) )
   8.113      return true;
   8.114  
   8.115 +  // Eliminate Opaque and LoopLimit nodes. Do it after all loop optimizations.
   8.116 +  bool progress = true;
   8.117 +  while (progress) {
   8.118 +    progress = false;
   8.119 +    for (int i = C->macro_count(); i > 0; i--) {
   8.120 +      Node * n = C->macro_node(i-1);
   8.121 +      bool success = false;
   8.122 +      debug_only(int old_macro_count = C->macro_count(););
   8.123 +      if (n->Opcode() == Op_LoopLimit) {
   8.124 +        // Remove it from macro list and put on IGVN worklist to optimize.
   8.125 +        C->remove_macro_node(n);
   8.126 +        _igvn._worklist.push(n);
   8.127 +        success = true;
   8.128 +      } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
   8.129 +        _igvn.replace_node(n, n->in(1));
   8.130 +        success = true;
   8.131 +      }
   8.132 +      assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
   8.133 +      progress = progress || success;
   8.134 +    }
   8.135 +  }
   8.136 +
   8.137    // expand "macro" nodes
   8.138    // nodes are removed from the macro list as they are processed
   8.139    while (C->macro_count() > 0) {
   8.140 @@ -2265,5 +2289,6 @@
   8.141  
   8.142    _igvn.set_delay_transform(false);
   8.143    _igvn.optimize();
   8.144 +  if (C->failing())  return true;
   8.145    return false;
   8.146  }
     9.1 --- a/src/share/vm/opto/macro.hpp	Wed Nov 16 01:39:50 2011 -0800
     9.2 +++ b/src/share/vm/opto/macro.hpp	Wed Nov 16 09:13:57 2011 -0800
     9.3 @@ -119,6 +119,7 @@
     9.4    PhaseMacroExpand(PhaseIterGVN &igvn) : Phase(Macro_Expand), _igvn(igvn) {
     9.5      _igvn.set_delay_transform(true);
     9.6    }
     9.7 +  void eliminate_macro_nodes();
     9.8    bool expand_macro_nodes();
     9.9  
    9.10  };
    10.1 --- a/src/share/vm/opto/memnode.cpp	Wed Nov 16 01:39:50 2011 -0800
    10.2 +++ b/src/share/vm/opto/memnode.cpp	Wed Nov 16 09:13:57 2011 -0800
    10.3 @@ -2661,6 +2661,8 @@
    10.4  // control copies
    10.5  Node *StrIntrinsicNode::Ideal(PhaseGVN *phase, bool can_reshape) {
    10.6    if (remove_dead_region(phase, can_reshape)) return this;
    10.7 +  // Don't bother trying to transform a dead node
    10.8 +  if (in(0) && in(0)->is_top())  return NULL;
    10.9  
   10.10    if (can_reshape) {
   10.11      Node* mem = phase->transform(in(MemNode::Memory));
   10.12 @@ -2675,6 +2677,12 @@
   10.13    return NULL;
   10.14  }
   10.15  
   10.16 +//------------------------------Value------------------------------------------
   10.17 +const Type *StrIntrinsicNode::Value( PhaseTransform *phase ) const {
   10.18 +  if (in(0) && phase->type(in(0)) == Type::TOP) return Type::TOP;
   10.19 +  return bottom_type();
   10.20 +}
   10.21 +
   10.22  //=============================================================================
   10.23  MemBarNode::MemBarNode(Compile* C, int alias_idx, Node* precedent)
   10.24    : MultiNode(TypeFunc::Parms + (precedent == NULL? 0: 1)),
   10.25 @@ -2715,6 +2723,8 @@
   10.26  // control copies
   10.27  Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) {
   10.28    if (remove_dead_region(phase, can_reshape)) return this;
   10.29 +  // Don't bother trying to transform a dead node
   10.30 +  if (in(0) && in(0)->is_top())  return NULL;
   10.31  
   10.32    // Eliminate volatile MemBars for scalar replaced objects.
   10.33    if (can_reshape && req() == (Precedent+1) &&
    11.1 --- a/src/share/vm/opto/memnode.hpp	Wed Nov 16 01:39:50 2011 -0800
    11.2 +++ b/src/share/vm/opto/memnode.hpp	Wed Nov 16 09:13:57 2011 -0800
    11.3 @@ -800,6 +800,7 @@
    11.4    virtual uint match_edge(uint idx) const;
    11.5    virtual uint ideal_reg() const { return Op_RegI; }
    11.6    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
    11.7 +  virtual const Type *Value(PhaseTransform *phase) const;
    11.8  };
    11.9  
   11.10  //------------------------------StrComp-------------------------------------

mercurial