aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SplitKit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/SplitKit.cpp')
-rw-r--r--lib/CodeGen/SplitKit.cpp278
1 files changed, 73 insertions, 205 deletions
diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp
index 5b9f49d11a..bce606c3ef 100644
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -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() {
+/// 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());
}
- 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");
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())) {
- 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;
+ 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");
+ 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");
- 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");
+ SlotIndex End = lis_.getMBBEndIdx(&MBB);
+ VNInfo *ParentVNI = curli_->getVNInfoAt(End.getPrevSlot());
+ if (!ParentVNI) {
+ DEBUG(dbgs() << " enterIntvAtEnd " << End << ": not live\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");
+
+ 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());
- // 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?");
-
- // 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?");
-
- // 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();
-
- // 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);
- }
+ VNInfo *VNI = dupli_.defByCopyFrom(openli_.getLI()->reg, ParentVNI,
+ MBB, MBB.begin());
- DEBUG(dbgs() << " leaveIntvAtTop at " << Idx << ": " << *openli_.getLI()
+ // Finally we must make sure that openli is properly extended from Start to
+ // the new copy.
+ openli_.mapValue(ParentVNI, VNI->def.getUseIndex());
+
+ DEBUG(dbgs() << " leaveIntvAtTop at " << Start << ": " << *openli_.getLI()
<< '\n');
}
@@ -861,22 +737,14 @@ 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);
- }
- // 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');
+ for (LiveInterval::iterator I = openli_.getLI()->begin(),
+ E = openli_.getLI()->end(); I != E; ++I) {
+ dupli_.getLI()->removeRange(I->start, I->end);
}
+ // 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.