#include "VirtRegMap.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/Value.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
void SimpleRegisterCoalescing::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
+ AU.addRequired<AliasAnalysis>();
AU.addRequired<LiveIntervals>();
AU.addPreserved<LiveIntervals>();
+ AU.addPreserved<SlotIndexes>();
AU.addRequired<MachineLoopInfo>();
AU.addPreserved<MachineLoopInfo>();
AU.addPreservedID(MachineDominatorsID);
bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA,
LiveInterval &IntB,
MachineInstr *CopyMI) {
- MachineInstrIndex CopyIdx = li_->getDefIndex(li_->getInstructionIndex(CopyMI));
+ SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI).getDefIndex();
// BValNo is a value number in B that is defined by a copy from A. 'B3' in
// the example above.
assert(BValNo->def == CopyIdx && "Copy doesn't define the value?");
// AValNo is the value number in A that defines the copy, A3 in the example.
- MachineInstrIndex CopyUseIdx = li_->getUseIndex(CopyIdx);
+ SlotIndex CopyUseIdx = CopyIdx.getUseIndex();
LiveInterval::iterator ALR = IntA.FindLiveRangeContaining(CopyUseIdx);
assert(ALR != IntA.end() && "Live range not found!");
VNInfo *AValNo = ALR->valno;
// See PR3149:
// 172 %ECX<def> = MOV32rr %reg1039<kill>
// 180 INLINEASM <es:subl $5,$1
- // sbbl $3,$0>, 10, %EAX<def>, 14, %ECX<earlyclobber,def>, 9, %EAX<kill>,
+ // sbbl $3,$0>, 10, %EAX<def>, 14, %ECX<earlyclobber,def>, 9,
+ // %EAX<kill>,
// 36, <fi#0>, 1, %reg0, 0, 9, %ECX<kill>, 36, <fi#1>, 1, %reg0, 0
// 188 %EAX<def> = MOV32rr %EAX<kill>
// 196 %ECX<def> = MOV32rr %ECX<kill>
// Get the LiveRange in IntB that this value number starts with.
LiveInterval::iterator ValLR =
- IntB.FindLiveRangeContaining(li_->getPrevSlot(AValNo->def));
+ IntB.FindLiveRangeContaining(AValNo->def.getPrevSlot());
assert(ValLR != IntB.end() && "Live range not found!");
// Make sure that the end of the live range is inside the same block as
// CopyMI.
MachineInstr *ValLREndInst =
- li_->getInstructionFromIndex(li_->getPrevSlot(ValLR->end));
+ li_->getInstructionFromIndex(ValLR->end.getPrevSlot());
if (!ValLREndInst ||
ValLREndInst->getParent() != CopyMI->getParent()) return false;
IntB.print(errs(), tri_);
});
- MachineInstrIndex FillerStart = ValLR->end, FillerEnd = BLR->start;
+ 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
// instruction #.
return false;
}
-/// RemoveCopyByCommutingDef - We found a non-trivially-coalescable copy with IntA
-/// being the source and IntB being the dest, thus this defines a value number
-/// in IntB. If the source value number (in IntA) is defined by a commutable
-/// instruction and its other operand is coalesced to the copy dest register,
-/// see if we can transform the copy into a noop by commuting the definition. For
-/// example,
+static void
+TransferImplicitOps(MachineInstr *MI, MachineInstr *NewMI) {
+ for (unsigned i = MI->getDesc().getNumOperands(), e = MI->getNumOperands();
+ i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isImplicit())
+ NewMI->addOperand(MO);
+ }
+}
+
+/// RemoveCopyByCommutingDef - We found a non-trivially-coalescable copy with
+/// IntA being the source and IntB being the dest, thus this defines a value
+/// number in IntB. If the source value number (in IntA) is defined by a
+/// commutable instruction and its other operand is coalesced to the copy dest
+/// register, see if we can transform the copy into a noop by commuting the
+/// definition. For example,
///
/// A3 = op A2 B0<kill>
/// ...
bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
LiveInterval &IntB,
MachineInstr *CopyMI) {
- MachineInstrIndex CopyIdx =
- li_->getDefIndex(li_->getInstructionIndex(CopyMI));
+ SlotIndex CopyIdx =
+ li_->getInstructionIndex(CopyMI).getDefIndex();
// FIXME: For now, only eliminate the copy by commuting its def when the
// source register is a virtual register. We want to guard against cases
// AValNo is the value number in A that defines the copy, A3 in the example.
LiveInterval::iterator ALR =
- IntA.FindLiveRangeContaining(li_->getPrevSlot(CopyIdx));
+ IntA.FindLiveRangeContaining(CopyIdx.getUseIndex()); //
assert(ALR != IntA.end() && "Live range not found!");
VNInfo *AValNo = ALR->valno;
for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(IntA.reg),
UE = mri_->use_end(); UI != UE; ++UI) {
MachineInstr *UseMI = &*UI;
- MachineInstrIndex UseIdx = li_->getInstructionIndex(UseMI);
+ SlotIndex UseIdx = li_->getInstructionIndex(UseMI);
LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx);
if (ULR == IntA.end())
continue;
bool BHasPHIKill = BValNo->hasPHIKill();
SmallVector<VNInfo*, 4> BDeadValNos;
VNInfo::KillSet BKills;
- std::map<MachineInstrIndex, MachineInstrIndex> BExtend;
+ std::map<SlotIndex, SlotIndex> BExtend;
// If ALR and BLR overlaps and end of BLR extends beyond end of ALR, e.g.
// A = or A, B
++UI;
if (JoinedCopies.count(UseMI))
continue;
- MachineInstrIndex UseIdx = li_->getInstructionIndex(UseMI);
+ SlotIndex UseIdx = li_->getInstructionIndex(UseMI).getUseIndex();
LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx);
if (ULR == IntA.end() || ULR->valno != AValNo)
continue;
if (Extended)
UseMO.setIsKill(false);
else
- BKills.push_back(li_->getNextSlot(li_->getUseIndex(UseIdx)));
+ BKills.push_back(UseIdx.getDefIndex());
}
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (!tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
// 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.
- MachineInstrIndex DefIdx = li_->getDefIndex(UseIdx);
+ SlotIndex DefIdx = UseIdx.getDefIndex();
const LiveRange *DLR = IntB.getLiveRangeContaining(DefIdx);
BHasPHIKill |= DLR->valno->hasPHIKill();
assert(DLR->valno->def == DefIdx);
for (LiveInterval::iterator AI = IntA.begin(), AE = IntA.end();
AI != AE; ++AI) {
if (AI->valno != AValNo) continue;
- MachineInstrIndex End = AI->end;
- std::map<MachineInstrIndex, MachineInstrIndex>::iterator
+ SlotIndex End = AI->end;
+ std::map<SlotIndex, SlotIndex>::iterator
EI = BExtend.find(End);
if (EI != BExtend.end())
End = EI->second;
if (BHasSubRegs) {
for (const unsigned *SR = tri_->getSubRegisters(IntB.reg); *SR; ++SR) {
LiveInterval &SRLI = li_->getInterval(*SR);
- SRLI.MergeInClobberRange(AI->start, End, li_->getVNInfoAllocator());
+ SRLI.MergeInClobberRange(*li_, AI->start, End,
+ li_->getVNInfoAllocator());
}
}
}
/// from a physical register live interval as well as from the live intervals
/// of its sub-registers.
static void removeRange(LiveInterval &li,
- MachineInstrIndex Start, MachineInstrIndex End,
+ SlotIndex Start, SlotIndex End,
LiveIntervals *li_, const TargetRegisterInfo *tri_) {
li.removeRange(Start, End, true);
if (TargetRegisterInfo::isPhysicalRegister(li.reg)) {
if (!li_->hasInterval(*SR))
continue;
LiveInterval &sli = li_->getInterval(*SR);
- MachineInstrIndex RemoveStart = Start;
- MachineInstrIndex RemoveEnd = Start;
+ SlotIndex RemoveStart = Start;
+ SlotIndex RemoveEnd = Start;
+
while (RemoveEnd != End) {
LiveInterval::iterator LR = sli.FindLiveRangeContaining(RemoveStart);
if (LR == sli.end())
/// as the copy instruction, trim the live interval to the last use and return
/// true.
bool
-SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(MachineInstrIndex CopyIdx,
+SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(SlotIndex CopyIdx,
MachineBasicBlock *CopyMBB,
LiveInterval &li,
const LiveRange *LR) {
- MachineInstrIndex MBBStart = li_->getMBBStartIdx(CopyMBB);
- MachineInstrIndex LastUseIdx;
+ SlotIndex MBBStart = li_->getMBBStartIdx(CopyMBB);
+ SlotIndex LastUseIdx;
MachineOperand *LastUse =
- lastRegisterUse(LR->start, li_->getPrevSlot(CopyIdx), li.reg, LastUseIdx);
+ lastRegisterUse(LR->start, CopyIdx.getPrevSlot(), li.reg, LastUseIdx);
if (LastUse) {
MachineInstr *LastUseMI = LastUse->getParent();
if (!isSameOrFallThroughBB(LastUseMI->getParent(), CopyMBB, tii_)) {
// There are uses before the copy, just shorten the live range to the end
// of last use.
LastUse->setIsKill();
- removeRange(li, li_->getDefIndex(LastUseIdx), LR->end, li_, tri_);
- LR->valno->addKill(li_->getNextSlot(LastUseIdx));
+ removeRange(li, LastUseIdx.getDefIndex(), LR->end, li_, tri_);
+ LR->valno->addKill(LastUseIdx.getDefIndex());
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (tii_->isMoveInstr(*LastUseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
DstReg == li.reg) {
// Is it livein?
if (LR->start <= MBBStart && LR->end > MBBStart) {
- if (LR->start == MachineInstrIndex()) {
+ if (LR->start == li_->getZeroIndex()) {
assert(TargetRegisterInfo::isPhysicalRegister(li.reg));
// Live-in to the function but dead. Remove it from entry live-in set.
mf_->begin()->removeLiveIn(li.reg);
unsigned DstReg,
unsigned DstSubIdx,
MachineInstr *CopyMI) {
- MachineInstrIndex CopyIdx = li_->getUseIndex(li_->getInstructionIndex(CopyMI));
+ SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI).getUseIndex();
LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx);
assert(SrcLR != SrcInt.end() && "Live range not found!");
VNInfo *ValNo = SrcLR->valno;
const TargetInstrDesc &TID = DefMI->getDesc();
if (!TID.isAsCheapAsAMove())
return false;
- if (!DefMI->getDesc().isRematerializable() ||
- !tii_->isTriviallyReMaterializable(DefMI))
+ if (!tii_->isTriviallyReMaterializable(DefMI, AA))
return false;
bool SawStore = false;
- if (!DefMI->isSafeToMove(tii_, SawStore))
+ if (!DefMI->isSafeToMove(tii_, SawStore, AA))
return false;
if (TID.getNumDefs() != 1)
return false;
return false;
}
- MachineInstrIndex DefIdx = li_->getDefIndex(CopyIdx);
+ SlotIndex DefIdx = CopyIdx.getDefIndex();
const LiveRange *DLR= li_->getInterval(DstReg).getLiveRangeContaining(DefIdx);
DLR->valno->setCopy(0);
// Don't forget to update sub-register intervals.
checkForDeadDef = true;
}
- MachineBasicBlock::iterator MII = next(MachineBasicBlock::iterator(CopyMI));
- tii_->reMaterialize(*MBB, MII, DstReg, DstSubIdx, DefMI);
+ MachineBasicBlock::iterator MII =
+ llvm::next(MachineBasicBlock::iterator(CopyMI));
+ tii_->reMaterialize(*MBB, MII, DstReg, DstSubIdx, DefMI, tri_);
MachineInstr *NewMI = prior(MII);
if (checkForDeadDef) {
// should mark it dead:
if (DefMI->getParent() == MBB) {
DefMI->addRegisterDead(SrcInt.reg, tri_);
- SrcLR->end = li_->getNextSlot(SrcLR->start);
+ SrcLR->end = SrcLR->start.getNextSlot();
}
}
}
}
+ TransferImplicitOps(CopyMI, NewMI);
li_->ReplaceMachineInstrInMaps(CopyMI, NewMI);
CopyMI->eraseFromParent();
ReMatCopies.insert(CopyMI);
(TargetRegisterInfo::isVirtualRegister(CopyDstReg) ||
allocatableRegs_[CopyDstReg])) {
LiveInterval &LI = li_->getInterval(CopyDstReg);
- MachineInstrIndex DefIdx =
- li_->getDefIndex(li_->getInstructionIndex(UseMI));
+ SlotIndex DefIdx =
+ li_->getInstructionIndex(UseMI).getDefIndex();
if (const LiveRange *DLR = LI.getLiveRangeContaining(DefIdx)) {
if (DLR->valno->def == DefIdx)
DLR->valno->setCopy(UseMI);
if (!UseMO.isKill())
continue;
MachineInstr *UseMI = UseMO.getParent();
- MachineInstrIndex UseIdx =
- li_->getUseIndex(li_->getInstructionIndex(UseMI));
+ SlotIndex UseIdx =
+ li_->getInstructionIndex(UseMI).getUseIndex();
const LiveRange *LR = LI.getLiveRangeContaining(UseIdx);
- if (!LR || !LR->valno->isKill(li_->getNextSlot(UseIdx))) {
- if (LR->valno->def != li_->getNextSlot(UseIdx)) {
- // 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);
- }
+ 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);
}
}
}
/// Return true if live interval is removed.
bool SimpleRegisterCoalescing::ShortenDeadCopyLiveRange(LiveInterval &li,
MachineInstr *CopyMI) {
- MachineInstrIndex CopyIdx = li_->getInstructionIndex(CopyMI);
+ SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI);
LiveInterval::iterator MLR =
- li.FindLiveRangeContaining(li_->getDefIndex(CopyIdx));
+ li.FindLiveRangeContaining(CopyIdx.getDefIndex());
if (MLR == li.end())
return false; // Already removed by ShortenDeadCopySrcLiveRange.
- MachineInstrIndex RemoveStart = MLR->start;
- MachineInstrIndex RemoveEnd = MLR->end;
- MachineInstrIndex DefIdx = li_->getDefIndex(CopyIdx);
+ SlotIndex RemoveStart = MLR->start;
+ SlotIndex RemoveEnd = MLR->end;
+ SlotIndex DefIdx = CopyIdx.getDefIndex();
// Remove the liverange that's defined by this.
- if (RemoveStart == DefIdx && RemoveEnd == li_->getNextSlot(DefIdx)) {
+ if (RemoveStart == DefIdx && RemoveEnd == DefIdx.getStoreIndex()) {
removeRange(li, RemoveStart, RemoveEnd, li_, tri_);
return removeIntervalIfEmpty(li, li_, tri_);
}
/// the val# it defines. If the live interval becomes empty, remove it as well.
bool SimpleRegisterCoalescing::RemoveDeadDef(LiveInterval &li,
MachineInstr *DefMI) {
- MachineInstrIndex DefIdx = li_->getDefIndex(li_->getInstructionIndex(DefMI));
+ SlotIndex DefIdx = li_->getInstructionIndex(DefMI).getDefIndex();
LiveInterval::iterator MLR = li.FindLiveRangeContaining(DefIdx);
if (DefIdx != MLR->valno->def)
return false;
/// PropagateDeadness - Propagate the dead marker to the instruction which
/// defines the val#.
static void PropagateDeadness(LiveInterval &li, MachineInstr *CopyMI,
- MachineInstrIndex &LRStart, LiveIntervals *li_,
+ SlotIndex &LRStart, LiveIntervals *li_,
const TargetRegisterInfo* tri_) {
MachineInstr *DefMI =
- li_->getInstructionFromIndex(li_->getDefIndex(LRStart));
+ li_->getInstructionFromIndex(LRStart.getDefIndex());
if (DefMI && DefMI != CopyMI) {
int DeadIdx = DefMI->findRegisterDefOperandIdx(li.reg, false);
if (DeadIdx != -1)
DefMI->getOperand(DeadIdx).setIsDead();
else
DefMI->addOperand(MachineOperand::CreateReg(li.reg,
- true, true, false, true));
- LRStart = li_->getNextSlot(LRStart);
+ /*def*/true, /*implicit*/true, /*kill*/false, /*dead*/true));
+ LRStart = LRStart.getNextSlot();
}
}
bool
SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li,
MachineInstr *CopyMI) {
- MachineInstrIndex CopyIdx = li_->getInstructionIndex(CopyMI);
- if (CopyIdx == MachineInstrIndex()) {
+ SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI);
+ if (CopyIdx == SlotIndex()) {
// FIXME: special case: function live in. It can be a general case if the
// first instruction index starts at > 0 value.
assert(TargetRegisterInfo::isPhysicalRegister(li.reg));
}
LiveInterval::iterator LR =
- li.FindLiveRangeContaining(li_->getPrevSlot(CopyIdx));
+ li.FindLiveRangeContaining(CopyIdx.getPrevIndex().getStoreIndex());
if (LR == li.end())
// Livein but defined by a phi.
return false;
- MachineInstrIndex RemoveStart = LR->start;
- MachineInstrIndex RemoveEnd = li_->getNextSlot(li_->getDefIndex(CopyIdx));
+ SlotIndex RemoveStart = LR->start;
+ SlotIndex RemoveEnd = CopyIdx.getStoreIndex();
if (LR->end > RemoveEnd)
// More uses past this copy? Nothing to do.
return false;
// If the live range starts in another mbb and the copy mbb is not a fall
// through mbb, then we can only cut the range from the beginning of the
// copy mbb.
- RemoveStart = li_->getNextSlot(li_->getMBBStartIdx(CopyMBB));
+ RemoveStart = li_->getMBBStartIdx(CopyMBB).getNextIndex().getBaseIndex();
if (LR->valno->def == RemoveStart) {
// If the def MI defines the val# and this copy is the only kill of the
// If the virtual register live interval extends into a loop, turn down
// aggressiveness.
- MachineInstrIndex CopyIdx =
- li_->getDefIndex(li_->getInstructionIndex(CopyMI));
+ SlotIndex CopyIdx =
+ li_->getInstructionIndex(CopyMI).getDefIndex();
const MachineLoop *L = loopInfo->getLoopFor(CopyMBB);
if (!L) {
// Let's see if the virtual register live interval extends into the loop.
LiveInterval::iterator DLR = DstInt.FindLiveRangeContaining(CopyIdx);
assert(DLR != DstInt.end() && "Live range not found!");
- DLR = DstInt.FindLiveRangeContaining(li_->getNextSlot(DLR->end));
+ DLR = DstInt.FindLiveRangeContaining(DLR->end.getNextSlot());
if (DLR != DstInt.end()) {
CopyMBB = li_->getMBBFromIndex(DLR->start);
L = loopInfo->getLoopFor(CopyMBB);
if (!L || Length <= Threshold)
return true;
- MachineInstrIndex UseIdx = li_->getUseIndex(CopyIdx);
+ SlotIndex UseIdx = CopyIdx.getUseIndex();
LiveInterval::iterator SLR = SrcInt.FindLiveRangeContaining(UseIdx);
MachineBasicBlock *SMBB = li_->getMBBFromIndex(SLR->start);
if (loopInfo->getLoopFor(SMBB) != L) {
if (SuccMBB == CopyMBB)
continue;
if (DstInt.overlaps(li_->getMBBStartIdx(SuccMBB),
- li_->getNextSlot(li_->getMBBEndIdx(SuccMBB))))
+ li_->getMBBEndIdx(SuccMBB).getNextIndex().getBaseIndex()))
return false;
}
}
// If the virtual register live interval is defined or cross a loop, turn
// down aggressiveness.
- MachineInstrIndex CopyIdx =
- li_->getDefIndex(li_->getInstructionIndex(CopyMI));
- MachineInstrIndex UseIdx = li_->getUseIndex(CopyIdx);
+ SlotIndex CopyIdx =
+ li_->getInstructionIndex(CopyMI).getDefIndex();
+ SlotIndex UseIdx = CopyIdx.getUseIndex();
LiveInterval::iterator SLR = SrcInt.FindLiveRangeContaining(UseIdx);
assert(SLR != SrcInt.end() && "Live range not found!");
- SLR = SrcInt.FindLiveRangeContaining(li_->getPrevSlot(SLR->start));
+ SLR = SrcInt.FindLiveRangeContaining(SLR->start.getPrevSlot());
if (SLR == SrcInt.end())
return true;
MachineBasicBlock *SMBB = li_->getMBBFromIndex(SLR->start);
if (PredMBB == SMBB)
continue;
if (SrcInt.overlaps(li_->getMBBStartIdx(PredMBB),
- li_->getNextSlot(li_->getMBBEndIdx(PredMBB))))
+ li_->getMBBEndIdx(PredMBB).getNextIndex().getBaseIndex()))
return false;
}
}
"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 (SrcSubIdx)
SrcSubRC = SrcRC->getSubRegisterRegClass(SrcSubIdx);
assert(SrcSubRC && "Illegal subregister index");
- if (!SrcSubRC->contains(DstReg)) {
+ if (!SrcSubRC->contains(DstSubReg)) {
DEBUG(errs() << "\tIncompatible source regclass: "
<< tri_->getName(DstSubReg) << " not in "
<< SrcSubRC->getName() << ".\n");
}
}
} else {
- // If the virtual register live interval is long but it has low use desity,
- // do not join them, instead mark the physical register as its allocation
- // preference.
+ // 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;
// Update the liveintervals of sub-registers.
for (const unsigned *AS = tri_->getSubRegisters(DstReg); *AS; ++AS)
- li_->getOrCreateInterval(*AS).MergeInClobberRanges(*ResSrcInt,
+ li_->getOrCreateInterval(*AS).MergeInClobberRanges(*li_, *ResSrcInt,
li_->getVNInfoAllocator());
}
return std::find(V.begin(), V.end(), Val) != V.end();
}
+static bool isValNoDefMove(const MachineInstr *MI, unsigned DR, unsigned SR,
+ const TargetInstrInfo *TII,
+ const TargetRegisterInfo *TRI) {
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
+ ;
+ else if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ DstReg = MI->getOperand(0).getReg();
+ SrcReg = MI->getOperand(1).getReg();
+ } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
+ MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
+ DstReg = MI->getOperand(0).getReg();
+ SrcReg = MI->getOperand(2).getReg();
+ } else
+ return false;
+ return (SrcReg == SR || TRI->isSuperRegister(SR, SrcReg)) &&
+ (DstReg == DR || TRI->isSuperRegister(DR, DstReg));
+}
+
/// RangeIsDefinedByCopyFromReg - Return true if the specified live range of
/// the specified live interval is defined by a copy from the specified
/// register.
// It's a sub-register live interval, we may not have precise information.
// Re-compute it.
MachineInstr *DefMI = li_->getInstructionFromIndex(LR->start);
- unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
- if (DefMI &&
- tii_->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
- DstReg == li.reg && SrcReg == Reg) {
+ if (DefMI && isValNoDefMove(DefMI, li.reg, Reg, tii_, tri_)) {
// Cache computed info.
- LR->valno->def = LR->start;
+ LR->valno->def = LR->start;
LR->valno->setCopy(DefMI);
return true;
}
return false;
}
+
+/// ValueLiveAt - Return true if the LiveRange pointed to by the given
+/// iterator, or any subsequent range with the same value number,
+/// is live at the given point.
+bool SimpleRegisterCoalescing::ValueLiveAt(LiveInterval::iterator LRItr,
+ LiveInterval::iterator LREnd,
+ SlotIndex defPoint) const {
+ for (const VNInfo *valno = LRItr->valno;
+ (LRItr != LREnd) && (LRItr->valno == valno); ++LRItr) {
+ if (LRItr->contains(defPoint))
+ return true;
+ }
+
+ return false;
+}
+
+
/// SimpleJoin - Attempt to joint the specified interval into this one. The
/// caller of this method must guarantee that the RHS only contains a single
/// value number and that the RHS is not defined by a copy from this
if (Overlaps) {
// If we haven't already recorded that this value # is safe, check it.
if (!InVector(LHSIt->valno, EliminatedLHSVals)) {
+ // If it's re-defined by an early clobber somewhere in the live range,
+ // then conservatively abort coalescing.
+ if (LHSIt->valno->hasRedefByEC())
+ return false;
// Copy from the RHS?
if (!RangeIsDefinedByCopyFromReg(LHS, LHSIt, RHS.reg))
return false; // Nope, bail out.
- if (LHSIt->contains(RHSIt->valno->def))
+ if (ValueLiveAt(LHSIt, LHS.end(), RHSIt->valno->def))
// Here is an interesting situation:
// BB1:
// vr1025 = copy vr1024
// if coalescing succeeds. Just skip the liverange.
if (++LHSIt == LHSEnd) break;
} else {
+ // If it's re-defined by an early clobber somewhere in the live range,
+ // then conservatively abort coalescing.
+ if (LHSIt->valno->hasRedefByEC())
+ return false;
// Otherwise, if this is a copy from the RHS, mark it as being merged
// in.
if (RangeIsDefinedByCopyFromReg(LHS, LHSIt, RHS.reg)) {
- if (LHSIt->contains(RHSIt->valno->def))
+ if (ValueLiveAt(LHSIt, LHS.end(), RHSIt->valno->def))
// Here is an interesting situation:
// BB1:
// vr1025 = copy vr1024
// Update the liveintervals of sub-registers.
if (TargetRegisterInfo::isPhysicalRegister(LHS.reg))
for (const unsigned *AS = tri_->getSubRegisters(LHS.reg); *AS; ++AS)
- li_->getOrCreateInterval(*AS).MergeInClobberRanges(LHS,
+ li_->getOrCreateInterval(*AS).MergeInClobberRanges(*li_, LHS,
li_->getVNInfoAllocator());
return true;
} else {
// It was defined as a copy from the LHS, find out what value # it is.
RHSValNoInfo =
- LHS.getLiveRangeContaining(li_->getPrevSlot(RHSValNoInfo0->def))->valno;
+ LHS.getLiveRangeContaining(RHSValNoInfo0->def.getPrevSlot())->valno;
RHSValID = RHSValNoInfo->id;
RHSVal0DefinedFromLHS = RHSValID;
}
// Figure out the value # from the RHS.
LHSValsDefinedFromRHS[VNI]=
- RHS.getLiveRangeContaining(li_->getPrevSlot(VNI->def))->valno;
+ RHS.getLiveRangeContaining(VNI->def.getPrevSlot())->valno;
}
// Loop over the value numbers of the RHS, seeing if any are defined from
// Figure out the value # from the LHS.
RHSValsDefinedFromLHS[VNI]=
- LHS.getLiveRangeContaining(li_->getPrevSlot(VNI->def))->valno;
+ LHS.getLiveRangeContaining(VNI->def.getPrevSlot())->valno;
}
LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
if (LHSValNoAssignments[I->valno->id] !=
RHSValNoAssignments[J->valno->id])
return false;
+ // If it's re-defined by an early clobber somewhere in the live range,
+ // then conservatively abort coalescing.
+ if (NewVNInfo[LHSValNoAssignments[I->valno->id]]->hasRedefByEC())
+ return false;
}
if (I->end < J->end) {
struct DepthMBBCompare {
typedef std::pair<unsigned, MachineBasicBlock*> DepthMBBPair;
bool operator()(const DepthMBBPair &LHS, const DepthMBBPair &RHS) const {
- if (LHS.first > RHS.first) return true; // Deeper loops first
- return LHS.first == RHS.first &&
- LHS.second->getNumber() < RHS.second->getNumber();
+ // Deeper loops first
+ if (LHS.first != RHS.first)
+ return LHS.first > RHS.first;
+
+ // Prefer blocks that are more connected in the CFG. This takes care of
+ // the most difficult copies first while intervals are short.
+ unsigned cl = LHS.second->pred_size() + LHS.second->succ_size();
+ unsigned cr = RHS.second->pred_size() + RHS.second->succ_size();
+ if (cl != cr)
+ return cl > cr;
+
+ // As a last resort, sort by block number.
+ return LHS.second->getNumber() < RHS.second->getNumber();
}
};
}
void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
std::vector<CopyRec> &TryAgain) {
- DEBUG(errs() << ((Value*)MBB->getBasicBlock())->getName() << ":\n");
+ DEBUG(errs() << 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;
+ bool isInsUndef = false;
if (Inst->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
DstReg = Inst->getOperand(0).getReg();
SrcReg = Inst->getOperand(1).getReg();
+ } else if (Inst->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
+ DstReg = Inst->getOperand(0).getReg();
+ SrcReg = Inst->getOperand(2).getReg();
+ if (Inst->getOperand(1).isUndef())
+ isInsUndef = true;
} else if (Inst->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
Inst->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) {
DstReg = Inst->getOperand(0).getReg();
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;
/// lastRegisterUse - Returns the last use of the specific register between
/// cycles Start and End or NULL if there are no uses.
MachineOperand *
-SimpleRegisterCoalescing::lastRegisterUse(MachineInstrIndex Start,
- MachineInstrIndex End,
+SimpleRegisterCoalescing::lastRegisterUse(SlotIndex Start,
+ SlotIndex End,
unsigned Reg,
- MachineInstrIndex &UseIdx) const{
- UseIdx = MachineInstrIndex();
+ SlotIndex &UseIdx) const{
+ UseIdx = SlotIndex();
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
MachineOperand *LastUse = NULL;
for (MachineRegisterInfo::use_iterator I = mri_->use_begin(Reg),
SrcReg == DstReg)
// Ignore identity copies.
continue;
- MachineInstrIndex Idx = li_->getInstructionIndex(UseMI);
+ SlotIndex Idx = li_->getInstructionIndex(UseMI);
+ // FIXME: Should this be Idx != UseIdx? SlotIndex() will return something
+ // that compares higher than any other interval.
if (Idx >= Start && Idx < End && Idx >= UseIdx) {
LastUse = &Use;
- UseIdx = li_->getUseIndex(Idx);
+ UseIdx = Idx.getUseIndex();
}
}
return LastUse;
}
- MachineInstrIndex s = Start;
- MachineInstrIndex e = li_->getBaseIndex(li_->getPrevSlot(End));
+ SlotIndex s = Start;
+ SlotIndex e = End.getPrevSlot().getBaseIndex();
while (e >= s) {
// Skip deleted instructions
MachineInstr *MI = li_->getInstructionFromIndex(e);
- while (e != MachineInstrIndex() && li_->getPrevIndex(e) >= s && !MI) {
- e = li_->getPrevIndex(e);
+ while (e != SlotIndex() && e.getPrevIndex() >= s && !MI) {
+ e = e.getPrevIndex();
MI = li_->getInstructionFromIndex(e);
}
if (e < s || MI == NULL)
MachineOperand &Use = MI->getOperand(i);
if (Use.isReg() && Use.isUse() && Use.getReg() &&
tri_->regsOverlap(Use.getReg(), Reg)) {
- UseIdx = li_->getUseIndex(e);
+ UseIdx = e.getUseIndex();
return &Use;
}
}
- e = li_->getPrevIndex(e);
+ e = e.getPrevIndex();
}
return NULL;
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 (li_->getPrevIndex(i->end) > 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;
- MachineInstrIndex MBBEnd = li_->getMBBEndIdx(MBB);
- MachineLoop* loop = loopInfo->getLoopFor(MBB);
- unsigned loopDepth = loop ? loop->getLoopDepth() : 0;
- bool isExit = loop ? loop->isLoopExit(MBB) : false;
-
- for (MachineBasicBlock::iterator mii = MBB->begin(), mie = MBB->end();
- mii != mie; ++mii) {
- MachineInstr *MI = mii;
-
- 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 && isExit) {
- // Looks like this is a loop count variable update.
- MachineInstrIndex DefIdx =
- li_->getDefIndex(li_->getInstructionIndex(MI));
- 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();
tri_ = tm_->getRegisterInfo();
tii_ = tm_->getInstrInfo();
li_ = &getAnalysis<LiveIntervals>();
+ AA = &getAnalysis<AliasAnalysis>();
loopInfo = &getAnalysis<MachineLoopInfo>();
DEBUG(errs() << "********** SIMPLE REGISTER COALESCING **********\n"
joinIntervals();
DEBUG({
errs() << "********** INTERVALS POST JOINING **********\n";
- for (LiveIntervals::iterator I = li_->begin(), E = li_->end(); I != E; ++I){
+ for (LiveIntervals::iterator I = li_->begin(), E = li_->end();
+ I != E; ++I){
I->second->print(errs(), tri_);
errs() << "\n";
}
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (JoinedCopies.count(MI)) {
// 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");
DstReg = MI->getOperand(0).getReg();
+ if (TargetRegisterInfo::isPhysicalRegister(DstReg))
+ // Do not delete extract_subreg, insert_subreg of physical
+ // registers unless the definition is dead. e.g.
+ // %DO<def> = INSERT_SUBREG %D0<undef>, %S0<kill>, 1
+ // or else the scavenger may complain. LowerSubregs will
+ // delete them later.
+ DoDelete = false;
}
if (MI->registerDefIsDead(DstReg)) {
LiveInterval &li = li_->getInterval(DstReg);
if (!ShortenDeadCopySrcLiveRange(li, MI))
ShortenDeadCopyLiveRange(li, MI);
+ DoDelete = true;
+ }
+ if (!DoDelete)
+ mii = llvm::next(mii);
+ else {
+ li_->RemoveMachineInstrFromMaps(MI);
+ mii = mbbi->erase(mii);
+ ++numPeep;
}
- li_->RemoveMachineInstrFromMaps(MI);
- mii = mbbi->erase(mii);
- ++numPeep;
continue;
}
}
}
- CalculateSpillWeights();
-
DEBUG(dump());
return true;
}