Use the value mapping provided by LiveIntervalMap. This simplifies the code a

great deal because we don't have to worry about maintaining SSA form.

Unconditionally copy back to dupli when the register is live out of the split
range, even if the live-out value was defined outside the range. Skipping the
back-copy only makes sense when the live range is going to spill outside the
split range, and we don't know that it will. Besides, this was a hack to avoid
SSA update issues.

Clear up some confusion about the end point of a half-open LiveRange. Methinks
LiveRanges need to be closed so both start and end are included in the range.
The low bits of a SlotIndex are symbolic, so a half-open range doesn't really
make sense. This would be a pervasive change, though.

llvm-svn: 114043
This commit is contained in:
Jakob Stoklund Olesen 2010-09-16 00:01:36 +00:00
parent 3e972009fb
commit 9855109b65
2 changed files with 86 additions and 226 deletions

View File

@ -363,10 +363,8 @@ VNInfo *LiveIntervalMap::defValue(const VNInfo *ParentVNI, SlotIndex Idx) {
if (Idx == ParentVNI->def)
return mapValue(ParentVNI, Idx);
// This is a complex def. Mark with a NULL in valueMap.
VNInfo *&OldVNI = valueMap_[ParentVNI];
assert(!OldVNI && "Simple/Complex values mixed");
OldVNI = 0;
// This is now a complex def. Mark with a NULL in valueMap.
valueMap_[ParentVNI] = 0;
// Should we insert a minimal snippet of VNI LiveRange, or can we count on
// callers to do that? We need it for lookups of complex values.
@ -417,10 +415,10 @@ VNInfo *LiveIntervalMap::mapValue(const VNInfo *ParentVNI, SlotIndex Idx) {
IDFI = idf_begin(IdxMBB),
IDFE = idf_end(IdxMBB); IDFI != IDFE;) {
MachineBasicBlock *MBB = *IDFI;
SlotIndex End = lis_.getMBBEndIdx(MBB);
SlotIndex End = lis_.getMBBEndIdx(MBB).getPrevSlot();
// We are operating on the restricted CFG where ParentVNI is live.
if (parentli_.getVNInfoAt(End.getPrevSlot()) != ParentVNI) {
if (parentli_.getVNInfoAt(End) != ParentVNI) {
IDFI.skipChildren();
continue;
}
@ -489,7 +487,7 @@ VNInfo *LiveIntervalMap::mapValue(const VNInfo *ParentVNI, SlotIndex Idx) {
if (MBB == IdxMBB) {
// Don't add full liveness to IdxMBB, stop at Idx.
if (Start != Idx)
li_->addRange(LiveRange(Start, Idx, VNI));
li_->addRange(LiveRange(Start, Idx.getNextSlot(), VNI));
// The caller had better add some liveness to IdxVNI, or it leaks.
IdxVNI = VNI;
} else
@ -511,8 +509,8 @@ VNInfo *LiveIntervalMap::extendTo(MachineBasicBlock *MBB, SlotIndex Idx) {
--I;
if (I->start < lis_.getMBBStartIdx(MBB))
return 0;
if (I->end < Idx)
I->end = Idx;
if (I->end <= Idx)
I->end = Idx.getNextSlot();
return I->valno;
}
@ -574,6 +572,20 @@ void LiveIntervalMap::addRange(SlotIndex Start, SlotIndex End) {
addSimpleRange(I->start, std::min(End, I->end), I->valno);
}
VNInfo *LiveIntervalMap::defByCopyFrom(unsigned Reg,
const VNInfo *ParentVNI,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) {
const TargetInstrDesc &TID = MBB.getParent()->getTarget().getInstrInfo()->
get(TargetOpcode::COPY);
MachineInstr *MI = BuildMI(MBB, I, DebugLoc(), TID, li_->reg).addReg(Reg);
SlotIndex DefIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
VNInfo *VNI = defValue(ParentVNI, DefIdx);
VNI->setCopy(MI);
li_->addRange(LiveRange(DefIdx, DefIdx.getNextSlot(), VNI));
return VNI;
}
//===----------------------------------------------------------------------===//
// Split Editor
//===----------------------------------------------------------------------===//
@ -600,122 +612,56 @@ SplitEditor::SplitEditor(SplitAnalysis &sa, LiveIntervals &lis, VirtRegMap &vrm,
}
LiveInterval *SplitEditor::createInterval() {
unsigned curli = sa_.getCurLI()->reg;
unsigned Reg = mri_.createVirtualRegister(mri_.getRegClass(curli));
unsigned Reg = mri_.createVirtualRegister(mri_.getRegClass(curli_->reg));
LiveInterval &Intv = lis_.getOrCreateInterval(Reg);
vrm_.grow();
vrm_.assignVirt2StackSlot(Reg, vrm_.getStackSlot(curli));
vrm_.assignVirt2StackSlot(Reg, vrm_.getStackSlot(curli_->reg));
return &Intv;
}
LiveInterval *SplitEditor::getDupLI() {
if (!dupli_.getLI()) {
// Create an interval for dupli that is a copy of curli.
dupli_.reset(createInterval());
dupli_.getLI()->Copy(*curli_, &mri_, lis_.getVNInfoAllocator());
}
return dupli_.getLI();
}
VNInfo *SplitEditor::mapValue(const VNInfo *curliVNI) {
VNInfo *&VNI = valueMap_[curliVNI];
if (!VNI)
VNI = openli_.getLI()->createValueCopy(curliVNI, lis_.getVNInfoAllocator());
return VNI;
}
/// Insert a COPY instruction curli -> li. Allocate a new value from li
/// defined by the COPY. Note that rewrite() will deal with the curli
/// register, so this function can be used to copy from any interval - openli,
/// curli, or dupli.
VNInfo *SplitEditor::insertCopy(LiveInterval &LI,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) {
MachineInstr *MI = BuildMI(MBB, I, DebugLoc(), tii_.get(TargetOpcode::COPY),
LI.reg).addReg(curli_->reg);
SlotIndex DefIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
return LI.getNextValue(DefIdx, MI, true, lis_.getVNInfoAllocator());
}
/// Create a new virtual register and live interval.
void SplitEditor::openIntv() {
assert(!openli_.getLI() && "Previous LI not closed before openIntv");
if (!dupli_.getLI()) {
// Create an interval for dupli that is a copy of curli.
dupli_.reset(createInterval());
dupli_.getLI()->Copy(*curli_, &mri_, lis_.getVNInfoAllocator());
}
openli_.reset(createInterval());
intervals_.push_back(openli_.getLI());
liveThrough_ = false;
}
/// enterIntvBefore - Enter openli before the instruction at Idx. If curli is
/// not live before Idx, a COPY is not inserted.
void SplitEditor::enterIntvBefore(SlotIndex Idx) {
assert(openli_.getLI() && "openIntv not called before enterIntvBefore");
// Copy from curli_ if it is live.
if (VNInfo *CurVNI = curli_->getVNInfoAt(Idx.getUseIndex())) {
VNInfo *ParentVNI = curli_->getVNInfoAt(Idx.getUseIndex());
if (!ParentVNI) {
DEBUG(dbgs() << " enterIntvBefore " << Idx << ": not live\n");
return;
}
MachineInstr *MI = lis_.getInstructionFromIndex(Idx);
assert(MI && "enterIntvBefore called with invalid index");
VNInfo *VNI = insertCopy(*openli_.getLI(), *MI->getParent(), MI);
openli_.getLI()->addRange(LiveRange(VNI->def, Idx.getDefIndex(), VNI));
// Make sure CurVNI is properly mapped.
VNInfo *&mapVNI = valueMap_[CurVNI];
// We dont have SSA update yet, so only one entry per value is allowed.
assert(!mapVNI && "enterIntvBefore called more than once for the same value");
mapVNI = VNI;
}
openli_.defByCopyFrom(curli_->reg, ParentVNI, *MI->getParent(), MI);
DEBUG(dbgs() << " enterIntvBefore " << Idx << ": " << *openli_.getLI()
<< '\n');
}
/// enterIntvAtEnd - Enter openli at the end of MBB.
/// PhiMBB is a successor inside openli where a PHI value is created.
/// Currently, all entries must share the same PhiMBB.
void SplitEditor::enterIntvAtEnd(MachineBasicBlock &A, MachineBasicBlock &B) {
void SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) {
assert(openli_.getLI() && "openIntv not called before enterIntvAtEnd");
SlotIndex EndA = lis_.getMBBEndIdx(&A);
VNInfo *CurVNIA = curli_->getVNInfoAt(EndA.getPrevIndex());
if (!CurVNIA) {
DEBUG(dbgs() << " enterIntvAtEnd, curli not live out of BB#"
<< A.getNumber() << ".\n");
SlotIndex End = lis_.getMBBEndIdx(&MBB);
VNInfo *ParentVNI = curli_->getVNInfoAt(End.getPrevSlot());
if (!ParentVNI) {
DEBUG(dbgs() << " enterIntvAtEnd " << End << ": not live\n");
return;
}
// Add a phi kill value and live range out of A.
VNInfo *VNIA = insertCopy(*openli_.getLI(), A, A.getFirstTerminator());
openli_.getLI()->addRange(LiveRange(VNIA->def, EndA, VNIA));
// FIXME: If this is the only entry edge, we don't need the extra PHI value.
// FIXME: If there are multiple entry blocks (so not a loop), we need proper
// SSA update.
// Now look at the start of B.
SlotIndex StartB = lis_.getMBBStartIdx(&B);
SlotIndex EndB = lis_.getMBBEndIdx(&B);
const LiveRange *CurB = curli_->getLiveRangeContaining(StartB);
if (!CurB) {
DEBUG(dbgs() << " enterIntvAtEnd: curli not live in to BB#"
<< B.getNumber() << ".\n");
return;
}
VNInfo *VNIB = openli_.getLI()->getVNInfoAt(StartB);
if (!VNIB) {
// Create a phi value.
VNIB = openli_.getLI()->getNextValue(SlotIndex(StartB, true), 0, false,
lis_.getVNInfoAllocator());
VNIB->setIsPHIDef(true);
VNInfo *&mapVNI = valueMap_[CurB->valno];
if (mapVNI) {
// Multiple copies - must create PHI value.
abort();
} else {
// This is the first copy of dupLR. Mark the mapping.
mapVNI = VNIB;
}
}
VNInfo *VNI = openli_.defByCopyFrom(curli_->reg, ParentVNI,
MBB, MBB.getFirstTerminator());
// Make sure openli is live out of MBB.
openli_.getLI()->addRange(LiveRange(VNI->def, End, VNI));
DEBUG(dbgs() << " enterIntvAtEnd: " << *openli_.getLI() << '\n');
}
@ -726,24 +672,7 @@ void SplitEditor::useIntv(const MachineBasicBlock &MBB) {
void SplitEditor::useIntv(SlotIndex Start, SlotIndex End) {
assert(openli_.getLI() && "openIntv not called before useIntv");
// Map the curli values from the interval into openli_
LiveInterval::const_iterator B = curli_->begin(), E = curli_->end();
LiveInterval::const_iterator I = std::lower_bound(B, E, Start);
if (I != B) {
--I;
// I begins before Start, but overlaps.
if (I->end > Start)
openli_.getLI()->addRange(LiveRange(Start, std::min(End, I->end),
mapValue(I->valno)));
++I;
}
// The remaining ranges begin after Start.
for (;I != E && I->start < End; ++I)
openli_.getLI()->addRange(LiveRange(I->start, std::min(End, I->end),
mapValue(I->valno)));
openli_.addRange(Start, End);
DEBUG(dbgs() << " use [" << Start << ';' << End << "): "
<< *openli_.getLI() << '\n');
}
@ -752,32 +681,24 @@ void SplitEditor::useIntv(SlotIndex Start, SlotIndex End) {
void SplitEditor::leaveIntvAfter(SlotIndex Idx) {
assert(openli_.getLI() && "openIntv not called before leaveIntvAfter");
const LiveRange *CurLR = curli_->getLiveRangeContaining(Idx.getDefIndex());
if (!CurLR || CurLR->end <= Idx.getBoundaryIndex()) {
// The interval must be live beyond the instruction at Idx.
SlotIndex EndIdx = Idx.getNextIndex().getBaseIndex();
VNInfo *ParentVNI = curli_->getVNInfoAt(EndIdx);
if (!ParentVNI) {
DEBUG(dbgs() << " leaveIntvAfter " << Idx << ": not live\n");
return;
}
// Was this value of curli live through openli?
if (!openli_.getLI()->liveAt(CurLR->valno->def)) {
DEBUG(dbgs() << " leaveIntvAfter " << Idx << ": using external value\n");
liveThrough_ = true;
return;
}
MachineInstr *MI = lis_.getInstructionFromIndex(Idx);
assert(MI && "leaveIntvAfter called with invalid index");
// We are going to insert a back copy, so we must have a dupli_.
LiveRange *DupLR = getDupLI()->getLiveRangeContaining(Idx.getDefIndex());
assert(DupLR && "dupli not live into block, but curli is?");
VNInfo *VNI = dupli_.defByCopyFrom(openli_.getLI()->reg, ParentVNI,
*MI->getParent(), MI);
// Finally we must make sure that openli is properly extended from Idx to the
// new copy.
openli_.mapValue(ParentVNI, VNI->def.getUseIndex());
// Insert the COPY instruction.
MachineBasicBlock::iterator I = lis_.getInstructionFromIndex(Idx);
MachineInstr *MI = BuildMI(*I->getParent(), llvm::next(I), I->getDebugLoc(),
tii_.get(TargetOpcode::COPY), dupli_.getLI()->reg)
.addReg(openli_.getLI()->reg);
SlotIndex CopyIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
openli_.getLI()->addRange(LiveRange(Idx.getDefIndex(), CopyIdx,
mapValue(CurLR->valno)));
DupLR->valno->def = CopyIdx;
DEBUG(dbgs() << " leaveIntvAfter " << Idx << ": " << *openli_.getLI()
<< '\n');
}
@ -788,68 +709,23 @@ void SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) {
assert(openli_.getLI() && "openIntv not called before leaveIntvAtTop");
SlotIndex Start = lis_.getMBBStartIdx(&MBB);
const LiveRange *CurLR = curli_->getLiveRangeContaining(Start);
VNInfo *ParentVNI = curli_->getVNInfoAt(Start);
// Is curli even live-in to MBB?
if (!CurLR) {
if (!ParentVNI) {
DEBUG(dbgs() << " leaveIntvAtTop at " << Start << ": not live\n");
return;
}
// Is curli defined by PHI at the beginning of MBB?
bool isPHIDef = CurLR->valno->isPHIDef() &&
CurLR->valno->def.getBaseIndex() == Start;
// If MBB is using a value of curli that was defined outside the openli range,
// we don't want to copy it back here.
if (!isPHIDef && !openli_.getLI()->liveAt(CurLR->valno->def)) {
DEBUG(dbgs() << " leaveIntvAtTop at " << Start
<< ": using external value\n");
liveThrough_ = true;
return;
}
// We are going to insert a back copy, so we must have a dupli_.
LiveRange *DupLR = getDupLI()->getLiveRangeContaining(Start);
assert(DupLR && "dupli not live into block, but curli is?");
VNInfo *VNI = dupli_.defByCopyFrom(openli_.getLI()->reg, ParentVNI,
MBB, MBB.begin());
// Insert the COPY instruction.
MachineInstr *MI = BuildMI(MBB, MBB.begin(), DebugLoc(),
tii_.get(TargetOpcode::COPY), dupli_.getLI()->reg)
.addReg(openli_.getLI()->reg);
SlotIndex Idx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
// Finally we must make sure that openli is properly extended from Start to
// the new copy.
openli_.mapValue(ParentVNI, VNI->def.getUseIndex());
// Adjust dupli and openli values.
if (isPHIDef) {
// dupli was already a PHI on entry to MBB. Simply insert an openli PHI,
// and shift the dupli def down to the COPY.
VNInfo *VNI = openli_.getLI()->getNextValue(SlotIndex(Start,true), 0, false,
lis_.getVNInfoAllocator());
VNI->setIsPHIDef(true);
openli_.getLI()->addRange(LiveRange(VNI->def, Idx, VNI));
dupli_.getLI()->removeRange(Start, Idx);
DupLR->valno->def = Idx;
DupLR->valno->setIsPHIDef(false);
} else {
// The dupli value was defined somewhere inside the openli range.
DEBUG(dbgs() << " leaveIntvAtTop source value defined at "
<< DupLR->valno->def << "\n");
// FIXME: We may not need a PHI here if all predecessors have the same
// value.
VNInfo *VNI = openli_.getLI()->getNextValue(SlotIndex(Start,true), 0, false,
lis_.getVNInfoAllocator());
VNI->setIsPHIDef(true);
openli_.getLI()->addRange(LiveRange(VNI->def, Idx, VNI));
// FIXME: What if DupLR->valno is used by multiple exits? SSA Update.
// closeIntv is going to remove the superfluous live ranges.
DupLR->valno->def = Idx;
DupLR->valno->setIsPHIDef(false);
}
DEBUG(dbgs() << " leaveIntvAtTop at " << Idx << ": " << *openli_.getLI()
DEBUG(dbgs() << " leaveIntvAtTop at " << Start << ": " << *openli_.getLI()
<< '\n');
}
@ -861,12 +737,6 @@ void SplitEditor::closeIntv() {
DEBUG(dbgs() << " closeIntv cleaning up\n");
DEBUG(dbgs() << " open " << *openli_.getLI() << '\n');
if (liveThrough_) {
DEBUG(dbgs() << " value live through region, leaving dupli as is.\n");
} else {
// live out with copies inserted, or killed by region. Either way we need to
// remove the overlapping region from dupli.
getDupLI();
for (LiveInterval::iterator I = openli_.getLI()->begin(),
E = openli_.getLI()->end(); I != E; ++I) {
dupli_.getLI()->removeRange(I->start, I->end);
@ -874,9 +744,7 @@ void SplitEditor::closeIntv() {
// FIXME: A block branching to the entry block may also branch elsewhere
// curli is live. We need both openli and curli to be live in that case.
DEBUG(dbgs() << " dup2 " << *dupli_.getLI() << '\n');
}
openli_.reset(0);
valueMap_.clear();
}
/// rewrite - after all the new live ranges have been created, rewrite
@ -957,7 +825,7 @@ bool SplitEditor::splitAroundLoop(const MachineLoop *Loop) {
for (SplitAnalysis::BlockPtrSet::iterator I = Blocks.Preds.begin(),
E = Blocks.Preds.end(); I != E; ++I) {
MachineBasicBlock &MBB = const_cast<MachineBasicBlock&>(**I);
enterIntvAtEnd(MBB, *Loop->getHeader());
enterIntvAtEnd(MBB);
}
// Switch all loop blocks.

View File

@ -162,8 +162,8 @@ class LiveIntervalMap {
ValueMap valueMap_;
// extendTo - Find the last li_ value defined in MBB at or before Idx. The
// parentli_ is assumed to be live at Idx. Extend the live range to Idx.
// Return the found VNInfo, or NULL.
// parentli is assumed to be live at Idx. Extend the live range to include
// Idx. Return the found VNInfo, or NULL.
VNInfo *extendTo(MachineBasicBlock *MBB, SlotIndex Idx);
// addSimpleRange - Add a simple range from parentli_ to li_.
@ -200,6 +200,14 @@ public:
/// All needed values whose def is not inside [Start;End) must be defined
/// beforehand so mapValue will work.
void addRange(SlotIndex Start, SlotIndex End);
/// defByCopyFrom - Insert a copy from Reg to li, assuming that Reg carries
/// ParentVNI. Add a minimal live range for the new value and return it.
VNInfo *defByCopyFrom(unsigned Reg,
const VNInfo *ParentVNI,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I);
};
@ -236,20 +244,6 @@ class SplitEditor {
/// register class and spill slot as curli.
LiveInterval *createInterval();
/// getDupLI - Ensure dupli is created and return it.
LiveInterval *getDupLI();
/// valueMap_ - Map values in cupli to values in openli. These are direct 1-1
/// mappings, and do not include values created by inserted copies.
DenseMap<const VNInfo*, VNInfo*> valueMap_;
/// mapValue - Return the openIntv value that corresponds to the given curli
/// value.
VNInfo *mapValue(const VNInfo *curliVNI);
/// A dupli value is live through openIntv.
bool liveThrough_;
/// All the new intervals created for this split are added to intervals_.
SmallVectorImpl<LiveInterval*> &intervals_;
@ -259,7 +253,7 @@ class SplitEditor {
/// Insert a COPY instruction curli -> li. Allocate a new value from li
/// defined by the COPY
VNInfo *insertCopy(LiveInterval &LI,
VNInfo *insertCopy(LiveIntervalMap &LI,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I);
@ -280,9 +274,7 @@ public:
void enterIntvBefore(SlotIndex Idx);
/// enterIntvAtEnd - Enter openli at the end of MBB.
/// PhiMBB is a successor inside openli where a PHI value is created.
/// Currently, all entries must share the same PhiMBB.
void enterIntvAtEnd(MachineBasicBlock &MBB, MachineBasicBlock &PhiMBB);
void enterIntvAtEnd(MachineBasicBlock &MBB);
/// useIntv - indicate that all instructions in MBB should use openli.
void useIntv(const MachineBasicBlock &MBB);