< prev index next >

src/share/vm/opto/reg_split.cpp

Print this page

        

*** 58,80 **** // 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) { ! assert(false, "attempted to spill a non-spillable item: %d: %s <- %d: %s, ireg = %d, spill_type: %s", ! def->_idx, def->Name(), use->_idx, use->Name(), ireg, MachSpillCopyNode::spill_type(spill_type)); C->record_method_not_compilable("attempted to spill a non-spillable item"); return NULL; } if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { return NULL; } const RegMask *i_mask = &def->out_RegMask(); ! const RegMask *w_mask = C->matcher()->idealreg2spillmask[ireg]; const RegMask *o_mask = use ? &use->in_RegMask(uidx) : w_mask; const RegMask *w_i_mask = w_mask->overlap( *i_mask ) ? w_mask : i_mask; const RegMask *w_o_mask; int num_regs = RegMask::num_registers(ireg); --- 58,80 ---- // 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 ! Opcodes ireg = def->ideal_reg(); ! if (ireg == Opcodes::Op_Node || ireg == Opcodes::Op_RegFlags) { ! assert(false, "attempted to spill a non-spillable item: %d: %s <- %d: %s, ireg = %u, spill_type: %s", ! def->_idx, def->Name(), use->_idx, use->Name(), static_cast<uint>(ireg), MachSpillCopyNode::spill_type(spill_type)); C->record_method_not_compilable("attempted to spill a non-spillable item"); return NULL; } if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { return NULL; } const RegMask *i_mask = &def->out_RegMask(); ! const RegMask *w_mask = C->matcher()->idealreg2spillmask[static_cast<uint>(ireg)]; const RegMask *o_mask = use ? &use->in_RegMask(uidx) : w_mask; const RegMask *w_i_mask = w_mask->overlap( *i_mask ) ? w_mask : i_mask; const RegMask *w_o_mask; int num_regs = RegMask::num_registers(ireg);
*** 90,100 **** // Mis-aligned doubles come here and XMM->FPR moves on x86. w_o_mask = o_mask; // Must target desired registers // Does the ideal-reg-mask overlap with o_mask? I.e., can I use // a reg-reg move or do I need a trip across register classes // (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 MachSpillCopyNode(spill_type, def, *w_i_mask, *w_o_mask ); } --- 90,100 ---- // Mis-aligned doubles come here and XMM->FPR moves on x86. w_o_mask = o_mask; // Must target desired registers // Does the ideal-reg-mask overlap with o_mask? I.e., can I use // a reg-reg move or do I need a trip across register classes // (and thus through memory)? ! if( !C->matcher()->idealreg2regmask[static_cast<uint>(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 MachSpillCopyNode(spill_type, def, *w_i_mask, *w_o_mask ); }
*** 154,164 **** // (The implicit_null_check function ensures the use is also dominated // by the branch-not-taken block.) Node *be = b->end(); if( be->is_MachNullCheck() && be->in(1) == def && def == b->get_node(loc)) { // Spill goes in the branch-not-taken block ! b = b->_succs[b->get_node(b->end_idx()+1)->Opcode() == Op_IfTrue]; loc = 0; // Just past the Region } assert( loc >= 0, "must insert past block head" ); // Get a def-side SpillCopy --- 154,164 ---- // (The implicit_null_check function ensures the use is also dominated // by the branch-not-taken block.) Node *be = b->end(); if( be->is_MachNullCheck() && be->in(1) == def && def == b->get_node(loc)) { // Spill goes in the branch-not-taken block ! b = b->_succs[b->get_node(b->end_idx()+1)->Opcode() == Opcodes::Op_IfTrue]; loc = 0; // Just past the Region } assert( loc >= 0, "must insert past block head" ); // Get a def-side SpillCopy
*** 332,342 **** Block *b_def = _cfg.get_block_for_node(def); int idx_def = b_def->find_node(def); // Cannot spill Op_RegFlags. Node *in_spill; ! if (in->ideal_reg() != Op_RegFlags) { 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++; --- 332,342 ---- Block *b_def = _cfg.get_block_for_node(def); int idx_def = b_def->find_node(def); // Cannot spill Op_RegFlags. Node *in_spill; ! if (in->ideal_reg() != Opcodes::Op_RegFlags) { 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++;
*** 949,959 **** } MachNode *mach = n->is_Mach() ? n->as_Mach() : NULL; // Base pointers and oopmap references do not care where they live. if ((inpidx >= oopoff) || ! (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); --- 949,959 ---- } MachNode *mach = n->is_Mach() ? n->as_Mach() : NULL; // Base pointers and oopmap references do not care where they live. if ((inpidx >= oopoff) || ! (mach && mach->ideal_Opcode() == Opcodes::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);
*** 973,983 **** // derived value is spilling and we have a copy both in Reachblock // (called here 'def') and debug_defs[slidx] we need to mention // both in derived/base pairs or kill one. Node *derived_debug = debug_defs[slidx]; if( ((inpidx - oopoff) & 1) == DERIVED && // derived vs base? ! mach && mach->ideal_Opcode() != Op_Halt && derived_debug != NULL && derived_debug != def ) { // Actual 2nd value appears // We have already set 'def' as a derived value. // Also set debug_defs[slidx] as a derived value. uint k; --- 973,983 ---- // derived value is spilling and we have a copy both in Reachblock // (called here 'def') and debug_defs[slidx] we need to mention // both in derived/base pairs or kill one. Node *derived_debug = debug_defs[slidx]; if( ((inpidx - oopoff) & 1) == DERIVED && // derived vs base? ! mach && mach->ideal_Opcode() != Opcodes::Op_Halt && derived_debug != NULL && derived_debug != def ) { // Actual 2nd value appears // We have already set 'def' as a derived value. // Also set debug_defs[slidx] as a derived value. uint k;
*** 1092,1103 **** insidx++; // Reset iterator to skip USE side split } 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 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 --- 1092,1103 ---- insidx++; // Reset iterator to skip USE side split } else { // DOWN, mem->mem copy // COPY UP & DOWN HERE - NO DEF - NO CISC SPILL // First Split-UP to move value into Register ! Opcodes def_ideal = def->ideal_reg(); ! const RegMask* tmp_rm = Matcher::idealreg2regmask[static_cast<uint>(def_ideal)]; Node *spill = new 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
*** 1182,1192 **** set_was_spilled(n); assert(!n->is_Phi(),"Cannot insert Phi into DEFS list"); // Grab UP info for DEF const RegMask &dmask = n->out_RegMask(); bool defup = dmask.is_UP(); ! int ireg = n->ideal_reg(); bool is_vect = RegMask::is_vector(ireg); // Only split at Def if this is a HRP block or bound (and spilled once) if( !n->rematerialize() && (((dmask.is_bound(ireg) || !is_vect && dmask.is_misaligned_pair()) && (deflrg._direct_conflict || deflrg._must_spill)) || --- 1182,1192 ---- set_was_spilled(n); assert(!n->is_Phi(),"Cannot insert Phi into DEFS list"); // Grab UP info for DEF const RegMask &dmask = n->out_RegMask(); bool defup = dmask.is_UP(); ! Opcodes ireg = n->ideal_reg(); bool is_vect = RegMask::is_vector(ireg); // Only split at Def if this is a HRP block or bound (and spilled once) if( !n->rematerialize() && (((dmask.is_bound(ireg) || !is_vect && dmask.is_misaligned_pair()) && (deflrg._direct_conflict || deflrg._must_spill)) ||
*** 1241,1252 **** deflrg.reg() < LRG::SPILL_REG ) { // And DEF is from stack LRG &uselrg = lrgs(useidx); if( OptoReg::is_stack(uselrg.reg()) && uselrg.reg() < LRG::SPILL_REG && // USE is from stack deflrg.reg() != uselrg.reg() ) { // Not trivially removed ! uint def_ideal_reg = n->bottom_type()->ideal_reg(); ! const RegMask &def_rm = *Matcher::idealreg2regmask[def_ideal_reg]; 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; } --- 1241,1252 ---- deflrg.reg() < LRG::SPILL_REG ) { // And DEF is from stack LRG &uselrg = lrgs(useidx); if( OptoReg::is_stack(uselrg.reg()) && uselrg.reg() < LRG::SPILL_REG && // USE is from stack deflrg.reg() != uselrg.reg() ) { // Not trivially removed ! Opcodes def_ideal_reg = n->bottom_type()->ideal_reg(); ! const RegMask &def_rm = *Matcher::idealreg2regmask[static_cast<uint>(def_ideal_reg)]; 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; }
< prev index next >