#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
cl::desc("Avoid coalescing cross register class copies"),
cl::init(false), cl::Hidden);
-static cl::opt<bool>
-PhysJoinTweak("tweak-phys-join-heuristics",
- cl::desc("Tweak heuristics for joining phys reg with vr"),
- cl::init(false), cl::Hidden);
-
static RegisterPass<SimpleRegisterCoalescing>
X("simple-register-coalescing", "Simple Register Coalescing");
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() << "\t\tInterfere with sub-register ";
+ li_->getInterval(*SR).print(dbgs(), tri_);
});
return false;
}
}
DEBUG({
- errs() << "\nExtending: ";
- IntB.print(errs(), tri_);
+ dbgs() << "Extending: ";
+ IntB.print(dbgs(), tri_);
});
SlotIndex FillerStart = ValLR->end, FillerEnd = BLR->start;
// We are about to delete CopyMI, so need to remove it as the 'instruction
- // that defines this value #'. Update the the valnum with the new defining
+ // that defines this value #'. Update the valnum with the new defining
// instruction #.
BValNo->def = FillerStart;
BValNo->setCopy(0);
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
// If the copy instruction was killing the destination register before the
// merge, find the last use and trim the live range. That will also add the
// isKill marker.
- if (CopyMI->killsRegister(IntA.reg))
+ if (ALR->valno->isKill(CopyIdx))
TrimLiveIntervalToLastUse(CopyUseIdx, CopyMI->getParent(), IntA, ALR);
++numExtends;
for (; BI != IntB.ranges.end() && AI->end >= BI->start; ++BI) {
if (BI->valno == BValNo)
continue;
+ // When BValNo is null, we're looking for a dummy clobber-value for a subreg.
+ if (!BValNo && !BI->valno->isDefAccurate() && !BI->valno->getCopy())
+ continue;
if (BI->start <= AI->start && BI->end > AI->start)
return true;
if (BI->start > AI->start && BI->start < AI->end)
if (HasOtherReachingDefs(IntA, IntB, AValNo, BValNo))
return false;
+ bool BHasSubRegs = false;
+ if (TargetRegisterInfo::isPhysicalRegister(IntB.reg))
+ BHasSubRegs = *tri_->getSubRegisters(IntB.reg);
+
+ // Abort if the subregisters of IntB.reg have values that are not simply the
+ // clobbers from the superreg.
+ if (BHasSubRegs)
+ for (const unsigned *SR = tri_->getSubRegisters(IntB.reg); *SR; ++SR)
+ if (HasOtherReachingDefs(IntA, li_->getInterval(*SR), AValNo, 0))
+ return false;
+
// If some of the uses of IntA.reg is already coalesced away, return false.
// It's not possible to determine whether it's safe to perform the coalescing.
- for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(IntA.reg),
- UE = mri_->use_end(); UI != UE; ++UI) {
+ for (MachineRegisterInfo::use_nodbg_iterator UI =
+ mri_->use_nodbg_begin(IntA.reg),
+ UE = mri_->use_nodbg_end(); UI != UE; ++UI) {
MachineInstr *UseMI = &*UI;
SlotIndex UseIdx = li_->getInstructionIndex(UseMI);
LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx);
BExtend[ALR->end] = BLR->end;
// Update uses of IntA of the specific Val# with IntB.
- bool BHasSubRegs = false;
- if (TargetRegisterInfo::isPhysicalRegister(IntB.reg))
- BHasSubRegs = *tri_->getSubRegisters(IntB.reg);
for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(IntA.reg),
UE = mri_->use_end(); UI != UE;) {
MachineOperand &UseMO = UI.getOperand();
++UI;
if (JoinedCopies.count(UseMI))
continue;
+ if (UseMI->isDebugValue()) {
+ // FIXME These don't have an instruction index. Not clear we have enough
+ // info to decide whether to do this replacement or not. For now do it.
+ UseMO.setReg(NewReg);
+ continue;
+ }
SlotIndex UseIdx = li_->getInstructionIndex(UseMI).getUseIndex();
LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx);
if (ULR == IntA.end() || ULR->valno != AValNo)
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (!tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
continue;
- if (DstReg == IntB.reg) {
+ if (DstReg == IntB.reg && DstSubIdx == 0) {
// This copy will become a noop. If it's defining a new val#,
// remove that val# as well. However this live range is being
// extended to the end of the existing live range defined by the copy.
// 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() << "Extending: ";
+ 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() << "\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;
LR->valno->addKill(LastUseIdx.getDefIndex());
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (tii_->isMoveInstr(*LastUseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
- DstReg == li.reg) {
+ DstReg == li.reg && DstSubIdx == 0) {
// Last use is itself an identity code.
int DeadIdx = LastUseMI->findRegisterDefOperandIdx(li.reg, false, tri_);
LastUseMI->getOperand(DeadIdx).setIsDead();
if (!tii_->isTriviallyReMaterializable(DefMI, AA))
return false;
bool SawStore = false;
- if (!DefMI->isSafeToMove(tii_, SawStore, AA))
+ if (!DefMI->isSafeToMove(tii_, AA, SawStore))
return false;
if (TID.getNumDefs() != 1)
return false;
- if (DefMI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) {
+ if (!DefMI->isImplicitDef()) {
// Make sure the copy destination register class fits the instruction
// definition register class. The mismatch can happen as a result of earlier
// extract_subreg, insert_subreg, subreg_to_reg coalescing.
for (const unsigned* SR = tri_->getSubRegisters(DstReg); *SR; ++SR) {
if (!li_->hasInterval(*SR))
continue;
- DLR = li_->getInterval(*SR).getLiveRangeContaining(DefIdx);
+ const LiveRange *DLR =
+ li_->getInterval(*SR).getLiveRangeContaining(DefIdx);
if (DLR && DLR->valno->getCopy() == CopyMI)
DLR->valno->setCopy(0);
}
// kill.
bool checkForDeadDef = false;
MachineBasicBlock *MBB = CopyMI->getParent();
- if (CopyMI->killsRegister(SrcInt.reg))
+ if (SrcLR->valno->isKill(DefIdx))
if (!TrimLiveIntervalToLastUse(CopyIdx, MBB, SrcInt, SrcLR)) {
checkForDeadDef = true;
}
NewMI->addOperand(MO);
if (MO.isDef() && li_->hasInterval(MO.getReg())) {
unsigned Reg = MO.getReg();
- DLR = li_->getInterval(Reg).getLiveRangeContaining(DefIdx);
+ const LiveRange *DLR =
+ li_->getInterval(Reg).getLiveRangeContaining(DefIdx);
if (DLR && DLR->valno->getCopy() == CopyMI)
DLR->valno->setCopy(0);
+ // Handle subregs as well
+ if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
+ for (const unsigned* SR = tri_->getSubRegisters(Reg); *SR; ++SR) {
+ if (!li_->hasInterval(*SR))
+ continue;
+ const LiveRange *DLR =
+ li_->getInterval(*SR).getLiveRangeContaining(DefIdx);
+ if (DLR && DLR->valno->getCopy() == CopyMI)
+ DLR->valno->setCopy(0);
+ }
+ }
}
}
CopyMI->eraseFromParent();
ReMatCopies.insert(CopyMI);
ReMatDefs.insert(DefMI);
+ DEBUG(dbgs() << "Remat: " << *NewMI);
++NumReMats;
return true;
}
SubIdx = 0;
}
+ // Copy the register use-list before traversing it. We may be adding operands
+ // and invalidating pointers.
+ SmallVector<std::pair<MachineInstr*, unsigned>, 32> reglist;
for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(SrcReg),
- E = mri_->reg_end(); I != E; ) {
- MachineOperand &O = I.getOperand();
- MachineInstr *UseMI = &*I;
- ++I;
+ E = mri_->reg_end(); I != E; ++I)
+ reglist.push_back(std::make_pair(&*I, I.getOperandNo()));
+
+ for (unsigned N=0; N != reglist.size(); ++N) {
+ MachineInstr *UseMI = reglist[N].first;
+ MachineOperand &O = UseMI->getOperand(reglist[N].second);
unsigned OldSubIdx = O.getSubReg();
if (DstIsPhys) {
unsigned UseDstReg = DstReg;
unsigned CopySrcReg, CopyDstReg, CopySrcSubIdx, CopyDstSubIdx;
if (tii_->isMoveInstr(*UseMI, CopySrcReg, CopyDstReg,
CopySrcSubIdx, CopyDstSubIdx) &&
+ CopySrcSubIdx == 0 &&
+ CopyDstSubIdx == 0 &&
CopySrcReg != CopyDstReg &&
CopySrcReg == SrcReg && CopyDstReg != UseDstReg) {
// If the use is a copy and it won't be coalesced away, and its source
// is defined by a trivial computation, try to rematerialize it instead.
- if (ReMaterializeTrivialDef(li_->getInterval(SrcReg), CopyDstReg,
+ if (!JoinedCopies.count(UseMI) &&
+ ReMaterializeTrivialDef(li_->getInterval(SrcReg), CopyDstReg,
CopyDstSubIdx, UseMI))
continue;
}
O.setReg(UseDstReg);
O.setSubReg(0);
+ if (OldSubIdx) {
+ // Def and kill of subregister of a virtual register actually defs and
+ // kills the whole register. Add imp-defs and imp-kills as needed.
+ if (O.isDef()) {
+ if(O.isDead())
+ UseMI->addRegisterDead(DstReg, tri_, true);
+ else
+ UseMI->addRegisterDefined(DstReg, tri_);
+ } else if (!O.isUndef() &&
+ (O.isKill() ||
+ UseMI->isRegTiedToDefOperand(&O-&UseMI->getOperand(0))))
+ UseMI->addRegisterKilled(DstReg, tri_, true);
+ }
+ DEBUG(dbgs() << "\t\tupdated: " << li_->getInstructionIndex(UseMI)
+ << "\t" << *UseMI);
continue;
}
assert(OldSubIdx < SubIdx && "Conflicting sub-register index!");
else if (SubIdx)
O.setSubReg(SubIdx);
- // Remove would-be duplicated kill marker.
- if (O.isKill() && UseMI->killsRegister(DstReg))
- O.setIsKill(false);
O.setReg(DstReg);
+ DEBUG(dbgs() << "\t\tupdated: " << li_->getInstructionIndex(UseMI)
+ << "\t" << *UseMI);
+
// After updating the operand, check if the machine instruction has
// become a copy. If so, update its val# information.
if (JoinedCopies.count(UseMI))
}
}
-/// RemoveUnnecessaryKills - Remove kill markers that are no longer accurate
-/// due to live range lengthening as the result of coalescing.
-void SimpleRegisterCoalescing::RemoveUnnecessaryKills(unsigned Reg,
- LiveInterval &LI) {
- for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
- UE = mri_->use_end(); UI != UE; ++UI) {
- MachineOperand &UseMO = UI.getOperand();
- if (!UseMO.isKill())
- continue;
- MachineInstr *UseMI = UseMO.getParent();
- SlotIndex UseIdx =
- li_->getInstructionIndex(UseMI).getUseIndex();
- const LiveRange *LR = LI.getLiveRangeContaining(UseIdx);
- if (!LR ||
- (!LR->valno->isKill(UseIdx.getDefIndex()) &&
- LR->valno->def != UseIdx.getDefIndex())) {
- // Interesting problem. After coalescing reg1027's def and kill are both
- // at the same point: %reg1027,0.000000e+00 = [56,814:0) 0@70-(814)
- //
- // bb5:
- // 60 %reg1027<def> = t2MOVr %reg1027, 14, %reg0, %reg0
- // 68 %reg1027<def> = t2LDRi12 %reg1027<kill>, 8, 14, %reg0
- // 76 t2CMPzri %reg1038<kill,undef>, 0, 14, %reg0, %CPSR<imp-def>
- // 84 %reg1027<def> = t2MOVr %reg1027, 14, %reg0, %reg0
- // 96 t2Bcc mbb<bb5,0x2030910>, 1, %CPSR<kill>
- //
- // Do not remove the kill marker on t2LDRi12.
- UseMO.setIsKill(false);
- }
- }
-}
-
/// removeIntervalIfEmpty - Check if the live interval of a physical register
/// is empty, if so remove it and also remove the empty intervals of its
/// sub-registers. Return true if live interval is removed.
unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
unsigned Length = li_->getApproximateInstructionCount(DstInt);
if (Length > Threshold &&
- (((float)std::distance(mri_->use_begin(DstInt.reg),
- mri_->use_end()) / Length) < (1.0 / Threshold)))
+ std::distance(mri_->use_nodbg_begin(DstInt.reg),
+ mri_->use_nodbg_end()) * Threshold < Length)
return false;
// If the virtual register live interval extends into a loop, turn down
if (SuccMBB == CopyMBB)
continue;
if (DstInt.overlaps(li_->getMBBStartIdx(SuccMBB),
- li_->getMBBEndIdx(SuccMBB).getNextIndex().getBaseIndex()))
+ li_->getMBBEndIdx(SuccMBB)))
return false;
}
}
MachineBasicBlock *CopyMBB,
LiveInterval &DstInt,
LiveInterval &SrcInt) {
- // If the virtual register live interval is long but it has low use desity,
+ // If the virtual register live interval is long but it has low use density,
// do not join them, instead mark the physical register as its allocation
// preference.
const TargetRegisterClass *RC = mri_->getRegClass(SrcInt.reg);
unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
unsigned Length = li_->getApproximateInstructionCount(SrcInt);
if (Length > Threshold &&
- (((float)std::distance(mri_->use_begin(SrcInt.reg),
- mri_->use_end()) / Length) < (1.0 / Threshold)))
+ std::distance(mri_->use_nodbg_begin(SrcInt.reg),
+ mri_->use_nodbg_end()) * Threshold < Length)
return false;
if (SrcInt.empty())
if (PredMBB == SMBB)
continue;
if (SrcInt.overlaps(li_->getMBBStartIdx(PredMBB),
- li_->getMBBEndIdx(PredMBB).getNextIndex().getBaseIndex()))
+ li_->getMBBEndIdx(PredMBB)))
return false;
}
}
/// isWinToJoinCrossClass - Return true if it's profitable to coalesce
/// two virtual registers from different register classes.
bool
-SimpleRegisterCoalescing::isWinToJoinCrossClass(unsigned LargeReg,
- unsigned SmallReg,
- unsigned Threshold) {
- // Then make sure the intervals are *short*.
- LiveInterval &LargeInt = li_->getInterval(LargeReg);
- LiveInterval &SmallInt = li_->getInterval(SmallReg);
- unsigned LargeSize = li_->getApproximateInstructionCount(LargeInt);
- unsigned SmallSize = li_->getApproximateInstructionCount(SmallInt);
- if (SmallSize > Threshold || LargeSize > Threshold)
- if ((float)std::distance(mri_->use_begin(SmallReg),
- mri_->use_end()) / SmallSize <
- (float)std::distance(mri_->use_begin(LargeReg),
- mri_->use_end()) / LargeSize)
+SimpleRegisterCoalescing::isWinToJoinCrossClass(unsigned SrcReg,
+ unsigned DstReg,
+ const TargetRegisterClass *SrcRC,
+ const TargetRegisterClass *DstRC,
+ const TargetRegisterClass *NewRC) {
+ unsigned NewRCCount = allocatableRCRegs_[NewRC].count();
+ // This heuristics is good enough in practice, but it's obviously not *right*.
+ // 4 is a magic number that works well enough for x86, ARM, etc. It filter
+ // out all but the most restrictive register classes.
+ if (NewRCCount > 4 ||
+ // Early exit if the function is fairly small, coalesce aggressively if
+ // that's the case. For really special register classes with 3 or
+ // fewer registers, be a bit more careful.
+ (li_->getFuncInstructionCount() / NewRCCount) < 8)
+ return true;
+ LiveInterval &SrcInt = li_->getInterval(SrcReg);
+ LiveInterval &DstInt = li_->getInterval(DstReg);
+ unsigned SrcSize = li_->getApproximateInstructionCount(SrcInt);
+ unsigned DstSize = li_->getApproximateInstructionCount(DstInt);
+ if (SrcSize <= NewRCCount && DstSize <= NewRCCount)
+ return true;
+ // Estimate *register use density*. If it doubles or more, abort.
+ unsigned SrcUses = std::distance(mri_->use_nodbg_begin(SrcReg),
+ mri_->use_nodbg_end());
+ unsigned DstUses = std::distance(mri_->use_nodbg_begin(DstReg),
+ mri_->use_nodbg_end());
+ unsigned NewUses = SrcUses + DstUses;
+ unsigned NewSize = SrcSize + DstSize;
+ if (SrcRC != NewRC && SrcSize > NewRCCount) {
+ unsigned SrcRCCount = allocatableRCRegs_[SrcRC].count();
+ if (NewUses*SrcSize*SrcRCCount > 2*SrcUses*NewSize*NewRCCount)
return false;
+ }
+ if (DstRC != NewRC && DstSize > NewRCCount) {
+ unsigned DstRCCount = allocatableRCRegs_[DstRC].count();
+ if (NewUses*DstSize*DstRCCount > 2*DstUses*NewSize*NewRCCount)
+ return false;
+ }
return true;
}
for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(VirtReg),
E = mri_->reg_end(); I != E; ++I) {
MachineOperand &O = I.getOperand();
+ if (O.isDebug())
+ continue;
MachineInstr *MI = &*I;
if (MI == CopyMI || JoinedCopies.count(MI))
continue;
unsigned SubIdx = O.getSubReg();
if (SubIdx && !tri_->getSubReg(PhysReg, SubIdx))
return true;
- if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ if (MI->isExtractSubreg()) {
SubIdx = MI->getOperand(2).getImm();
if (O.isUse() && !tri_->getSubReg(PhysReg, SubIdx))
return true;
return true;
}
}
- if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) {
+ if (MI->isInsertSubreg() || MI->isSubregToReg()) {
SubIdx = MI->getOperand(3).getImm();
if (VirtReg == MI->getOperand(0).getReg()) {
if (!tri_->getSubReg(PhysReg, SubIdx))
unsigned &RealDstReg) {
const TargetRegisterClass *RC = mri_->getRegClass(SrcReg);
RealDstReg = tri_->getMatchingSuperReg(DstReg, SubIdx, RC);
- assert(RealDstReg && "Invalid extract_subreg instruction!");
+ if (!RealDstReg) {
+ DEBUG(dbgs() << "\tIncompatible source regclass: "
+ << "none of the super-registers of " << tri_->getName(DstReg)
+ << " are in " << RC->getName() << ".\n");
+ return false;
+ }
+ LiveInterval &RHS = li_->getInterval(SrcReg);
// For this type of EXTRACT_SUBREG, conservatively
// check if the live interval of the source register interfere with the
// actual super physical register we are trying to coalesce with.
- LiveInterval &RHS = li_->getInterval(SrcReg);
if (li_->hasInterval(RealDstReg) &&
RHS.overlaps(li_->getInterval(RealDstReg))) {
DEBUG({
- errs() << "Interfere with register ";
- li_->getInterval(RealDstReg).print(errs(), tri_);
+ dbgs() << "\t\tInterfere 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))) {
+ // Do not check DstReg or its sub-register. JoinIntervals() will take care
+ // of that.
+ if (*SR != DstReg &&
+ !tri_->isSubRegister(DstReg, *SR) &&
+ li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) {
DEBUG({
- errs() << "Interfere with sub-register ";
- li_->getInterval(*SR).print(errs(), tri_);
+ dbgs() << "\t\tInterfere with sub-register ";
+ li_->getInterval(*SR).print(dbgs(), tri_);
});
return false; // Not coalescable
}
unsigned &RealSrcReg) {
const TargetRegisterClass *RC = mri_->getRegClass(DstReg);
RealSrcReg = tri_->getMatchingSuperReg(SrcReg, SubIdx, RC);
- assert(RealSrcReg && "Invalid extract_subreg instruction!");
+ if (!RealSrcReg) {
+ DEBUG(dbgs() << "\tIncompatible destination regclass: "
+ << "none of the super-registers of " << tri_->getName(SrcReg)
+ << " are in " << RC->getName() << ".\n");
+ return false;
+ }
- LiveInterval &RHS = li_->getInterval(DstReg);
+ LiveInterval &LHS = li_->getInterval(DstReg);
if (li_->hasInterval(RealSrcReg) &&
- RHS.overlaps(li_->getInterval(RealSrcReg))) {
+ LHS.overlaps(li_->getInterval(RealSrcReg))) {
DEBUG({
- errs() << "Interfere with register ";
- li_->getInterval(RealSrcReg).print(errs(), tri_);
+ dbgs() << "\t\tInterfere 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))) {
+ // Do not check SrcReg or its sub-register. JoinIntervals() will take care
+ // of that.
+ if (*SR != SrcReg &&
+ !tri_->isSubRegister(SrcReg, *SR) &&
+ li_->hasInterval(*SR) && LHS.overlaps(li_->getInterval(*SR))) {
DEBUG({
- errs() << "Interfere with sub-register ";
- li_->getInterval(*SR).print(errs(), tri_);
+ dbgs() << "\t\tInterfere 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;
- bool isInsSubReg = CopyMI->getOpcode() == TargetInstrInfo::INSERT_SUBREG;
- bool isSubRegToReg = CopyMI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG;
+ bool isExtSubReg = CopyMI->isExtractSubreg();
+ bool isInsSubReg = CopyMI->isInsertSubreg();
+ bool isSubRegToReg = CopyMI->isSubregToReg();
unsigned SubIdx = 0;
if (isExtSubReg) {
DstReg = CopyMI->getOperand(0).getReg();
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.
}
- } else if (!tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)){
+ } else if (tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
+ if (SrcSubIdx && DstSubIdx && SrcSubIdx != DstSubIdx) {
+ // e.g. %reg16404:1<def> = MOV8rr %reg16412:2<kill>
+ Again = true;
+ return false; // Not coalescable.
+ }
+ } else {
llvm_unreachable("Unrecognized copy instruction!");
}
// 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.
}
+ // We cannot handle dual subreg indices and mismatched classes at the same
+ // time.
+ if (SrcSubIdx && DstSubIdx && differingRegisterClasses(SrcReg, DstReg)) {
+ DEBUG(dbgs() << "\tCannot handle subreg indices and mismatched classes.\n");
+ return false;
+ }
+
// Check that a physical source register is compatible with dst regclass
if (SrcIsPhys) {
unsigned SrcSubReg = SrcSubIdx ?
DstSubRC = DstRC->getSubRegisterRegClass(DstSubIdx);
assert(DstSubRC && "Illegal subregister index");
if (!DstSubRC->contains(SrcSubReg)) {
- DEBUG(errs() << "\tIncompatible destination regclass: "
- << tri_->getName(SrcSubReg) << " not in "
+ DEBUG(dbgs() << "\tIncompatible destination regclass: "
+ << "none of the super-registers of "
+ << tri_->getName(SrcSubReg) << " are 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: "
- << tri_->getName(DstSubReg) << " not in "
+ DEBUG(dbgs() << "\tIncompatible source regclass: "
+ << "none of the super-registers of "
+ << tri_->getName(DstSubReg) << " are in "
<< SrcSubRC->getName() << ".\n");
(void)DstSubReg;
return false; // Not coalescable.
const TargetRegisterClass *SrcRC= SrcIsPhys ? 0 : mri_->getRegClass(SrcReg);
const TargetRegisterClass *DstRC= DstIsPhys ? 0 : mri_->getRegClass(DstReg);
const TargetRegisterClass *NewRC = NULL;
- MachineBasicBlock *CopyMBB = CopyMI->getParent();
unsigned RealDstReg = 0;
unsigned RealSrcReg = 0;
if (isExtSubReg || isInsSubReg || isSubRegToReg) {
// 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.
}
+ // FIXME: The following checks are somewhat conservative. Perhaps a better
+ // way to implement this is to treat this as coalescing a vr with the
+ // super physical register.
if (isExtSubReg) {
if (!CanJoinExtractSubRegToPhysReg(DstReg, SrcReg, SubIdx, RealDstReg))
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
}
- unsigned LargeReg = isExtSubReg ? SrcReg : DstReg;
- unsigned SmallReg = isExtSubReg ? DstReg : SrcReg;
- unsigned Limit= allocatableRCRegs_[mri_->getRegClass(SmallReg)].count();
- if (!isWinToJoinCrossClass(LargeReg, SmallReg, Limit)) {
+ if (!isWinToJoinCrossClass(SrcReg, DstReg, SrcRC, DstRC, NewRC)) {
+ DEBUG(dbgs() << "\tAvoid coalescing to constrained register class: "
+ << SrcRC->getName() << "/"
+ << DstRC->getName() << " -> "
+ << NewRC->getName() << ".\n");
Again = true; // May be possible to coalesce later.
return false;
}
}
}
- unsigned LargeReg = SrcReg;
- unsigned SmallReg = DstReg;
-
// Now determine the register class of the joined register.
- if (isExtSubReg) {
- if (SubIdx && DstRC && DstRC->isASubClass()) {
- // This is a move to a sub-register class. However, the source is a
- // sub-register of a larger register class. We don't know what should
- // the register class be. FIXME.
- Again = true;
- return false;
+ if (!SrcIsPhys && !DstIsPhys) {
+ if (isExtSubReg) {
+ NewRC =
+ SubIdx ? tri_->getMatchingSuperRegClass(SrcRC, DstRC, SubIdx) : SrcRC;
+ } else if (isInsSubReg) {
+ NewRC =
+ SubIdx ? tri_->getMatchingSuperRegClass(DstRC, SrcRC, SubIdx) : DstRC;
+ } else {
+ NewRC = getCommonSubClass(SrcRC, DstRC);
}
- if (!DstIsPhys && !SrcIsPhys)
- NewRC = SrcRC;
- } 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.
}
- if (DstRC->getSize() > SrcRC->getSize())
- std::swap(LargeReg, SmallReg);
- }
- // If we are joining two virtual registers and the resulting register
- // class is more restrictive (fewer register, smaller size). Check if it's
- // worth doing the merge.
- if (!SrcIsPhys && !DstIsPhys &&
- (isExtSubReg || DstRC->isASubClass()) &&
- !isWinToJoinCrossClass(LargeReg, SmallReg,
- allocatableRCRegs_[NewRC].count())) {
- DEBUG(errs() << "\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
- // But later r1024 is assigned EAX then r1025 may be coalesced with EAX.
- Again = true; // May be possible to coalesce later.
- return false;
+ // If we are joining two virtual registers and the resulting register
+ // class is more restrictive (fewer register, smaller size). Check if it's
+ // worth doing the merge.
+ if (!isWinToJoinCrossClass(SrcReg, DstReg, SrcRC, DstRC, NewRC)) {
+ DEBUG(dbgs() << "\tAvoid coalescing to constrained register class: "
+ << SrcRC->getName() << "/"
+ << DstRC->getName() << " -> "
+ << NewRC->getName() << ".\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
+ // But later r1024 is assigned EAX then r1025 may be coalesced with EAX.
+ Again = true; // May be possible to coalesce later.
+ return false;
+ }
}
}
"Register mapping is horribly broken!");
DEBUG({
- errs() << "\t\tInspecting "; SrcInt.print(errs(), tri_);
- errs() << " and "; DstInt.print(errs(), tri_);
- errs() << ": ";
+ dbgs() << "\t\tInspecting ";
+ if (SrcRC) dbgs() << SrcRC->getName() << ": ";
+ SrcInt.print(dbgs(), tri_);
+ dbgs() << "\n\t\t and ";
+ if (DstRC) dbgs() << DstRC->getName() << ": ";
+ DstInt.print(dbgs(), tri_);
+ dbgs() << "\n";
});
// Save a copy of the virtual register live interval. We'll manually
// merge this into the "real" physical register live interval this is
// coalesced with.
- LiveInterval *SavedLI = 0;
+ OwningPtr<LiveInterval> SavedLI;
if (RealDstReg)
- SavedLI = li_->dupInterval(&SrcInt);
+ SavedLI.reset(li_->dupInterval(&SrcInt));
else if (RealSrcReg)
- SavedLI = li_->dupInterval(&DstInt);
+ SavedLI.reset(li_->dupInterval(&DstInt));
- // Check if it is necessary to propagate "isDead" property.
if (!isExtSubReg && !isInsSubReg && !isSubRegToReg) {
+ // Check if it is necessary to propagate "isDead" property.
MachineOperand *mopd = CopyMI->findRegisterDefOperand(DstReg, false);
bool isDead = mopd->isDead();
// these are not spillable! If the destination interval uses are far away,
// think twice about coalescing them!
if (!isDead && (SrcIsPhys || DstIsPhys)) {
- // If the copy is in a loop, take care not to coalesce aggressively if the
- // src is coming in from outside the loop (or the dst is out of the loop).
- // If it's not in a loop, then determine whether to join them base purely
- // by the length of the interval.
- if (PhysJoinTweak) {
- if (SrcIsPhys) {
- if (!isWinToJoinVRWithSrcPhysReg(CopyMI, CopyMBB, DstInt, SrcInt)) {
- mri_->setRegAllocationHint(DstInt.reg, 0, SrcReg);
- ++numAborts;
- DEBUG(errs() << "\tMay tie down a physical register, abort!\n");
- Again = true; // May be possible to coalesce later.
- return false;
- }
- } else {
- if (!isWinToJoinVRWithDstPhysReg(CopyMI, CopyMBB, DstInt, SrcInt)) {
- mri_->setRegAllocationHint(SrcInt.reg, 0, DstReg);
- ++numAborts;
- DEBUG(errs() << "\tMay tie down a physical register, abort!\n");
- Again = true; // May be possible to coalesce later.
- return false;
- }
- }
- } else {
- // If the virtual register live interval is long but it has low use
- // density, do not join them, instead mark the physical register as its
- // allocation preference.
- LiveInterval &JoinVInt = SrcIsPhys ? DstInt : SrcInt;
- unsigned JoinVReg = SrcIsPhys ? DstReg : SrcReg;
- unsigned JoinPReg = SrcIsPhys ? SrcReg : DstReg;
- const TargetRegisterClass *RC = mri_->getRegClass(JoinVReg);
- unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
- unsigned Length = li_->getApproximateInstructionCount(JoinVInt);
- float Ratio = 1.0 / Threshold;
- if (Length > Threshold &&
- (((float)std::distance(mri_->use_begin(JoinVReg),
- mri_->use_end()) / Length) < Ratio)) {
- mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
- ++numAborts;
- DEBUG(errs() << "\tMay tie down a physical register, abort!\n");
- Again = true; // May be possible to coalesce later.
- return false;
- }
+ // If the virtual register live interval is long but it has low use
+ // density, do not join them, instead mark the physical register as its
+ // allocation preference.
+ LiveInterval &JoinVInt = SrcIsPhys ? DstInt : SrcInt;
+ LiveInterval &JoinPInt = SrcIsPhys ? SrcInt : DstInt;
+ unsigned JoinVReg = SrcIsPhys ? DstReg : SrcReg;
+ unsigned JoinPReg = SrcIsPhys ? SrcReg : DstReg;
+
+ // Don't join with physregs that have a ridiculous number of live
+ // ranges. The data structure performance is really bad when that
+ // happens.
+ if (JoinPInt.ranges.size() > 1000) {
+ mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
+ ++numAborts;
+ DEBUG(dbgs()
+ << "\tPhysical register live interval too complicated, abort!\n");
+ return false;
+ }
+
+ const TargetRegisterClass *RC = mri_->getRegClass(JoinVReg);
+ unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
+ unsigned Length = li_->getApproximateInstructionCount(JoinVInt);
+ if (Length > Threshold &&
+ std::distance(mri_->use_nodbg_begin(JoinVReg),
+ mri_->use_nodbg_end()) * Threshold < Length) {
+ // Before giving up coalescing, if definition of source is defined by
+ // trivial computation, try rematerializing it.
+ if (ReMaterializeTrivialDef(SrcInt, DstReg, DstSubIdx, CopyMI))
+ return true;
+
+ mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
+ ++numAborts;
+ DEBUG(dbgs() << "\tMay tie down a physical register, abort!\n");
+ Again = true; // May be possible to coalesce later.
+ return false;
}
}
}
// been modified, so we can use this information below to update aliases.
bool Swapped = false;
// If SrcInt is implicitly defined, it's safe to coalesce.
- bool isEmpty = SrcInt.empty();
- if (isEmpty && !CanCoalesceWithImpDef(CopyMI, DstInt, SrcInt)) {
- // 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");
- return false;
- }
-
- if (!isEmpty && !JoinIntervals(DstInt, SrcInt, Swapped)) {
+ if (SrcInt.empty()) {
+ if (!CanCoalesceWithImpDef(CopyMI, DstInt, SrcInt)) {
+ // 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(dbgs() << "\tNot profitable!\n");
+ return false;
+ }
+ } else if (!JoinIntervals(DstInt, SrcInt, Swapped)) {
// Coalescing failed.
// If definition of source is defined by trivial computation, try
(AdjustCopiesBackFrom(SrcInt, DstInt, CopyMI) ||
RemoveCopyByCommutingDef(SrcInt, DstInt, CopyMI))) {
JoinedCopies.insert(CopyMI);
+ DEBUG(dbgs() << "\tTrivial!\n");
return true;
}
// Otherwise, we are unable to join the intervals.
- DEBUG(errs() << "Interference!\n");
+ DEBUG(dbgs() << "\tInterference!\n");
Again = true; // May be possible to coalesce later.
return false;
}
// Remember to delete the copy instruction.
JoinedCopies.insert(CopyMI);
- // Some live range has been lengthened due to colaescing, eliminate the
- // unnecessary kills.
- RemoveUnnecessaryKills(SrcReg, *ResDstInt);
- if (TargetRegisterInfo::isVirtualRegister(DstReg))
- RemoveUnnecessaryKills(DstReg, *ResDstInt);
-
UpdateRegDefsUses(SrcReg, DstReg, SubIdx);
+ // If we have extended the live range of a physical register, make sure we
+ // update live-in lists as well.
+ if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
+ const LiveInterval &VRegInterval = li_->getInterval(SrcReg);
+ SmallVector<MachineBasicBlock*, 16> BlockSeq;
+ for (LiveInterval::const_iterator I = VRegInterval.begin(),
+ E = VRegInterval.end(); I != E; ++I ) {
+ li_->findLiveInMBBs(I->start, I->end, BlockSeq);
+ for (unsigned idx = 0, size = BlockSeq.size(); idx != size; ++idx) {
+ MachineBasicBlock &block = *BlockSeq[idx];
+ if (!block.isLiveIn(DstReg))
+ block.addLiveIn(DstReg);
+ }
+ BlockSeq.clear();
+ }
+ }
+
// SrcReg is guarateed to be the register whose live interval that is
// being merged.
li_->removeInterval(SrcReg);
// Manually deleted the live interval copy.
if (SavedLI) {
SavedLI->clear();
- delete SavedLI;
+ SavedLI.reset();
}
// If resulting interval has a preference that no longer fits because of subreg
}
DEBUG({
- errs() << "\n\t\tJoined. Result = ";
- ResDstInt->print(errs(), tri_);
- errs() << "\n";
+ dbgs() << "\t\tJoined. Result = ";
+ ResDstInt->print(dbgs(), tri_);
+ dbgs() << "\n";
});
++numJoins;
// If the VN has already been computed, just return it.
if (ThisValNoAssignments[VN] >= 0)
return ThisValNoAssignments[VN];
-// assert(ThisValNoAssignments[VN] != -2 && "Cyclic case?");
+ assert(ThisValNoAssignments[VN] != -2 && "Cyclic value numbers");
// If this val is not a copy from the other val, then it must be a new value
// number in the destination.
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
;
- else if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ else if (MI->isExtractSubreg()) {
DstReg = MI->getOperand(0).getReg();
SrcReg = MI->getOperand(1).getReg();
- } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
- MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
+ } else if (MI->isSubregToReg() ||
+ MI->isInsertSubreg()) {
DstReg = MI->getOperand(0).getReg();
SrcReg = MI->getOperand(2).getReg();
} else
li_->intervalIsInOneMBB(RHS) &&
li_->getApproximateInstructionCount(RHS) <= 10) {
// Perform a more exhaustive check for some common cases.
- if (li_->conflictsWithPhysRegRef(RHS, LHS.reg, true, JoinedCopies))
+ if (li_->conflictsWithSubPhysRegRef(RHS, LHS.reg, true, JoinedCopies))
return false;
} else {
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() << "\tInterfere with sub-register ";
+ li_->getInterval(*SR).print(dbgs(), tri_);
});
return false;
}
if (LHS.containsOneValue() &&
li_->getApproximateInstructionCount(LHS) <= 10) {
// Perform a more exhaustive check for some common cases.
- if (li_->conflictsWithPhysRegRef(LHS, RHS.reg, false, JoinedCopies))
+ if (li_->conflictsWithSubPhysRegRef(LHS, RHS.reg, false, JoinedCopies))
return false;
} else {
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() << "\tInterfere 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;
// If this isn't a copy nor a extract_subreg, we can't join intervals.
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
- if (Inst->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ bool isInsUndef = false;
+ if (Inst->isExtractSubreg()) {
DstReg = Inst->getOperand(0).getReg();
SrcReg = Inst->getOperand(1).getReg();
- } else if (Inst->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- Inst->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) {
+ } else if (Inst->isInsertSubreg()) {
+ DstReg = Inst->getOperand(0).getReg();
+ SrcReg = Inst->getOperand(2).getReg();
+ if (Inst->getOperand(1).isUndef())
+ isInsUndef = true;
+ } else if (Inst->isInsertSubreg() || Inst->isSubregToReg()) {
DstReg = Inst->getOperand(0).getReg();
SrcReg = Inst->getOperand(2).getReg();
} else if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
bool SrcIsPhys = TargetRegisterInfo::isPhysicalRegister(SrcReg);
bool DstIsPhys = TargetRegisterInfo::isPhysicalRegister(DstReg);
- if (li_->hasInterval(SrcReg) && li_->getInterval(SrcReg).empty())
+ if (isInsUndef ||
+ (li_->hasInterval(SrcReg) && li_->getInterval(SrcReg).empty()))
ImpDefCopies.push_back(CopyRec(Inst, 0));
else if (SrcIsPhys || DstIsPhys)
PhysCopies.push_back(CopyRec(Inst, 0));
VirtCopies.push_back(CopyRec(Inst, 0));
}
- // Try coalescing implicit copies first, followed by copies to / from
- // physical registers, then finally copies from virtual registers to
- // virtual registers.
+ // Try coalescing implicit copies and insert_subreg <undef> first,
+ // followed by copies to / from physical registers, then finally copies
+ // from virtual registers to virtual registers.
for (unsigned i = 0, e = ImpDefCopies.size(); i != e; ++i) {
CopyRec &TheCopy = ImpDefCopies[i];
bool Again = false;
}
void SimpleRegisterCoalescing::joinIntervals() {
- DEBUG(errs() << "********** JOINING INTERVALS ***********\n");
+ DEBUG(dbgs() << "********** JOINING INTERVALS ***********\n");
std::vector<CopyRec> TryAgainList;
if (loopInfo->empty()) {
return !RegClassA->contains(RegB);
}
-/// lastRegisterUse - Returns the last use of the specific register between
-/// cycles Start and End or NULL if there are no uses.
+/// lastRegisterUse - Returns the last (non-debug) use of the specific register
+/// between cycles Start and End or NULL if there are no uses.
MachineOperand *
SimpleRegisterCoalescing::lastRegisterUse(SlotIndex Start,
SlotIndex End,
UseIdx = SlotIndex();
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
MachineOperand *LastUse = NULL;
- for (MachineRegisterInfo::use_iterator I = mri_->use_begin(Reg),
- E = mri_->use_end(); I != E; ++I) {
+ for (MachineRegisterInfo::use_nodbg_iterator I = mri_->use_nodbg_begin(Reg),
+ E = mri_->use_nodbg_end(); I != E; ++I) {
MachineOperand &Use = I.getOperand();
MachineInstr *UseMI = Use.getParent();
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
- SrcReg == DstReg)
+ SrcReg == DstReg && SrcSubIdx == DstSubIdx)
// Ignore identity copies.
continue;
SlotIndex Idx = li_->getInstructionIndex(UseMI);
// Ignore identity copies.
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (!(tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
- SrcReg == DstReg))
+ SrcReg == DstReg && SrcSubIdx == DstSubIdx))
for (unsigned i = 0, NumOps = MI->getNumOperands(); i != NumOps; ++i) {
MachineOperand &Use = MI->getOperand(i);
if (Use.isReg() && Use.isUse() && Use.getReg() &&
return NULL;
}
-
-void SimpleRegisterCoalescing::printRegName(unsigned reg) const {
- if (TargetRegisterInfo::isPhysicalRegister(reg))
- errs() << tri_->getName(reg);
- else
- errs() << "%reg" << reg;
-}
-
void SimpleRegisterCoalescing::releaseMemory() {
JoinedCopies.clear();
ReMatCopies.clear();
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";
}
});
}
// Delete all coalesced copies.
bool DoDelete = true;
if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
- assert((MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
- MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) &&
- "Unrecognized copy instruction");
+ assert((MI->isExtractSubreg() || MI->isInsertSubreg() ||
+ MI->isSubregToReg()) && "Unrecognized copy instruction");
DstReg = MI->getOperand(0).getReg();
if (TargetRegisterInfo::isPhysicalRegister(DstReg))
// Do not delete extract_subreg, insert_subreg of physical
// delete them later.
DoDelete = false;
}
- if (MI->registerDefIsDead(DstReg)) {
+ if (MI->allDefsAreDead()) {
LiveInterval &li = li_->getInterval(DstReg);
if (!ShortenDeadCopySrcLiveRange(li, MI))
ShortenDeadCopyLiveRange(li, MI);
if (MO.isDead())
continue;
if (TargetRegisterInfo::isPhysicalRegister(Reg) ||
- !mri_->use_empty(Reg)) {
+ !mri_->use_nodbg_empty(Reg)) {
isDead = false;
break;
}
// If the move will be an identity move delete it
bool isMove= tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx);
- if (isMove && SrcReg == DstReg) {
+ if (isMove && SrcReg == DstReg && SrcSubIdx == DstSubIdx) {
if (li_->hasInterval(SrcReg)) {
LiveInterval &RegInt = li_->getInterval(SrcReg);
// If def of this move instruction is dead, remove its live range
li_->RemoveMachineInstrFromMaps(MI);
mii = mbbi->erase(mii);
++numPeep;
- } else {
- ++mii;
+ continue;
+ }
+
+ ++mii;
+
+ // Check for now unnecessary kill flags.
+ if (li_->isNotInMIMap(MI)) continue;
+ SlotIndex UseIdx = li_->getInstructionIndex(MI).getUseIndex();
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.isKill()) continue;
+ unsigned reg = MO.getReg();
+ if (!reg || !li_->hasInterval(reg)) continue;
+ LiveInterval &LI = li_->getInterval(reg);
+ const LiveRange *LR = LI.getLiveRangeContaining(UseIdx);
+ if (!LR ||
+ (!LR->valno->isKill(UseIdx.getDefIndex()) &&
+ LR->valno->def != UseIdx.getDefIndex()))
+ MO.setIsKill(false);
}
}
}
- CalculateSpillWeights();
-
DEBUG(dump());
return true;
}