for (const unsigned* SR = tri_->getSubRegisters(IntB.reg); *SR; ++SR)
if (li_->hasInterval(*SR) && IntA.overlaps(li_->getInterval(*SR))) {
DEBUG({
- errs() << "Interfere with sub-register ";
- li_->getInterval(*SR).print(errs(), tri_);
+ dbgs() << "Interfere with sub-register ";
+ li_->getInterval(*SR).print(dbgs(), tri_);
});
return false;
}
}
DEBUG({
- errs() << "\nExtending: ";
- IntB.print(errs(), tri_);
+ dbgs() << "\nExtending: ";
+ IntB.print(dbgs(), tri_);
});
SlotIndex FillerStart = ValLR->end, FillerEnd = BLR->start;
IntB.MergeValueNumberInto(BValNo, ValLR->valno);
}
DEBUG({
- errs() << " result = ";
- IntB.print(errs(), tri_);
- errs() << "\n";
+ dbgs() << " result = ";
+ IntB.print(dbgs(), tri_);
+ dbgs() << "\n";
});
// If the source instruction was killing the source register before the
// We need to insert a new liverange: [ALR.start, LastUse). It may be we can
// simply extend BLR if CopyMI doesn't end the range.
DEBUG({
- errs() << "\nExtending: ";
- IntB.print(errs(), tri_);
+ dbgs() << "\nExtending: ";
+ IntB.print(dbgs(), tri_);
});
// Remove val#'s defined by copies that will be coalesced away.
ValNo->setHasPHIKill(BHasPHIKill);
DEBUG({
- errs() << " result = ";
- IntB.print(errs(), tri_);
- errs() << '\n';
- errs() << "\nShortening: ";
- IntA.print(errs(), tri_);
+ dbgs() << " result = ";
+ IntB.print(dbgs(), tri_);
+ dbgs() << '\n';
+ dbgs() << "\nShortening: ";
+ IntA.print(dbgs(), tri_);
});
IntA.removeValNo(AValNo);
DEBUG({
- errs() << " result = ";
- IntA.print(errs(), tri_);
- errs() << '\n';
+ dbgs() << " result = ";
+ IntA.print(dbgs(), tri_);
+ dbgs() << '\n';
});
++numCommutes;
if (SuccMBB == CopyMBB)
continue;
if (DstInt.overlaps(li_->getMBBStartIdx(SuccMBB),
- li_->getMBBEndIdx(SuccMBB).getNextIndex().getBaseIndex()))
+ li_->getMBBEndIdx(SuccMBB)))
return false;
}
}
if (PredMBB == SMBB)
continue;
if (SrcInt.overlaps(li_->getMBBStartIdx(PredMBB),
- li_->getMBBEndIdx(PredMBB).getNextIndex().getBaseIndex()))
+ li_->getMBBEndIdx(PredMBB)))
return false;
}
}
if (li_->hasInterval(RealDstReg) &&
RHS.overlaps(li_->getInterval(RealDstReg))) {
DEBUG({
- errs() << "Interfere with register ";
- li_->getInterval(RealDstReg).print(errs(), tri_);
+ dbgs() << "Interfere with register ";
+ li_->getInterval(RealDstReg).print(dbgs(), tri_);
});
return false; // Not coalescable
}
for (const unsigned* SR = tri_->getSubRegisters(RealDstReg); *SR; ++SR)
if (li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) {
DEBUG({
- errs() << "Interfere with sub-register ";
- li_->getInterval(*SR).print(errs(), tri_);
+ dbgs() << "Interfere with sub-register ";
+ li_->getInterval(*SR).print(dbgs(), tri_);
});
return false; // Not coalescable
}
if (li_->hasInterval(RealSrcReg) &&
RHS.overlaps(li_->getInterval(RealSrcReg))) {
DEBUG({
- errs() << "Interfere with register ";
- li_->getInterval(RealSrcReg).print(errs(), tri_);
+ dbgs() << "Interfere with register ";
+ li_->getInterval(RealSrcReg).print(dbgs(), tri_);
});
return false; // Not coalescable
}
for (const unsigned* SR = tri_->getSubRegisters(RealSrcReg); *SR; ++SR)
if (li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) {
DEBUG({
- errs() << "Interfere with sub-register ";
- li_->getInterval(*SR).print(errs(), tri_);
+ dbgs() << "Interfere with sub-register ";
+ li_->getInterval(*SR).print(dbgs(), tri_);
});
return false; // Not coalescable
}
if (JoinedCopies.count(CopyMI) || ReMatCopies.count(CopyMI))
return false; // Already done.
- DEBUG(errs() << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI);
+ DEBUG(dbgs() << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI);
unsigned SrcReg, DstReg, SrcSubIdx = 0, DstSubIdx = 0;
bool isExtSubReg = CopyMI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG;
if (SrcSubIdx && SrcSubIdx != DstSubIdx) {
// r1025 = INSERT_SUBREG r1025, r1024<2>, 2 Then r1024 has already been
// coalesced to a larger register so the subreg indices cancel out.
- DEBUG(errs() << "\tSource of insert_subreg or subreg_to_reg is already "
+ DEBUG(dbgs() << "\tSource of insert_subreg or subreg_to_reg is already "
"coalesced to another register.\n");
return false; // Not coalescable.
}
// If they are already joined we continue.
if (SrcReg == DstReg) {
- DEBUG(errs() << "\tCopy already coalesced.\n");
+ DEBUG(dbgs() << "\tCopy already coalesced.\n");
return false; // Not coalescable.
}
// If they are both physical registers, we cannot join them.
if (SrcIsPhys && DstIsPhys) {
- DEBUG(errs() << "\tCan not coalesce physregs.\n");
+ DEBUG(dbgs() << "\tCan not coalesce physregs.\n");
return false; // Not coalescable.
}
// We only join virtual registers with allocatable physical registers.
if (SrcIsPhys && !allocatableRegs_[SrcReg]) {
- DEBUG(errs() << "\tSrc reg is unallocatable physreg.\n");
+ DEBUG(dbgs() << "\tSrc reg is unallocatable physreg.\n");
return false; // Not coalescable.
}
if (DstIsPhys && !allocatableRegs_[DstReg]) {
- DEBUG(errs() << "\tDst reg is unallocatable physreg.\n");
+ DEBUG(dbgs() << "\tDst reg is unallocatable physreg.\n");
return false; // Not coalescable.
}
DstSubRC = DstRC->getSubRegisterRegClass(DstSubIdx);
assert(DstSubRC && "Illegal subregister index");
if (!DstSubRC->contains(SrcSubReg)) {
- DEBUG(errs() << "\tIncompatible destination regclass: "
+ DEBUG(dbgs() << "\tIncompatible destination regclass: "
<< tri_->getName(SrcSubReg) << " not in "
<< DstSubRC->getName() << ".\n");
return false; // Not coalescable.
SrcSubRC = SrcRC->getSubRegisterRegClass(SrcSubIdx);
assert(SrcSubRC && "Illegal subregister index");
if (!SrcSubRC->contains(DstSubReg)) {
- DEBUG(errs() << "\tIncompatible source regclass: "
+ DEBUG(dbgs() << "\tIncompatible source regclass: "
<< tri_->getName(DstSubReg) << " not in "
<< SrcSubRC->getName() << ".\n");
(void)DstSubReg;
// r1024<2> = EXTRACT_SUBREG EAX, 2. Then r1024 has already been
// coalesced to a larger register so the subreg indices cancel out.
if (DstSubIdx != SubIdx) {
- DEBUG(errs() << "\t Sub-register indices mismatch.\n");
+ DEBUG(dbgs() << "\t Sub-register indices mismatch.\n");
return false; // Not coalescable.
}
} else
// EAX = INSERT_SUBREG EAX, r1024<2>, 2 Then r1024 has already been
// coalesced to a larger register so the subreg indices cancel out.
if (SrcSubIdx != SubIdx) {
- DEBUG(errs() << "\t Sub-register indices mismatch.\n");
+ DEBUG(dbgs() << "\t Sub-register indices mismatch.\n");
return false; // Not coalescable.
}
} else
} else if ((DstIsPhys && isExtSubReg) ||
(SrcIsPhys && (isInsSubReg || isSubRegToReg))) {
if (!isSubRegToReg && CopyMI->getOperand(1).getSubReg()) {
- DEBUG(errs() << "\tSrc of extract_subreg already coalesced with reg"
+ DEBUG(dbgs() << "\tSrc of extract_subreg already coalesced with reg"
<< " of a super-class.\n");
return false; // Not coalescable.
}
// class as the would be resulting register.
SubIdx = 0;
else {
- DEBUG(errs() << "\t Sub-register indices mismatch.\n");
+ DEBUG(dbgs() << "\t Sub-register indices mismatch.\n");
return false; // Not coalescable.
}
}
NewRC = tri_->getMatchingSuperRegClass(SrcRC, DstRC, SubIdx);
}
if (!NewRC) {
- DEBUG(errs() << "\t Conflicting sub-register indices.\n");
+ DEBUG(dbgs() << "\t Conflicting sub-register indices.\n");
return false; // Not coalescable
}
} else if (!SrcIsPhys && !DstIsPhys) {
NewRC = getCommonSubClass(SrcRC, DstRC);
if (!NewRC) {
- DEBUG(errs() << "\tDisjoint regclasses: "
+ DEBUG(dbgs() << "\tDisjoint regclasses: "
<< SrcRC->getName() << ", "
<< DstRC->getName() << ".\n");
return false; // Not coalescable.
(isExtSubReg || DstRC->isASubClass()) &&
!isWinToJoinCrossClass(LargeReg, SmallReg,
allocatableRCRegs_[NewRC].count())) {
- DEBUG(errs() << "\tSrc/Dest are different register classes.\n");
+ DEBUG(dbgs() << "\tSrc/Dest are different register classes.\n");
// Allow the coalescer to try again in case either side gets coalesced to
// a physical register that's compatible with the other side. e.g.
// r1024 = MOV32to32_ r1025
"Register mapping is horribly broken!");
DEBUG({
- errs() << "\t\tInspecting "; SrcInt.print(errs(), tri_);
- errs() << " and "; DstInt.print(errs(), tri_);
- errs() << ": ";
+ dbgs() << "\t\tInspecting "; SrcInt.print(dbgs(), tri_);
+ dbgs() << " and "; DstInt.print(dbgs(), tri_);
+ dbgs() << ": ";
});
// Save a copy of the virtual register live interval. We'll manually
if (!isWinToJoinVRWithSrcPhysReg(CopyMI, CopyMBB, DstInt, SrcInt)) {
mri_->setRegAllocationHint(DstInt.reg, 0, SrcReg);
++numAborts;
- DEBUG(errs() << "\tMay tie down a physical register, abort!\n");
+ DEBUG(dbgs() << "\tMay tie down a physical register, abort!\n");
Again = true; // May be possible to coalesce later.
return false;
}
if (!isWinToJoinVRWithDstPhysReg(CopyMI, CopyMBB, DstInt, SrcInt)) {
mri_->setRegAllocationHint(SrcInt.reg, 0, DstReg);
++numAborts;
- DEBUG(errs() << "\tMay tie down a physical register, abort!\n");
+ DEBUG(dbgs() << "\tMay tie down a physical register, abort!\n");
Again = true; // May be possible to coalesce later.
return false;
}
mri_->use_end()) / Length) < Ratio)) {
mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
++numAborts;
- DEBUG(errs() << "\tMay tie down a physical register, abort!\n");
+ DEBUG(dbgs() << "\tMay tie down a physical register, abort!\n");
Again = true; // May be possible to coalesce later.
return false;
}
// Only coalesce an empty interval (defined by implicit_def) with
// another interval which has a valno defined by the CopyMI and the CopyMI
// is a kill of the implicit def.
- DEBUG(errs() << "Not profitable!\n");
+ DEBUG(dbgs() << "Not profitable!\n");
return false;
}
}
// Otherwise, we are unable to join the intervals.
- DEBUG(errs() << "Interference!\n");
+ DEBUG(dbgs() << "Interference!\n");
Again = true; // May be possible to coalesce later.
return false;
}
}
DEBUG({
- errs() << "\n\t\tJoined. Result = ";
- ResDstInt->print(errs(), tri_);
- errs() << "\n";
+ dbgs() << "\n\t\tJoined. Result = ";
+ ResDstInt->print(dbgs(), tri_);
+ dbgs() << "\n";
});
++numJoins;
for (const unsigned* SR = tri_->getSubRegisters(LHS.reg); *SR; ++SR)
if (li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) {
DEBUG({
- errs() << "Interfere with sub-register ";
- li_->getInterval(*SR).print(errs(), tri_);
+ dbgs() << "Interfere with sub-register ";
+ li_->getInterval(*SR).print(dbgs(), tri_);
});
return false;
}
for (const unsigned* SR = tri_->getSubRegisters(RHS.reg); *SR; ++SR)
if (li_->hasInterval(*SR) && LHS.overlaps(li_->getInterval(*SR))) {
DEBUG({
- errs() << "Interfere with sub-register ";
- li_->getInterval(*SR).print(errs(), tri_);
+ dbgs() << "Interfere with sub-register ";
+ li_->getInterval(*SR).print(dbgs(), tri_);
});
return false;
}
continue;
// Figure out the value # from the RHS.
- LHSValsDefinedFromRHS[VNI]=
- RHS.getLiveRangeContaining(VNI->def.getPrevSlot())->valno;
+ LiveRange *lr = RHS.getLiveRangeContaining(VNI->def.getPrevSlot());
+ assert(lr && "Cannot find live range");
+ LHSValsDefinedFromRHS[VNI] = lr->valno;
}
// Loop over the value numbers of the RHS, seeing if any are defined from
continue;
// Figure out the value # from the LHS.
- RHSValsDefinedFromLHS[VNI]=
- LHS.getLiveRangeContaining(VNI->def.getPrevSlot())->valno;
+ LiveRange *lr = LHS.getLiveRangeContaining(VNI->def.getPrevSlot());
+ assert(lr && "Cannot find live range");
+ RHSValsDefinedFromLHS[VNI] = lr->valno;
}
LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
std::vector<CopyRec> &TryAgain) {
- DEBUG(errs() << MBB->getName() << ":\n");
+ DEBUG(dbgs() << MBB->getName() << ":\n");
std::vector<CopyRec> VirtCopies;
std::vector<CopyRec> PhysCopies;
}
void SimpleRegisterCoalescing::joinIntervals() {
- DEBUG(errs() << "********** JOINING INTERVALS ***********\n");
+ DEBUG(dbgs() << "********** JOINING INTERVALS ***********\n");
std::vector<CopyRec> TryAgainList;
if (loopInfo->empty()) {
return NULL;
}
-
void SimpleRegisterCoalescing::printRegName(unsigned reg) const {
if (TargetRegisterInfo::isPhysicalRegister(reg))
- errs() << tri_->getName(reg);
+ dbgs() << tri_->getName(reg);
else
- errs() << "%reg" << reg;
+ dbgs() << "%reg" << reg;
}
void SimpleRegisterCoalescing::releaseMemory() {
ReMatDefs.clear();
}
-/// Returns true if the given live interval is zero length.
-static bool isZeroLengthInterval(LiveInterval *li, LiveIntervals *li_) {
- for (LiveInterval::Ranges::const_iterator
- i = li->ranges.begin(), e = li->ranges.end(); i != e; ++i)
- if (i->end.getPrevIndex() > i->start)
- return false;
- return true;
-}
-
-
-void SimpleRegisterCoalescing::CalculateSpillWeights() {
- SmallSet<unsigned, 4> Processed;
- for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
- mbbi != mbbe; ++mbbi) {
- MachineBasicBlock* MBB = mbbi;
- SlotIndex MBBEnd = li_->getMBBEndIdx(MBB);
- MachineLoop* loop = loopInfo->getLoopFor(MBB);
- unsigned loopDepth = loop ? loop->getLoopDepth() : 0;
- bool isExiting = loop ? loop->isLoopExiting(MBB) : false;
-
- for (MachineBasicBlock::const_iterator mii = MBB->begin(), mie = MBB->end();
- mii != mie; ++mii) {
- const MachineInstr *MI = mii;
- if (tii_->isIdentityCopy(*MI))
- continue;
-
- if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
- continue;
-
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- const MachineOperand &mopi = MI->getOperand(i);
- if (!mopi.isReg() || mopi.getReg() == 0)
- continue;
- unsigned Reg = mopi.getReg();
- if (!TargetRegisterInfo::isVirtualRegister(mopi.getReg()))
- continue;
- // Multiple uses of reg by the same instruction. It should not
- // contribute to spill weight again.
- if (!Processed.insert(Reg))
- continue;
-
- bool HasDef = mopi.isDef();
- bool HasUse = !HasDef;
- for (unsigned j = i+1; j != e; ++j) {
- const MachineOperand &mopj = MI->getOperand(j);
- if (!mopj.isReg() || mopj.getReg() != Reg)
- continue;
- HasDef |= mopj.isDef();
- HasUse |= mopj.isUse();
- if (HasDef && HasUse)
- break;
- }
-
- LiveInterval &RegInt = li_->getInterval(Reg);
- float Weight = li_->getSpillWeight(HasDef, HasUse, loopDepth);
- if (HasDef && isExiting) {
- // Looks like this is a loop count variable update.
- SlotIndex DefIdx = li_->getInstructionIndex(MI).getDefIndex();
- const LiveRange *DLR =
- li_->getInterval(Reg).getLiveRangeContaining(DefIdx);
- if (DLR->end > MBBEnd)
- Weight *= 3.0F;
- }
- RegInt.weight += Weight;
- }
- Processed.clear();
- }
- }
-
- for (LiveIntervals::iterator I = li_->begin(), E = li_->end(); I != E; ++I) {
- LiveInterval &LI = *I->second;
- if (TargetRegisterInfo::isVirtualRegister(LI.reg)) {
- // If the live interval length is essentially zero, i.e. in every live
- // range the use follows def immediately, it doesn't make sense to spill
- // it and hope it will be easier to allocate for this li.
- if (isZeroLengthInterval(&LI, li_)) {
- LI.weight = HUGE_VALF;
- continue;
- }
-
- bool isLoad = false;
- SmallVector<LiveInterval*, 4> SpillIs;
- if (li_->isReMaterializable(LI, SpillIs, isLoad)) {
- // If all of the definitions of the interval are re-materializable,
- // it is a preferred candidate for spilling. If non of the defs are
- // loads, then it's potentially very cheap to re-materialize.
- // FIXME: this gets much more complicated once we support non-trivial
- // re-materialization.
- if (isLoad)
- LI.weight *= 0.9F;
- else
- LI.weight *= 0.5F;
- }
-
- // Slightly prefer live interval that has been assigned a preferred reg.
- std::pair<unsigned, unsigned> Hint = mri_->getRegAllocationHint(LI.reg);
- if (Hint.first || Hint.second)
- LI.weight *= 1.01F;
-
- // Divide the weight of the interval by its size. This encourages
- // spilling of intervals that are large and have few uses, and
- // discourages spilling of small intervals with many uses.
- LI.weight /= li_->getApproximateInstructionCount(LI) * InstrSlots::NUM;
- }
- }
-}
-
-
bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
mf_ = &fn;
mri_ = &fn.getRegInfo();
AA = &getAnalysis<AliasAnalysis>();
loopInfo = &getAnalysis<MachineLoopInfo>();
- DEBUG(errs() << "********** SIMPLE REGISTER COALESCING **********\n"
+ DEBUG(dbgs() << "********** SIMPLE REGISTER COALESCING **********\n"
<< "********** Function: "
<< ((Value*)mf_->getFunction())->getName() << '\n');
if (EnableJoining) {
joinIntervals();
DEBUG({
- errs() << "********** INTERVALS POST JOINING **********\n";
+ dbgs() << "********** INTERVALS POST JOINING **********\n";
for (LiveIntervals::iterator I = li_->begin(), E = li_->end();
I != E; ++I){
- I->second->print(errs(), tri_);
- errs() << "\n";
+ I->second->print(dbgs(), tri_);
+ dbgs() << "\n";
}
});
}
}
}
- CalculateSpillWeights();
-
DEBUG(dump());
return true;
}