summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/LiveInterval.h2
-rw-r--r--lib/CodeGen/LiveRangeEdit.h1
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp15
-rw-r--r--lib/CodeGen/SplitKit.cpp326
-rw-r--r--lib/CodeGen/SplitKit.h63
5 files changed, 182 insertions, 225 deletions
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index b2915cee97..88131fbc40 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -560,7 +560,7 @@ namespace llvm {
/// getEqClass - Classify creates equivalence classes numbered 0..N. Return
/// the equivalence class assigned the VNI.
- unsigned getEqClass(const VNInfo *VNI) { return eqClass_[VNI->id]; }
+ unsigned getEqClass(const VNInfo *VNI) const { return eqClass_[VNI->id]; }
/// Distribute - Distribute values in LIV[0] into a separate LiveInterval
/// for each connected component. LIV must have a LiveInterval for each
diff --git a/lib/CodeGen/LiveRangeEdit.h b/lib/CodeGen/LiveRangeEdit.h
index 37b58279b1..73f69ed639 100644
--- a/lib/CodeGen/LiveRangeEdit.h
+++ b/lib/CodeGen/LiveRangeEdit.h
@@ -78,6 +78,7 @@ public:
iterator begin() const { return newRegs_.begin()+firstNew_; }
iterator end() const { return newRegs_.end(); }
unsigned size() const { return newRegs_.size()-firstNew_; }
+ bool empty() const { return size() == 0; }
LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; }
/// create - Create a new register with the same class and stack slot as
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index 2b30c316f1..d970c7d16a 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -645,9 +645,6 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs);
SplitEditor SE(*SA, *LIS, *VRM, *DomTree, LREdit);
- // Ranges to add to the register interval after all defs are in place.
- SmallVector<IndexPair, 8> UseRanges;
-
// Create the main cross-block interval.
SE.openIntv();
@@ -684,7 +681,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
if (!BI.LiveThrough) {
DEBUG(dbgs() << ", not live-through.\n");
SE.enterIntvBefore(BI.Def);
- UseRanges.push_back(IndexPair(BI.Def, Stop));
+ SE.useIntv(BI.Def, Stop);
continue;
}
if (!RegIn) {
@@ -692,7 +689,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
// Reload just before the first use.
DEBUG(dbgs() << ", not live-in, enter before first use.\n");
SE.enterIntvBefore(BI.FirstUse);
- UseRanges.push_back(IndexPair(BI.FirstUse, Stop));
+ SE.useIntv(BI.FirstUse, Stop);
continue;
}
DEBUG(dbgs() << ", live-through.\n");
@@ -717,7 +714,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
DEBUG(dbgs() << ", free use at " << Use << ".\n");
assert(Use <= BI.LastUse && "Couldn't find last use");
SE.enterIntvBefore(Use);
- UseRanges.push_back(IndexPair(Use, Stop));
+ SE.useIntv(Use, Stop);
continue;
}
@@ -726,12 +723,6 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
SE.enterIntvAtEnd(*BI.MBB);
}
- // Add the live-out ranges following the defs.
- // We must wait until all defs have been inserted, otherwise SplitKit gets
- // confused about the value mapping.
- for (unsigned i = 0, e = UseRanges.size(); i != e; ++i)
- SE.useIntv(UseRanges[i].first, UseRanges[i].second);
-
// Now all defs leading to live bundles are handled, do everything else.
for (unsigned i = 0, e = LiveBlocks.size(); i != e; ++i) {
BlockInfo &BI = LiveBlocks[i];
diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp
index daa3140c15..0ec983ec13 100644
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -449,7 +449,6 @@ VNInfo *LiveIntervalMap::mapValue(const VNInfo *ParentVNI, SlotIndex Idx,
// VNInfo. Insert phi-def VNInfos along the path back to IdxMBB.
DEBUG(dbgs() << "\n Reaching defs for BB#" << IdxMBB->getNumber()
<< " at " << Idx << " in " << *LI << '\n');
- DEBUG(dumpCache());
// Blocks where LI should be live-in.
SmallVector<MachineDomTreeNode*, 16> LiveIn;
@@ -587,7 +586,6 @@ VNInfo *LiveIntervalMap::mapValue(const VNInfo *ParentVNI, SlotIndex Idx,
assert(IdxVNI && "Didn't find value for Idx");
#ifndef NDEBUG
- DEBUG(dumpCache());
// Check the LiveOutCache invariants.
for (LiveOutMap::iterator I = LiveOutCache.begin(), E = LiveOutCache.end();
I != E; ++I) {
@@ -729,69 +727,86 @@ SplitEditor::SplitEditor(SplitAnalysis &sa,
LiveRangeEdit &edit)
: sa_(sa), LIS(lis), VRM(vrm),
MRI(vrm.getMachineFunction().getRegInfo()),
+ MDT(mdt),
TII(*vrm.getMachineFunction().getTarget().getInstrInfo()),
TRI(*vrm.getMachineFunction().getTarget().getRegisterInfo()),
Edit(edit),
- DupLI(LIS, mdt, edit.getParent()),
- OpenLI(LIS, mdt, edit.getParent())
+ OpenIdx(0),
+ RegAssign(Allocator)
{
// We don't need an AliasAnalysis since we will only be performing
// cheap-as-a-copy remats anyway.
Edit.anyRematerializable(LIS, TII, 0);
}
-bool SplitEditor::intervalsLiveAt(SlotIndex Idx) const {
- for (LiveRangeEdit::iterator I = Edit.begin(), E = Edit.end(); I != E; ++I)
- if (*I != DupLI.getLI() && (*I)->liveAt(Idx))
- return true;
- return false;
+void SplitEditor::dump() const {
+ if (RegAssign.empty()) {
+ dbgs() << " empty\n";
+ return;
+ }
+
+ for (RegAssignMap::const_iterator I = RegAssign.begin(); I.valid(); ++I)
+ dbgs() << " [" << I.start() << ';' << I.stop() << "):" << I.value();
+ dbgs() << '\n';
}
-VNInfo *SplitEditor::defFromParent(LiveIntervalMap &Reg,
+VNInfo *SplitEditor::defFromParent(unsigned RegIdx,
VNInfo *ParentVNI,
SlotIndex UseIdx,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) {
- VNInfo *VNI = 0;
MachineInstr *CopyMI = 0;
SlotIndex Def;
+ LiveInterval *LI = Edit.get(RegIdx);
// Attempt cheap-as-a-copy rematerialization.
LiveRangeEdit::Remat RM(ParentVNI);
if (Edit.canRematerializeAt(RM, UseIdx, true, LIS)) {
- Def = Edit.rematerializeAt(MBB, I, Reg.getLI()->reg, RM,
- LIS, TII, TRI);
+ Def = Edit.rematerializeAt(MBB, I, LI->reg, RM, LIS, TII, TRI);
} else {
// Can't remat, just insert a copy from parent.
- CopyMI = BuildMI(MBB, I, DebugLoc(), TII.get(TargetOpcode::COPY),
- Reg.getLI()->reg).addReg(Edit.getReg());
+ CopyMI = BuildMI(MBB, I, DebugLoc(), TII.get(TargetOpcode::COPY), LI->reg)
+ .addReg(Edit.getReg());
Def = LIS.InsertMachineInstrInMaps(CopyMI).getDefIndex();
}
// Define the value in Reg.
- VNI = Reg.defValue(ParentVNI, Def);
+ VNInfo *VNI = LIMappers[RegIdx].defValue(ParentVNI, Def);
VNI->setCopy(CopyMI);
// Add minimal liveness for the new value.
- if (UseIdx < Def)
- UseIdx = Def;
- Reg.getLI()->addRange(LiveRange(Def, UseIdx.getNextSlot(), VNI));
+ Edit.get(RegIdx)->addRange(LiveRange(Def, Def.getNextSlot(), VNI));
+
+ if (RegIdx) {
+ if (UseIdx < Def)
+ UseIdx = Def;
+ RegAssign.insert(Def, UseIdx.getNextSlot(), RegIdx);
+ }
return VNI;
}
/// Create a new virtual register and live interval.
void SplitEditor::openIntv() {
- assert(!OpenLI.getLI() && "Previous LI not closed before openIntv");
- if (!DupLI.getLI())
- DupLI.reset(&Edit.create(MRI, LIS, VRM));
+ assert(!OpenIdx && "Previous LI not closed before openIntv");
- OpenLI.reset(&Edit.create(MRI, LIS, VRM));
+ // Create the complement as index 0.
+ if (Edit.empty()) {
+ Edit.create(MRI, LIS, VRM);
+ LIMappers.push_back(LiveIntervalMap(LIS, MDT, Edit.getParent()));
+ LIMappers.back().reset(Edit.get(0));
+ }
+
+ // Create the open interval.
+ OpenIdx = Edit.size();
+ Edit.create(MRI, LIS, VRM);
+ LIMappers.push_back(LiveIntervalMap(LIS, MDT, Edit.getParent()));
+ LIMappers[OpenIdx].reset(Edit.get(OpenIdx));
}
/// 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");
+ assert(OpenIdx && "openIntv not called before enterIntvBefore");
Idx = Idx.getUseIndex();
DEBUG(dbgs() << " enterIntvBefore " << Idx);
VNInfo *ParentVNI = Edit.getParent().getVNInfoAt(Idx);
@@ -800,18 +815,16 @@ void SplitEditor::enterIntvBefore(SlotIndex Idx) {
return;
}
DEBUG(dbgs() << ": valno " << ParentVNI->id);
- truncatedValues.insert(ParentVNI);
MachineInstr *MI = LIS.getInstructionFromIndex(Idx);
assert(MI && "enterIntvBefore called with invalid index");
- defFromParent(OpenLI, ParentVNI, Idx, *MI->getParent(), MI);
-
- DEBUG(dbgs() << ": " << *OpenLI.getLI() << '\n');
+ defFromParent(OpenIdx, ParentVNI, Idx, *MI->getParent(), MI);
+ DEBUG(dump());
}
/// enterIntvAtEnd - Enter OpenLI at the end of MBB.
void SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) {
- assert(OpenLI.getLI() && "openIntv not called before enterIntvAtEnd");
+ assert(OpenIdx && "openIntv not called before enterIntvAtEnd");
SlotIndex End = LIS.getMBBEndIdx(&MBB).getPrevSlot();
DEBUG(dbgs() << " enterIntvAtEnd BB#" << MBB.getNumber() << ", " << End);
VNInfo *ParentVNI = Edit.getParent().getVNInfoAt(End);
@@ -820,9 +833,8 @@ void SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) {
return;
}
DEBUG(dbgs() << ": valno " << ParentVNI->id);
- truncatedValues.insert(ParentVNI);
- defFromParent(OpenLI, ParentVNI, End, MBB, MBB.getFirstTerminator());
- DEBUG(dbgs() << ": " << *OpenLI.getLI() << '\n');
+ defFromParent(OpenIdx, ParentVNI, End, MBB, MBB.getFirstTerminator());
+ DEBUG(dump());
}
/// useIntv - indicate that all instructions in MBB should use OpenLI.
@@ -831,15 +843,15 @@ void SplitEditor::useIntv(const MachineBasicBlock &MBB) {
}
void SplitEditor::useIntv(SlotIndex Start, SlotIndex End) {
- assert(OpenLI.getLI() && "openIntv not called before useIntv");
- OpenLI.addRange(Start, End);
- DEBUG(dbgs() << " use [" << Start << ';' << End << "): "
- << *OpenLI.getLI() << '\n');
+ assert(OpenIdx && "openIntv not called before useIntv");
+ DEBUG(dbgs() << " useIntv [" << Start << ';' << End << "):");
+ RegAssign.insert(Start, End, OpenIdx);
+ DEBUG(dump());
}
/// leaveIntvAfter - Leave OpenLI after the instruction at Idx.
void SplitEditor::leaveIntvAfter(SlotIndex Idx) {
- assert(OpenLI.getLI() && "openIntv not called before leaveIntvAfter");
+ assert(OpenIdx && "openIntv not called before leaveIntvAfter");
DEBUG(dbgs() << " leaveIntvAfter " << Idx);
// The interval must be live beyond the instruction at Idx.
@@ -852,20 +864,17 @@ void SplitEditor::leaveIntvAfter(SlotIndex Idx) {
DEBUG(dbgs() << ": valno " << ParentVNI->id);
MachineBasicBlock::iterator MII = LIS.getInstructionFromIndex(Idx);
- VNInfo *VNI = defFromParent(DupLI, ParentVNI, Idx,
+ VNInfo *VNI = defFromParent(0, ParentVNI, Idx,
*MII->getParent(), llvm::next(MII));
- // Make sure that OpenLI is properly extended from Idx to the new copy.
- // FIXME: This shouldn't be necessary for remats.
- OpenLI.addSimpleRange(Idx, VNI->def, ParentVNI);
-
- DEBUG(dbgs() << ": " << *OpenLI.getLI() << '\n');
+ RegAssign.insert(Idx, VNI->def, OpenIdx);
+ DEBUG(dump());
}
/// leaveIntvAtTop - Leave the interval at the top of MBB.
/// Currently, only one value can leave the interval.
void SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) {
- assert(OpenLI.getLI() && "openIntv not called before leaveIntvAtTop");
+ assert(OpenIdx && "openIntv not called before leaveIntvAtTop");
SlotIndex Start = LIS.getMBBStartIdx(&MBB);
DEBUG(dbgs() << " leaveIntvAtTop BB#" << MBB.getNumber() << ", " << Start);
@@ -875,179 +884,130 @@ void SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) {
return;
}
- VNInfo *VNI = defFromParent(DupLI, ParentVNI, Start, MBB,
+ VNInfo *VNI = defFromParent(0, ParentVNI, Start, MBB,
MBB.SkipPHIsAndLabels(MBB.begin()));
-
- // Finally we must make sure that OpenLI is properly extended from Start to
- // the new copy.
- OpenLI.addSimpleRange(Start, VNI->def, ParentVNI);
- DEBUG(dbgs() << ": " << *OpenLI.getLI() << '\n');
+ RegAssign.insert(Start, VNI->def, OpenIdx);
+ DEBUG(dump());
}
/// closeIntv - Indicate that we are done editing the currently open
/// LiveInterval, and ranges can be trimmed.
void SplitEditor::closeIntv() {
- assert(OpenLI.getLI() && "openIntv not called before closeIntv");
- DEBUG(dbgs() << " closeIntv " << *OpenLI.getLI() << '\n');
- OpenLI.reset(0);
+ assert(OpenIdx && "openIntv not called before closeIntv");
+ OpenIdx = 0;
}
-/// rewrite - Rewrite all uses of reg to use the new registers.
-void SplitEditor::rewrite(unsigned reg) {
- for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(reg),
+/// rewriteAssigned - Rewrite all uses of Edit.getReg().
+void SplitEditor::rewriteAssigned() {
+ for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Edit.getReg()),
RE = MRI.reg_end(); RI != RE;) {
MachineOperand &MO = RI.getOperand();
- unsigned OpNum = RI.getOperandNo();
MachineInstr *MI = MO.getParent();
++RI;
+ // LiveDebugVariables should have handled all DBG_VALUE instructions.
if (MI->isDebugValue()) {
DEBUG(dbgs() << "Zapping " << *MI);
- // FIXME: We can do much better with debug values.
MO.setReg(0);
continue;
}
SlotIndex Idx = LIS.getInstructionIndex(MI);
Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex();
- LiveInterval *LI = 0;
- for (LiveRangeEdit::iterator I = Edit.begin(), E = Edit.end(); I != E;
- ++I) {
- LiveInterval *testli = *I;
- if (testli->liveAt(Idx)) {
- LI = testli;
- break;
- }
- }
- DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t'<< Idx);
- assert(LI && "No register was live at use");
- MO.setReg(LI->reg);
- if (MO.isUse() && !MI->isRegTiedToDefOperand(OpNum))
- MO.setIsKill(LI->killedAt(Idx.getDefIndex()));
- DEBUG(dbgs() << '\t' << *MI);
+
+ // Rewrite to the mapped register at Idx.
+ unsigned RegIdx = RegAssign.lookup(Idx);
+ MO.setReg(Edit.get(RegIdx)->reg);
+ DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t'
+ << Idx << ':' << RegIdx << '\t' << *MI);
+
+ // Extend liveness to Idx.
+ const VNInfo *ParentVNI = Edit.getParent().getVNInfoAt(Idx);
+ LIMappers[RegIdx].mapValue(ParentVNI, Idx);
}
}
-void
-SplitEditor::addTruncSimpleRange(SlotIndex Start, SlotIndex End, VNInfo *VNI) {
- // Build vector of iterator pairs from the intervals.
- typedef std::pair<LiveInterval::const_iterator,
- LiveInterval::const_iterator> IIPair;
- SmallVector<IIPair, 8> Iters;
- for (LiveRangeEdit::iterator LI = Edit.begin(), LE = Edit.end(); LI != LE;
- ++LI) {
- if (*LI == DupLI.getLI())
+/// rewriteSplit - Rewrite uses of Intvs[0] according to the ConEQ mapping.
+void SplitEditor::rewriteComponents(const SmallVectorImpl<LiveInterval*> &Intvs,
+ const ConnectedVNInfoEqClasses &ConEq) {
+ for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Intvs[0]->reg),
+ RE = MRI.reg_end(); RI != RE;) {
+ MachineOperand &MO = RI.getOperand();
+ MachineInstr *MI = MO.getParent();
+ ++RI;
+ if (MO.isUse() && MO.isUndef())
continue;
- LiveInterval::const_iterator I = (*LI)->find(Start);
- LiveInterval::const_iterator E = (*LI)->end();
- if (I != E)
- Iters.push_back(std::make_pair(I, E));
- }
-
- SlotIndex sidx = Start;
- // Break [Start;End) into segments that don't overlap any intervals.
- for (;;) {
- SlotIndex next = sidx, eidx = End;
- // Find overlapping intervals.
- for (unsigned i = 0; i != Iters.size() && sidx < eidx; ++i) {
- LiveInterval::const_iterator I = Iters[i].first;
- // Interval I is overlapping [sidx;eidx). Trim sidx.
- if (I->start <= sidx) {
- sidx = I->end;
- // Move to the next run, remove iters when all are consumed.
- I = ++Iters[i].first;
- if (I == Iters[i].second) {
- Iters.erase(Iters.begin() + i);
- --i;
- continue;
- }
- }
- // Trim eidx too if needed.
- if (I->start >= eidx)
- continue;
- eidx = I->start;
- next = I->end;
- }
- // Now, [sidx;eidx) doesn't overlap anything in intervals_.
- if (sidx < eidx)
- DupLI.addSimpleRange(sidx, eidx, VNI);
- // If the interval end was truncated, we can try again from next.
- if (next <= sidx)
- break;
- sidx = next;
+ // DBG_VALUE instructions should have been eliminated earlier.
+ SlotIndex Idx = LIS.getInstructionIndex(MI);
+ Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex();
+ DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t'
+ << Idx << ':');
+ const VNInfo *VNI = Intvs[0]->getVNInfoAt(Idx);
+ assert(VNI && "Interval not live at use.");
+ MO.setReg(Intvs[ConEq.getEqClass(VNI)]->reg);
+ DEBUG(dbgs() << VNI->id << '\t' << *MI);
}
}
-void SplitEditor::computeRemainder() {
- // First we need to fill in the live ranges in dupli.
- // If values were redefined, we need a full recoloring with SSA update.
- // If values were truncated, we only need to truncate the ranges.
- // If values were partially rematted, we should shrink to uses.
- // If values were fully rematted, they should be omitted.
- // FIXME: If a single value is redefined, just move the def and truncate.
- LiveInterval &parent = Edit.getParent();
-
- DEBUG(dbgs() << "computeRemainder from " << parent << '\n');
-
- // Values that are fully contained in the split intervals.
- SmallPtrSet<const VNInfo*, 8> deadValues;
- // Map all CurLI values that should have live defs in dupli.
- for (LiveInterval::const_vni_iterator I = parent.vni_begin(),
- E = parent.vni_end(); I != E; ++I) {
- const VNInfo *VNI = *I;
- // Don't transfer unused values to the new intervals.
- if (VNI->isUnused())
- continue;
- // Original def is contained in the split intervals.
- if (intervalsLiveAt(VNI->def)) {
- // Did this value escape?
- if (DupLI.isMapped(VNI))
- truncatedValues.insert(VNI);
- else
- deadValues.insert(VNI);
- continue;
- }
- // Add minimal live range at the definition.
- VNInfo *DVNI = DupLI.defValue(VNI, VNI->def);
- DupLI.getLI()->addRange(LiveRange(VNI->def, VNI->def.getNextSlot(), DVNI));
+void SplitEditor::finish() {
+ assert(OpenIdx == 0 && "Previous LI not closed before rewrite");
+
+ // At this point, the live intervals in Edit contain VNInfos corresponding to
+ // the inserted copies.
+
+ // Add the original defs from the parent interval.
+ for (LiveInterval::const_vni_iterator I = Edit.getParent().vni_begin(),
+ E = Edit.getParent().vni_end(); I != E; ++I) {
+ const VNInfo *ParentVNI = *I;
+ LiveIntervalMap &LIM = LIMappers[RegAssign.lookup(ParentVNI->def)];
+ VNInfo *VNI = LIM.defValue(ParentVNI, ParentVNI->def);
+ LIM.getLI()->addRange(LiveRange(ParentVNI->def,
+ ParentVNI->def.getNextSlot(), VNI));
+ // Mark all values as complex to force liveness computation.
+ // This should really only be necessary for remat victims, but we are lazy.
+ LIM.markComplexMapped(ParentVNI);
}
- // Add all ranges to dupli.
- for (LiveInterval::const_iterator I = parent.begin(), E = parent.end();
- I != E; ++I) {
- const LiveRange &LR = *I;
- if (truncatedValues.count(LR.valno)) {
- // recolor after removing intervals_.
- addTruncSimpleRange(LR.start, LR.end, LR.valno);
- } else if (!deadValues.count(LR.valno)) {
- // recolor without truncation.
- DupLI.addSimpleRange(LR.start, LR.end, LR.valno);
+#ifndef NDEBUG
+ // Every new interval must have a def by now, otherwise the split is bogus.
+ for (LiveRangeEdit::iterator I = Edit.begin(), E = Edit.end(); I != E; ++I)
+ assert((*I)->hasAtLeastOneValue() && "Split interval has no value");
+#endif
+
+ // FIXME: Don't recompute the liveness of all values, infer it from the
+ // overlaps between the parent live interval and RegAssign.
+ // The mapValue algorithm is only necessary when:
+ // - The parent value maps to multiple defs, and new phis are needed, or
+ // - The value has been rematerialized before some uses, and we want to
+ // minimize the live range so it only reaches the remaining uses.
+ // All other values have simple liveness that can be computed from RegAssign
+ // and the parent live interval.
+
+ // Extend live ranges to be live-out for successor PHI values.
+ for (LiveInterval::const_vni_iterator I = Edit.getParent().vni_begin(),
+ E = Edit.getParent().vni_end(); I != E; ++I) {
+ const VNInfo *PHIVNI = *I;
+ if (!PHIVNI->isPHIDef())
+ continue;
+ LiveIntervalMap &LIM = LIMappers[RegAssign.lookup(PHIVNI->def)];
+ MachineBasicBlock *MBB = LIS.getMBBFromIndex(PHIVNI->def);
+ for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
+ PE = MBB->pred_end(); PI != PE; ++PI) {
+ SlotIndex End = LIS.getMBBEndIdx(*PI).getPrevSlot();
+ // The predecessor may not have a live-out value. That is OK, like an
+ // undef PHI operand.
+ if (VNInfo *VNI = Edit.getParent().getVNInfoAt(End))
+ LIM.mapValue(VNI, End);
}
}
- // Extend DupLI to be live out of any critical loop predecessors.
- // This means we have multiple registers live out of those blocks.
- // The alternative would be to split the critical edges.
- if (criticalPreds_.empty())
- return;
- for (SplitAnalysis::BlockPtrSet::iterator I = criticalPreds_.begin(),
- E = criticalPreds_.end(); I != E; ++I)
- DupLI.extendTo(*I, LIS.getMBBEndIdx(*I).getPrevSlot());
- criticalPreds_.clear();
-}
-
-void SplitEditor::finish() {
- assert(!OpenLI.getLI() && "Previous LI not closed before rewrite");
- assert(DupLI.getLI() && "No dupli for rewrite. Noop spilt?");
+ // Rewrite instructions.
+ rewriteAssigned();
- // Complete dupli liveness.
- computeRemainder();
+ // FIXME: Delete defs that were rematted everywhere.
// Get rid of unused values and set phi-kill flags.
for (LiveRangeEdit::iterator I = Edit.begin(), E = Edit.end(); I != E; ++I)
(*I)->RenumberValues(LIS);
- // Rewrite instructions.
- rewrite(Edit.getReg());
-
// Now check if any registers were separated into multiple components.
ConnectedVNInfoEqClasses ConEQ(LIS);
for (unsigned i = 0, e = Edit.size(); i != e; ++i) {
@@ -1061,9 +1021,8 @@ void SplitEditor::finish() {
dups.push_back(li);
for (unsigned i = 1; i != NumComp; ++i)
dups.push_back(&Edit.create(MRI, LIS, VRM));
+ rewriteComponents(dups, ConEQ);
ConEQ.Distribute(&dups[0]);
- // Rewrite uses to the new regs.
- rewrite(li->reg);
}
// Calculate spill weight and allocation hints for new intervals.
@@ -1095,9 +1054,6 @@ void SplitEditor::splitAroundLoop(const MachineLoop *Loop) {
sa_.getCriticalExits(Blocks, CriticalExits);
assert(CriticalExits.empty() && "Cannot break critical exits yet");
- // Get critical predecessors so computeRemainder can deal with them.
- sa_.getCriticalPreds(Blocks, criticalPreds_);
-
// Create new live interval for the loop.
openIntv();
diff --git a/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h
index bb4fca9084..5e9b96b629 100644
--- a/lib/CodeGen/SplitKit.h
+++ b/lib/CodeGen/SplitKit.h
@@ -13,11 +13,13 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/SlotIndexes.h"
namespace llvm {
+class ConnectedVNInfoEqClasses;
class LiveInterval;
class LiveIntervals;
class LiveRangeEdit;
@@ -263,6 +265,10 @@ public:
/// with defValue.
bool isComplexMapped(const VNInfo *ParentVNI) const;
+ /// markComplexMapped - Mark ParentVNI as complex mapped regardless of the
+ /// number of definitions.
+ void markComplexMapped(const VNInfo *ParentVNI) { Values[ParentVNI] = 0; }
+
// addSimpleRange - Add a simple range from ParentLI to LI.
// ParentVNI must be live in the [Start;End) interval.
void addSimpleRange(SlotIndex Start, SlotIndex End, const VNInfo *ParentVNI);
@@ -290,49 +296,49 @@ class SplitEditor {
LiveIntervals &LIS;
VirtRegMap &VRM;
MachineRegisterInfo &MRI;
+ MachineDominatorTree &MDT;
const TargetInstrInfo &TII;
const TargetRegisterInfo &TRI;
/// Edit - The current parent register and new intervals created.
LiveRangeEdit &Edit;
- /// DupLI - Created as a copy of CurLI, ranges are carved out as new
- /// intervals get added through openIntv / closeIntv. This is used to avoid
- /// editing CurLI.
- LiveIntervalMap DupLI;
+ /// Index into Edit of the currently open interval.
+ /// The index 0 is used for the complement, so the first interval started by
+ /// openIntv will be 1.
+ unsigned OpenIdx;
+
+ typedef IntervalMap<SlotIndex, unsigned> RegAssignMap;
+
+ /// Allocator for the interval map. This will eventually be shared with
+ /// SlotIndexes and LiveIntervals.
+ RegAssignMap::Allocator Allocator;
+
+ /// RegAssign - Map of the assigned register indexes.
+ /// Edit.get(RegAssign.lookup(Idx)) is the register that should be live at
+ /// Idx.
+ RegAssignMap RegAssign;
- /// Currently open LiveInterval.
- LiveIntervalMap OpenLI;
+ /// LIMappers - One LiveIntervalMap or each interval in Edit.
+ SmallVector<LiveIntervalMap, 4> LIMappers;
/// defFromParent - Define Reg from ParentVNI at UseIdx using either
/// rematerialization or a COPY from parent. Return the new value.
- VNInfo *defFromParent(LiveIntervalMap &Reg,
+ VNInfo *defFromParent(unsigned RegIdx,
VNInfo *ParentVNI,
SlotIndex UseIdx,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I);
- /// intervalsLiveAt - Return true if any member of intervals_ is live at Idx.
- bool intervalsLiveAt(SlotIndex Idx) const;
+ /// rewriteAssigned - Rewrite all uses of Edit.getReg() to assigned registers.
+ void rewriteAssigned();
- /// Values in CurLI whose live range has been truncated when entering an open
- /// li.
- SmallPtrSet<const VNInfo*, 8> truncatedValues;
-
- /// addTruncSimpleRange - Add the given simple range to DupLI after
- /// truncating any overlap with intervals_.
- void addTruncSimpleRange(SlotIndex Start, SlotIndex End, VNInfo *VNI);
-
- /// criticalPreds_ - Set of basic blocks where both dupli and OpenLI should be
- /// live out because of a critical edge.
- SplitAnalysis::BlockPtrSet criticalPreds_;
-
- /// computeRemainder - Compute the dupli liveness as the complement of all the
- /// new intervals.
- void computeRemainder();
-
- /// rewrite - Rewrite all uses of reg to use the new registers.
- void rewrite(unsigned reg);
+ /// rewriteComponents - Rewrite all uses of Intv[0] according to the eq
+ /// classes in ConEQ.
+ /// This must be done when Intvs[0] is styill live at all uses, before calling
+ /// ConEq.Distribute().
+ void rewriteComponents(const SmallVectorImpl<LiveInterval*> &Intvs,
+ const ConnectedVNInfoEqClasses &ConEq);
public:
/// Create a new SplitEditor for editing the LiveInterval analyzed by SA.
@@ -374,6 +380,9 @@ public:
/// remaining live range, and rewrite instructions to use the new registers.
void finish();
+ /// dump - print the current interval maping to dbgs().
+ void dump() const;
+
// ===--- High level methods ---===
/// splitAroundLoop - Split CurLI into a separate live interval inside