Wed, 16 Nov 2011 09:13:57 -0800
6890673: Eliminate allocations immediately after EA
Summary: Try to eliminate allocations and related locks immediately after escape analysis.
Reviewed-by: never
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-------------------------------------