src/share/vm/opto/chaitin.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/share/vm/opto/chaitin.cpp	Sat Jun  2 20:04:10 2012
--- new/src/share/vm/opto/chaitin.cpp	Sat Jun  2 20:04:10 2012

*** 73,82 **** --- 73,83 ---- tty->print("Cost:%4.2g Area:%4.2g Score:%4.2g ",_cost,_area, score()); // Flags if( _is_oop ) tty->print("Oop "); if( _is_float ) tty->print("Float "); + if( _is_vector ) tty->print("Vector "); if( _was_spilled1 ) tty->print("Spilled "); if( _was_spilled2 ) tty->print("Spilled2 "); if( _direct_conflict ) tty->print("Direct_conflict "); if( _fat_proj ) tty->print("Fat "); if( _was_lo ) tty->print("Lo ");
*** 477,496 **** --- 478,499 ---- NOT_PRODUCT( C->verify_graph_edges(); ) // Move important info out of the live_arena to longer lasting storage. alloc_node_regs(_names.Size()); ! for( uint i=0; i < _names.Size(); i++ ) { ! if( _names[i] ) { // Live range associated with Node? ! LRG &lrg = lrgs( _names[i] ); ! if( lrg.num_regs() == 1 ) { ! _node_regs[i].set1( lrg.reg() ); ! for (uint i=0; i < _names.Size(); i++) { ! if (_names[i]) { // Live range associated with Node? ! LRG &lrg = lrgs(_names[i]); ! if (!lrg.alive()) { ! _node_regs[i].set_bad(); + } else if (lrg.num_regs() == 1) { + _node_regs[i].set1(lrg.reg()); } else { // Must be a register-pair ! if( !lrg._fat_proj ) { // Must be aligned adjacent register pair ! if (!lrg._fat_proj) { // Must be aligned adjacent register pair // Live ranges record the highest register in their mask. // We want the low register for the AD file writer's convenience. ! _node_regs[i].set2( OptoReg::add(lrg.reg(),-1) ); ! _node_regs[i].set2( OptoReg::add(lrg.reg(),(1-lrg.num_regs())) ); } else { // Misaligned; extract 2 bits OptoReg::Name hi = lrg.reg(); // Get hi register lrg.Remove(hi); // Yank from mask int lo = lrg.mask().find_first_elem(); // Find lo _node_regs[i].set_pair( hi, lo );
*** 566,576 **** --- 569,579 ---- } // Check for float-vs-int live range (used in register-pressure // calculations) const Type *n_type = n->bottom_type(); ! if( n_type->is_floatingpoint() ) ! if (n_type->is_floatingpoint()) lrg._is_float = 1; // Check for twice prior spilling. Once prior spilling might have // spilled 'soft', 2nd prior spill should have spilled 'hard' and // further spilling is unlikely to make progress.
*** 597,618 **** --- 600,631 ---- lrg._def = lrg._def ? NodeSentinel : n; // Limit result register mask to acceptable registers const RegMask &rm = n->out_RegMask(); lrg.AND( rm ); + + int ireg = n->ideal_reg(); + assert( !n->bottom_type()->isa_oop_ptr() || ireg == Op_RegP, + "oops must be in Op_RegP's" ); + + // Check for vector live range (only if vector register is used). + // On SPARC vector uses RegD which could be misaligned so it is not + // processes as vector in RA. + if (RegMask::is_vector(ireg)) + lrg._is_vector = 1; + assert(n_type->isa_vect() == NULL || lrg._is_vector || ireg == Op_RegD, + "vector must be in vector registers"); + // Check for bound register masks const RegMask &lrgmask = lrg.mask(); ! if( lrgmask.is_bound1() || lrgmask.is_bound2() ) ! if (lrgmask.is_bound(ireg)) lrg._is_bound = 1; // Check for maximum frequency value ! if( lrg._maxfreq < b->_freq ) ! if (lrg._maxfreq < b->_freq) lrg._maxfreq = b->_freq; int ireg = n->ideal_reg(); assert( !n->bottom_type()->isa_oop_ptr() || ireg == Op_RegP, "oops must be in Op_RegP's" ); // Check for oop-iness, or long/double // Check for multi-kill projection switch( ireg ) { case MachProjNode::fat_proj: // Fat projections have size equal to number of registers killed
*** 687,697 **** --- 700,710 ---- // If this def of a double forces a mis-aligned double, // flag as '_fat_proj' - really flag as allowing misalignment // AND changes how we count interferences. A mis-aligned // double can interfere with TWO aligned pairs, or effectively // FOUR registers! ! if( rm.is_misaligned_Pair() ) { ! if (rm.is_misaligned_pair()) { lrg._fat_proj = 1; lrg._is_bound = 1; } break; case Op_RegF:
*** 704,713 **** --- 717,753 ---- lrg.set_reg_pressure(2); #else lrg.set_reg_pressure(1); #endif break; + case Op_VecS: + assert(Matcher::vector_size_supported(T_BYTE,4), "sanity"); + assert(RegMask::num_registers(Op_VecS) == RegMask::SlotsPerVecS, "sanity"); + lrg.set_num_regs(RegMask::SlotsPerVecS); + lrg.set_reg_pressure(1); + break; + case Op_VecD: + assert(Matcher::vector_size_supported(T_FLOAT,RegMask::SlotsPerVecD), "sanity"); + assert(RegMask::num_registers(Op_VecD) == RegMask::SlotsPerVecD, "sanity"); + assert(lrgmask.is_aligned_sets(RegMask::SlotsPerVecD), "vector should be aligned"); + lrg.set_num_regs(RegMask::SlotsPerVecD); + lrg.set_reg_pressure(1); + break; + case Op_VecX: + assert(Matcher::vector_size_supported(T_FLOAT,RegMask::SlotsPerVecX), "sanity"); + assert(RegMask::num_registers(Op_VecX) == RegMask::SlotsPerVecX, "sanity"); + assert(lrgmask.is_aligned_sets(RegMask::SlotsPerVecX), "vector should be aligned"); + lrg.set_num_regs(RegMask::SlotsPerVecX); + lrg.set_reg_pressure(1); + break; + case Op_VecY: + assert(Matcher::vector_size_supported(T_FLOAT,RegMask::SlotsPerVecY), "sanity"); + assert(RegMask::num_registers(Op_VecY) == RegMask::SlotsPerVecY, "sanity"); + assert(lrgmask.is_aligned_sets(RegMask::SlotsPerVecY), "vector should be aligned"); + lrg.set_num_regs(RegMask::SlotsPerVecY); + lrg.set_reg_pressure(1); + break; default: ShouldNotReachHere(); } }
*** 761,788 **** --- 801,842 ---- // Later, AFTER aggressive, this live range will have to spill // but the spiller handles slow-path calls very nicely. } else { lrg.AND( rm ); } + // Check for bound register masks const RegMask &lrgmask = lrg.mask(); ! if( lrgmask.is_bound1() || lrgmask.is_bound2() ) ! int kreg = n->in(k)->ideal_reg(); + bool is_vect = RegMask::is_vector(kreg); + assert(n->in(k)->bottom_type()->isa_vect() == NULL || + is_vect || kreg == Op_RegD, + "vector must be in vector registers"); + if (lrgmask.is_bound(kreg)) lrg._is_bound = 1; + // If this use of a double forces a mis-aligned double, // flag as '_fat_proj' - really flag as allowing misalignment // AND changes how we count interferences. A mis-aligned // double can interfere with TWO aligned pairs, or effectively // FOUR registers! if( lrg.num_regs() == 2 && !lrg._fat_proj && rm.is_misaligned_Pair() ) { + #ifdef ASSERT + if (is_vect) { + assert(lrgmask.is_aligned_sets(lrg.num_regs()), "vector should be aligned"); + assert(!lrg._fat_proj, "sanity"); + assert(RegMask::num_registers(kreg) == lrg.num_regs(), "sanity"); + } + #endif + if (!is_vect && lrg.num_regs() == 2 && !lrg._fat_proj && rm.is_misaligned_pair()) { lrg._fat_proj = 1; lrg._is_bound = 1; } // if the LRG is an unaligned pair, we will have to spill // so clear the LRG's register mask if it is not already spilled ! if (!is_vect && !n->is_SpillCopy() && (lrg._def == NULL || lrg.is_multidef() || !lrg._def->is_SpillCopy()) && ! lrgmask.is_misaligned_Pair()) { ! lrgmask.is_misaligned_pair()) { lrg.Clear(); } // Check for maximum frequency value if( lrg._maxfreq < b->_freq )
*** 791,806 **** --- 845,862 ---- } // End for all allocated inputs } // end for all instructions } // end for all blocks // Final per-liverange setup ! for( uint i2=0; i2<_maxlrg; i2++ ) { ! for (uint i2=0; i2<_maxlrg; i2++) { LRG &lrg = lrgs(i2); if( lrg.num_regs() == 2 && !lrg._fat_proj ) lrg.ClearToPairs(); + assert(!lrg._is_vector || !lrg._fat_proj, "sanity"); + if (lrg.num_regs() > 1 && !lrg._fat_proj) { + lrg.clear_to_sets(); + } lrg.compute_set_mask_size(); ! if( lrg.not_free() ) { // Handle case where we lose from the start ! if (lrg.not_free()) { // Handle case where we lose from the start lrg.set_reg(OptoReg::Name(LRG::SPILL_REG)); lrg._direct_conflict = 1; } lrg.set_degree(0); // no neighbors in IFG yet }
*** 1102,1127 **** --- 1158,1178 ---- return reg; } else if( chunk == 0 ) { // Choose a color which is legal for him RegMask tempmask = lrg.mask(); tempmask.AND(lrgs(copy_lrg).mask()); ! OptoReg::Name reg; if( lrg.num_regs() == 1 ) { reg = tempmask.find_first_elem(); } else { tempmask.ClearToPairs(); reg = tempmask.find_first_pair(); } if( OptoReg::is_valid(reg) ) ! tempmask.clear_to_sets(lrg.num_regs()); + OptoReg::Name reg = tempmask.find_first_set(lrg.num_regs()); + if (OptoReg::is_valid(reg)) return reg; } } // If no bias info exists, just go with the register selection ordering ! if( lrg.num_regs() == 2 ) { ! // Find an aligned pair ! return OptoReg::add(lrg.mask().find_first_pair(),chunk); ! if (lrg._is_vector || lrg.num_regs() == 2) { ! // Find an aligned set ! return OptoReg::add(lrg.mask().find_first_set(lrg.num_regs()),chunk); } // CNC - Fun hack. Alternate 1st and 2nd selection. Enables post-allocate // copy removal to remove many more copies, by preventing a just-assigned // register from being repeatedly assigned.
*** 1147,1156 **** --- 1198,1208 ---- if( lrg.num_regs() == 1 || // Common Case !lrg._fat_proj ) // Aligned+adjacent pairs ok // Use a heuristic to "bias" the color choice return bias_color(lrg, chunk); + assert(!lrg._is_vector, "should be not vector here" ); assert( lrg.num_regs() >= 2, "dead live ranges do not color" ); // Fat-proj case or misaligned double argument. assert(lrg.compute_mask_size() == lrg.num_regs() || lrg.num_regs() == 2,"fat projs exactly color" );
*** 1236,1253 **** --- 1288,1307 ---- #endif } } //assert(is_allstack == lrg->mask().is_AllStack(), "nbrs must not change AllStackedness"); // Aligned pairs need aligned masks if( lrg->num_regs() == 2 && !lrg->_fat_proj ) lrg->ClearToPairs(); + assert(!lrg->_is_vector || !lrg->_fat_proj, "sanity"); + if (lrg->num_regs() > 1 && !lrg->_fat_proj) { + lrg->clear_to_sets(); + } // Check if a color is available and if so pick the color OptoReg::Name reg = choose_color( *lrg, chunk ); #ifdef SPARC debug_only(lrg->compute_set_mask_size()); ! assert(lrg->num_regs() != 2 || lrg->is_bound() || is_even(reg-1), "allocate all doubles aligned"); ! assert(lrg->num_regs() < 2 || lrg->is_bound() || is_even(reg-1), "allocate all doubles aligned"); #endif //--------------- // If we fail to color and the AllStack flag is set, trigger // a chunk-rollover event
*** 1275,1295 **** --- 1329,1348 ---- reg = OptoReg::add(reg,-chunk); // If the live range is not bound, then we actually had some choices // to make. In this case, the mask has more bits in it than the colors // chosen. Restrict the mask to just what was picked. ! if( lrg->num_regs() == 1 ) { // Size 1 live range ! int n_regs = lrg->num_regs(); + assert(!lrg->_is_vector || !lrg->_fat_proj, "sanity"); + if (n_regs == 1 || !lrg->_fat_proj) { + assert(!lrg->_is_vector || n_regs <= RegMask::SlotsPerVecY, "sanity"); lrg->Clear(); // Clear the mask lrg->Insert(reg); // Set regmask to match selected reg lrg->set_mask_size(1); } else if( !lrg->_fat_proj ) { // For pairs, also insert the low bit of the pair ! assert( lrg->num_regs() == 2, "unbound fatproj???" ); lrg->Clear(); // Clear the mask lrg->Insert(reg); // Set regmask to match selected reg lrg->Insert(OptoReg::add(reg,-1)); lrg->set_mask_size(2); + // For vectors and pairs, also insert the low bit of the pair + for (int i = 1; i < n_regs; i++) + lrg->Insert(OptoReg::add(reg,-i)); ! lrg->set_mask_size(n_regs); } else { // Else fatproj // mask must be equal to fatproj bits, by definition } #ifndef PRODUCT if (trace_spilling()) {
*** 1858,1875 **** --- 1911,1936 ---- uint lidx = Find_const(n); // Grab LRG number if( !_ifg ) { sprintf(buf,"L%d",lidx); // No register binding yet } else if( !lidx ) { // Special, not allocated value strcpy(buf,"Special"); ! } else if( (lrgs(lidx).num_regs() == 1) ? !lrgs(lidx).mask().is_bound1() : !lrgs(lidx).mask().is_bound2() ) { ! } else { + if (lrgs(lidx)._is_vector) { + if (lrgs(lidx).mask().is_bound_set(lrgs(lidx).num_regs())) + print_reg( lrgs(lidx).reg(), this, buf ); // a bound machine register + else sprintf(buf,"L%d",lidx); // No register binding yet } else { // Hah! We have a bound machine register + } else if( (lrgs(lidx).num_regs() == 1) + ? lrgs(lidx).mask().is_bound1() + : lrgs(lidx).mask().is_bound_pair() ) { + // Hah! We have a bound machine register print_reg( lrgs(lidx).reg(), this, buf ); + } else { + sprintf(buf,"L%d",lidx); // No register binding yet } } + } return buf+strlen(buf); } //----------------------dump_for_spill_split_recycle-------------------------- void PhaseChaitin::dump_for_spill_split_recycle() const {

src/share/vm/opto/chaitin.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File