//------------------------------insert_copies---------------------------------- void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { // We do LRGs compressing and fix a liveout data only here since the other // place in Split() is guarded by the assert which we never hit. _phc.compress_uf_map_for_nodes(); // Fix block's liveout data for compressed live ranges. for(uint lrg = 1; lrg < _phc._maxlrg; lrg++ ) { uint compressed_lrg = _phc.Find(lrg); if( lrg != compressed_lrg ) { for( uint bidx = 0; bidx < _phc._cfg._num_blocks; bidx++ ) { IndexSet *liveout = _phc._live->live(_phc._cfg._blocks[bidx]); if( liveout->member(lrg) ) { liveout->remove(lrg); liveout->insert(compressed_lrg); } } } } // All new nodes added are actual copies to replace virtual copies. // Nodes with index less than '_unique' are original, non-virtual Nodes. _unique = C->unique(); for( uint i=0; i<_phc._cfg._num_blocks; i++ ) { Block *b = _phc._cfg._blocks[i]; uint cnt = b->num_preds(); // Number of inputs to the Phi for( uint l = 1; l<b->_nodes.size(); l++ ) { Node *n = b->_nodes[l]; // Do not use removed-copies, use copied value instead uint ncnt = n->req(); for( uint k = 1; k<ncnt; k++ ) { Node *copy = n->in(k); uint cidx = copy->is_Copy(); if( cidx ) { Node *def = copy->in(cidx); if( _phc.Find(copy) == _phc.Find(def) ) n->set_req(k,def); } } // Remove any explicit copies that get coalesced. uint cidx = n->is_Copy(); if( cidx ) { Node *def = n->in(cidx); if( _phc.Find(n) == _phc.Find(def) ) { n->replace_by(def); n->set_req(cidx,NULL); b->_nodes.remove(l); l--; continue; } } if( n->is_Phi() ) { // Get the chosen name for the Phi uint phi_name = _phc.Find( n ); // Ignore the pre-allocated specials if( !phi_name ) continue; // Check for mismatch inputs to Phi for( uint j = 1; j<cnt; j++ ) { Node *m = n->in(j); uint src_name = _phc.Find(m); if( src_name != phi_name ) { Block *pred = _phc._cfg._bbs[b->pred(j)->_idx]; Node *copy; assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach"); // Rematerialize constants instead of copying them if( m->is_Mach() && m->as_Mach()->is_Con() && m->as_Mach()->rematerialize() ) { copy = m->clone(); // Insert the copy in the predecessor basic block pred->add_inst(copy); // Copy any flags as well _phc.clone_projs( pred, pred->end_idx(), m, copy, _phc._maxlrg ); } else { const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()]; copy = new (C) MachSpillCopyNode(m,*rm,*rm); // Find a good place to insert. Kinda tricky, use a subroutine insert_copy_with_overlap(pred,copy,phi_name,src_name); } // Insert the copy in the use-def chain n->set_req( j, copy ); _phc._cfg._bbs.map( copy->_idx, pred ); // Extend ("register allocate") the names array for the copy. _phc._names.extend( copy->_idx, phi_name ); } // End of if Phi names do not match } // End of for all inputs to Phi } else { // End of if Phi // Now check for 2-address instructions uint idx; if( n->is_Mach() && (idx=n->as_Mach()->two_adr()) ) { // Get the chosen name for the Node uint name = _phc.Find( n ); assert( name, "no 2-address specials" ); // Check for name mis-match on the 2-address input Node *m = n->in(idx); if( _phc.Find(m) != name ) { Node *copy; assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach"); // At this point it is unsafe to extend live ranges (6550579). // Rematerialize only constants as we do for Phi above. if( m->is_Mach() && m->as_Mach()->is_Con() && m->as_Mach()->rematerialize() ) { copy = m->clone(); // Insert the copy in the basic block, just before us b->_nodes.insert( l++, copy ); if( _phc.clone_projs( b, l, m, copy, _phc._maxlrg ) ) l++; } else { const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()]; copy = new (C) MachSpillCopyNode( m, *rm, *rm ); // Insert the copy in the basic block, just before us b->_nodes.insert( l++, copy ); } // Insert the copy in the use-def chain n->set_req(idx, copy ); // Extend ("register allocate") the names array for the copy. _phc._names.extend( copy->_idx, name ); _phc._cfg._bbs.map( copy->_idx, b ); } } // End of is two-adr // Insert a copy at a debug use for a lrg which has high frequency if( b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(_phc._cfg._bbs) ) { // Walk the debug inputs to the node and check for lrg freq JVMState* jvms = n->jvms(); uint debug_start = jvms ? jvms->debug_start() : 999999; uint debug_end = jvms ? jvms->debug_end() : 999999; for(uint inpidx = debug_start; inpidx < debug_end; inpidx++) { // Do not split monitors; they are only needed for debug table // entries and need no code. if( jvms->is_monitor_use(inpidx) ) continue; Node *inp = n->in(inpidx); uint nidx = _phc.n2lidx(inp); LRG &lrg = lrgs(nidx); // If this lrg has a high frequency use/def if( lrg._maxfreq >= _phc.high_frequency_lrg() ) { // If the live range is also live out of this block (like it // would be for a fast/slow idiom), the normal spill mechanism // does an excellent job. If it is not live out of this block // (like it would be for debug info to uncommon trap) splitting // the live range now allows a better allocation in the high // frequency blocks. // Build_IFG_virtual has converted the live sets to // live-IN info, not live-OUT info. uint k; for( k=0; k < b->_num_succs; k++ ) if( _phc._live->live(b->_succs[k])->member( nidx ) ) break; // Live in to some successor block? if( k < b->_num_succs ) continue; // Live out; do not pre-split // Split the lrg at this use const RegMask *rm = C->matcher()->idealreg2spillmask[inp->ideal_reg()]; Node *copy = new (C) MachSpillCopyNode( inp, *rm, *rm ); // Insert the copy in the use-def chain n->set_req(inpidx, copy ); // Insert the copy in the basic block, just before us b->_nodes.insert( l++, copy ); // Extend ("register allocate") the names array for the copy. _phc.new_lrg( copy, _phc._maxlrg++ ); _phc._cfg._bbs.map( copy->_idx, b ); //tty->print_cr("Split a debug use in Aggressive Coalesce"); } // End of if high frequency use/def } // End of for all debug inputs } // End of if low frequency safepoint } // End of if Phi } // End of for all instructions } // End of for all blocks }