src/share/vm/opto/reg_split.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File JDK-8032656 Cdiff src/share/vm/opto/reg_split.cpp

src/share/vm/opto/reg_split.cpp

Print this page
rev 5829 : 8032656: Tag the MachSpillCopies with purpose information
Summary: Subclassed the MachSpillCopyNode with different subnodes for different spill purposes to enhance debugging / visualization
Reviewed-by:

*** 53,63 **** //------------------------------get_spillcopy_wide----------------------------- // Get a SpillCopy node with wide-enough masks. Use the 'wide-mask', the // wide ideal-register spill-mask if possible. If the 'wide-mask' does // not cover the input (or output), use the input (or output) mask instead. ! Node *PhaseChaitin::get_spillcopy_wide( Node *def, Node *use, uint uidx ) { // If ideal reg doesn't exist we've got a bad schedule happening // that is forcing us to spill something that isn't spillable. // Bail rather than abort int ireg = def->ideal_reg(); if( ireg == 0 || ireg == Op_RegFlags ) { --- 53,63 ---- //------------------------------get_spillcopy_wide----------------------------- // Get a SpillCopy node with wide-enough masks. Use the 'wide-mask', the // wide ideal-register spill-mask if possible. If the 'wide-mask' does // not cover the input (or output), use the input (or output) mask instead. ! Node *PhaseChaitin::get_spillcopy_wide(MachSpillCopyNode::SpillType spill_type, Node *def, Node *use, uint uidx ) { // If ideal reg doesn't exist we've got a bad schedule happening // that is forcing us to spill something that isn't spillable. // Bail rather than abort int ireg = def->ideal_reg(); if( ireg == 0 || ireg == Op_RegFlags ) {
*** 91,101 **** // (and thus through memory)? if( !C->matcher()->idealreg2regmask[ireg]->overlap( *o_mask) && o_mask->is_UP() ) // Here we assume a trip through memory is required. w_i_mask = &C->FIRST_STACK_mask(); } ! return new (C) MachSpillCopyNode( def, *w_i_mask, *w_o_mask ); } //------------------------------insert_proj------------------------------------ // Insert the spill at chosen location. Skip over any intervening Proj's or // Phis. Skip over a CatchNode and projs, inserting in the fall-through block --- 91,101 ---- // (and thus through memory)? if( !C->matcher()->idealreg2regmask[ireg]->overlap( *o_mask) && o_mask->is_UP() ) // Here we assume a trip through memory is required. w_i_mask = &C->FIRST_STACK_mask(); } ! return new (C) MachSpillCopyNode(spill_type, def, *w_i_mask, *w_o_mask ); } //------------------------------insert_proj------------------------------------ // Insert the spill at chosen location. Skip over any intervening Proj's or // Phis. Skip over a CatchNode and projs, inserting in the fall-through block
*** 157,167 **** loc = 0; // Just past the Region } assert( loc >= 0, "must insert past block head" ); // Get a def-side SpillCopy ! Node *spill = get_spillcopy_wide(def,NULL,0); // Did we fail to split?, then bail if (!spill) { return 0; } --- 157,167 ---- loc = 0; // Just past the Region } assert( loc >= 0, "must insert past block head" ); // Get a def-side SpillCopy ! Node *spill = get_spillcopy_wide(MachSpillCopyNode::Definition, def, NULL, 0); // Did we fail to split?, then bail if (!spill) { return 0; }
*** 178,188 **** } //------------------------------split_USE-------------------------------------- // Splits at uses can involve redeffing the LRG, so no CISC Spilling there. // Debug uses want to know if def is already stack enabled. ! uint PhaseChaitin::split_USE( Node *def, Block *b, Node *use, uint useidx, uint maxlrg, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx ) { #ifdef ASSERT // Increment the counter for this lrg splits.at_put(slidx, splits.at(slidx)+1); #endif --- 178,188 ---- } //------------------------------split_USE-------------------------------------- // Splits at uses can involve redeffing the LRG, so no CISC Spilling there. // Debug uses want to know if def is already stack enabled. ! uint PhaseChaitin::split_USE(MachSpillCopyNode::SpillType spill_type, Node *def, Block *b, Node *use, uint useidx, uint maxlrg, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx ) { #ifdef ASSERT // Increment the counter for this lrg splits.at_put(slidx, splits.at(slidx)+1); #endif
*** 214,224 **** // Put the clone just prior to use int bindex = b->find_node(use); // DEF is UP, so must copy it DOWN and hook in USE // Insert SpillCopy before the USE, which uses DEF as its input, // and defs a new live range, which is used by this node. ! Node *spill = get_spillcopy_wide(def,use,useidx); // did we fail to split? if (!spill) { // Bail return 0; } --- 214,224 ---- // Put the clone just prior to use int bindex = b->find_node(use); // DEF is UP, so must copy it DOWN and hook in USE // Insert SpillCopy before the USE, which uses DEF as its input, // and defs a new live range, which is used by this node. ! Node *spill = get_spillcopy_wide(spill_type, def,use,useidx); // did we fail to split? if (!spill) { // Bail return 0; }
*** 266,276 **** } else { // Put the clone just prior to use bindex = b->find_node(use); } ! Node *spill = get_spillcopy_wide( def, use, useidx ); if( !spill ) return 0; // Bailed out // Insert SpillCopy before the USE, which uses the reaching DEF as // its input, and defs a new live range, which is used by this node. insert_proj( b, bindex, spill, maxlrg++ ); // Use the spill/clone --- 266,276 ---- } else { // Put the clone just prior to use bindex = b->find_node(use); } ! Node *spill = get_spillcopy_wide(spill_type, def, use, useidx ); if( !spill ) return 0; // Bailed out // Insert SpillCopy before the USE, which uses the reaching DEF as // its input, and defs a new live range, which is used by this node. insert_proj( b, bindex, spill, maxlrg++ ); // Use the spill/clone
*** 325,335 **** continue; } Block *b_def = _cfg.get_block_for_node(def); int idx_def = b_def->find_node(def); ! Node *in_spill = get_spillcopy_wide( in, def, i ); if( !in_spill ) return 0; // Bailed out insert_proj(b_def,idx_def,in_spill,maxlrg++); if( b_def == b ) insidx++; def->set_req(i,in_spill); --- 325,335 ---- continue; } Block *b_def = _cfg.get_block_for_node(def); int idx_def = b_def->find_node(def); ! Node *in_spill = get_spillcopy_wide(MachSpillCopyNode::InputToRematerialization, in, def, i ); if( !in_spill ) return 0; // Bailed out insert_proj(b_def,idx_def,in_spill,maxlrg++); if( b_def == b ) insidx++; def->set_req(i,in_spill);
*** 933,943 **** (mach && mach->ideal_Opcode() == Op_AddP && inpidx == AddPNode::Base)) { if (def->rematerialize() && lrgs(useidx)._was_spilled2) { // This def has been rematerialized a couple of times without // progress. It doesn't care if it lives UP or DOWN, so // spill it down now. ! maxlrg = split_USE(def,b,n,inpidx,maxlrg,false,false,splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split --- 933,943 ---- (mach && mach->ideal_Opcode() == Op_AddP && inpidx == AddPNode::Base)) { if (def->rematerialize() && lrgs(useidx)._was_spilled2) { // This def has been rematerialized a couple of times without // progress. It doesn't care if it lives UP or DOWN, so // spill it down now. ! maxlrg = split_USE(MachSpillCopyNode::BasePointerToMem, def,b,n,inpidx,maxlrg,false,false,splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split
*** 1013,1023 **** (int)umask.Size() <= lrgs(useidx).num_regs() && (!def->rematerialize() || !is_vect && umask.is_misaligned_pair())) { // These need a Split regardless of overlap or pressure // SPLIT - NO DEF - NO CISC SPILL ! maxlrg = split_USE(def,b,n,inpidx,maxlrg,dup,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split --- 1013,1023 ---- (int)umask.Size() <= lrgs(useidx).num_regs() && (!def->rematerialize() || !is_vect && umask.is_misaligned_pair())) { // These need a Split regardless of overlap or pressure // SPLIT - NO DEF - NO CISC SPILL ! maxlrg = split_USE(MachSpillCopyNode::Bound, def,b,n,inpidx,maxlrg,dup,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split
*** 1025,1035 **** } if (UseFPUForSpilling && n->is_MachCall() && !uup && !dup ) { // The use at the call can force the def down so insert // a split before the use to allow the def more freedom. ! maxlrg = split_USE(def,b,n,inpidx,maxlrg,dup,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split --- 1025,1035 ---- } if (UseFPUForSpilling && n->is_MachCall() && !uup && !dup ) { // The use at the call can force the def down so insert // a split before the use to allow the def more freedom. ! maxlrg = split_USE(MachSpillCopyNode::CallUse, def,b,n,inpidx,maxlrg,dup,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split
*** 1061,1071 **** n->set_req(inpidx, def); } else { // Both are either up or down, and there is no overlap if( dup ) { // If UP, reg->reg copy // COPY ACROSS HERE - NO DEF - NO CISC SPILL ! maxlrg = split_USE(def,b,n,inpidx,maxlrg,false,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split --- 1061,1071 ---- n->set_req(inpidx, def); } else { // Both are either up or down, and there is no overlap if( dup ) { // If UP, reg->reg copy // COPY ACROSS HERE - NO DEF - NO CISC SPILL ! maxlrg = split_USE(MachSpillCopyNode::RegToReg, def,b,n,inpidx,maxlrg,false,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split
*** 1073,1086 **** else { // DOWN, mem->mem copy // COPY UP & DOWN HERE - NO DEF - NO CISC SPILL // First Split-UP to move value into Register uint def_ideal = def->ideal_reg(); const RegMask* tmp_rm = Matcher::idealreg2regmask[def_ideal]; ! Node *spill = new (C) MachSpillCopyNode(def, dmask, *tmp_rm); insert_proj( b, insidx, spill, maxlrg ); // Then Split-DOWN as if previous Split was DEF ! maxlrg = split_USE(spill,b,n,inpidx,maxlrg,false,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx += 2; // Reset iterator to skip USE side splits --- 1073,1086 ---- else { // DOWN, mem->mem copy // COPY UP & DOWN HERE - NO DEF - NO CISC SPILL // First Split-UP to move value into Register uint def_ideal = def->ideal_reg(); const RegMask* tmp_rm = Matcher::idealreg2regmask[def_ideal]; ! Node *spill = new (C) MachSpillCopyNode(MachSpillCopyNode::MemToReg, def, dmask, *tmp_rm); insert_proj( b, insidx, spill, maxlrg ); // Then Split-DOWN as if previous Split was DEF ! maxlrg = split_USE(MachSpillCopyNode::RegToMem, spill,b,n,inpidx,maxlrg,false,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx += 2; // Reset iterator to skip USE side splits
*** 1101,1111 **** } continue; } } // COPY DOWN HERE - NO DEF - NO CISC SPILL ! maxlrg = split_USE(def,b,n,inpidx,maxlrg,false,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split --- 1101,1111 ---- } continue; } } // COPY DOWN HERE - NO DEF - NO CISC SPILL ! maxlrg = split_USE(MachSpillCopyNode::RegToMem, def,b,n,inpidx,maxlrg,false,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split
*** 1116,1134 **** } else { // DOWN, Split-UP and check register pressure if( is_high_pressure( b, &lrgs(useidx), insidx ) ) { // COPY UP HERE - NO DEF - CISC SPILL ! maxlrg = split_USE(def,b,n,inpidx,maxlrg,true,true, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split } else { // LRP // COPY UP HERE - WITH DEF - NO CISC SPILL ! maxlrg = split_USE(def,b,n,inpidx,maxlrg,true,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } // Flag this lift-up in a low-pressure block as --- 1116,1134 ---- } else { // DOWN, Split-UP and check register pressure if( is_high_pressure( b, &lrgs(useidx), insidx ) ) { // COPY UP HERE - NO DEF - CISC SPILL ! maxlrg = split_USE(MachSpillCopyNode::MemToReg, def,b,n,inpidx,maxlrg,true,true, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } insidx++; // Reset iterator to skip USE side split } else { // LRP // COPY UP HERE - WITH DEF - NO CISC SPILL ! maxlrg = split_USE(MachSpillCopyNode::MemToReg, def,b,n,inpidx,maxlrg,true,false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } // Flag this lift-up in a low-pressure block as
*** 1227,1237 **** const RegMask &use_rm = n->in_RegMask(copyidx); if( def_rm.overlap(use_rm) && n->is_SpillCopy() ) { // Bug 4707800, 'n' may be a storeSSL if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { // Check when generating nodes return 0; } ! Node *spill = new (C) MachSpillCopyNode(use,use_rm,def_rm); n->set_req(copyidx,spill); n->as_MachSpillCopy()->set_in_RegMask(def_rm); // Put the spill just before the copy insert_proj( b, insidx++, spill, maxlrg++ ); } --- 1227,1237 ---- const RegMask &use_rm = n->in_RegMask(copyidx); if( def_rm.overlap(use_rm) && n->is_SpillCopy() ) { // Bug 4707800, 'n' may be a storeSSL if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { // Check when generating nodes return 0; } ! Node *spill = new (C) MachSpillCopyNode(MachSpillCopyNode::MemToReg, use,use_rm,def_rm); n->set_req(copyidx,spill); n->as_MachSpillCopy()->set_in_RegMask(def_rm); // Put the spill just before the copy insert_proj( b, insidx++, spill, maxlrg++ ); }
*** 1334,1344 **** // Update the Phi's input edge array phi->set_req(i,def); // Grab the UP/DOWN sense for the input u1 = UP[pidx][slidx]; if( u1 != (phi_up != 0)) { ! maxlrg = split_USE(def, b, phi, i, maxlrg, !u1, false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } } --- 1334,1344 ---- // Update the Phi's input edge array phi->set_req(i,def); // Grab the UP/DOWN sense for the input u1 = UP[pidx][slidx]; if( u1 != (phi_up != 0)) { ! maxlrg = split_USE(MachSpillCopyNode::PhiLocationDifferToInputLocation, def, b, phi, i, maxlrg, !u1, false, splits,slidx); // If it wasn't split bail if (!maxlrg) { return 0; } }
src/share/vm/opto/reg_split.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File