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