summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-03-30 02:52:39 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-03-30 02:52:39 +0000
commitf22ca3fe5f0cfbb832cf41270f97cf5c0134fd7b (patch)
treedb0733bc6370b0714ba03a280821bc5375b2d0ce /lib
parent9f86e8054b5c29c82dbcff6fdb1dcefa122fe7ce (diff)
downloadllvm-f22ca3fe5f0cfbb832cf41270f97cf5c0134fd7b.tar.gz
llvm-f22ca3fe5f0cfbb832cf41270f97cf5c0134fd7b.tar.bz2
llvm-f22ca3fe5f0cfbb832cf41270f97cf5c0134fd7b.tar.xz
Treat clones the same as their origin.
When DCE clones a live range because it separates into connected components, make sure that the clones enter the same register allocator stage as the register they were cloned from. For instance, clones may be split even when they where created during spilling. Other registers created during spilling are not candidates for splitting or even (re-)spilling. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128524 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/LiveRangeEdit.cpp5
-rw-r--r--lib/CodeGen/LiveRangeEdit.h4
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp26
3 files changed, 29 insertions, 6 deletions
diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp
index 6b8a533b66..4c7b9e6be9 100644
--- a/lib/CodeGen/LiveRangeEdit.cpp
+++ b/lib/CodeGen/LiveRangeEdit.cpp
@@ -231,8 +231,11 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
continue;
DEBUG(dbgs() << NumComp << " components: " << *LI << '\n');
SmallVector<LiveInterval*, 8> Dups(1, LI);
- for (unsigned i = 1; i != NumComp; ++i)
+ for (unsigned i = 1; i != NumComp; ++i) {
Dups.push_back(&createFrom(LI->reg, LIS, VRM));
+ if (delegate_)
+ delegate_->LRE_DidCloneVirtReg(Dups.back()->reg, LI->reg);
+ }
ConEQ.Distribute(&Dups[0], VRM.getRegInfo());
}
}
diff --git a/lib/CodeGen/LiveRangeEdit.h b/lib/CodeGen/LiveRangeEdit.h
index e02e0a872d..c96dfd6998 100644
--- a/lib/CodeGen/LiveRangeEdit.h
+++ b/lib/CodeGen/LiveRangeEdit.h
@@ -43,6 +43,10 @@ public:
/// Called before shrinking the live range of a virtual register.
virtual void LRE_WillShrinkVirtReg(unsigned) {}
+ /// Called after cloning a virtual register.
+ /// This is used for new registers representing connected components of Old.
+ virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {}
+
virtual ~Delegate() {}
};
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index 098df59beb..05387d2727 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -90,7 +90,8 @@ class RAGreedy : public MachineFunctionPass,
// range splitting algorithm terminates, something that is otherwise hard to
// ensure.
enum LiveRangeStage {
- RS_Original, ///< Never seen before, never split.
+ RS_New, ///< Never seen before.
+ RS_First, ///< First time in the queue.
RS_Second, ///< Second time in the queue.
RS_Region, ///< Produced by region splitting.
RS_Block, ///< Produced by per-block splitting.
@@ -107,8 +108,11 @@ class RAGreedy : public MachineFunctionPass,
template<typename Iterator>
void setStage(Iterator Begin, Iterator End, LiveRangeStage NewStage) {
LRStage.resize(MRI->getNumVirtRegs());
- for (;Begin != End; ++Begin)
- LRStage[(*Begin)->reg] = NewStage;
+ for (;Begin != End; ++Begin) {
+ unsigned Reg = (*Begin)->reg;
+ if (LRStage[Reg] == RS_New)
+ LRStage[Reg] = NewStage;
+ }
}
// splitting state.
@@ -162,6 +166,7 @@ private:
void LRE_WillEraseInstruction(MachineInstr*);
bool LRE_CanEraseVirtReg(unsigned);
void LRE_WillShrinkVirtReg(unsigned);
+ void LRE_DidCloneVirtReg(unsigned, unsigned);
void mapGlobalInterference(unsigned, SmallVectorImpl<IndexPair>&);
float calcSplitConstraints(const SmallVectorImpl<IndexPair>&);
@@ -192,7 +197,7 @@ FunctionPass* llvm::createGreedyRegisterAllocator() {
return new RAGreedy();
}
-RAGreedy::RAGreedy(): MachineFunctionPass(ID), LRStage(RS_Original) {
+RAGreedy::RAGreedy(): MachineFunctionPass(ID), LRStage(RS_New) {
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
@@ -265,6 +270,14 @@ void RAGreedy::LRE_WillShrinkVirtReg(unsigned VirtReg) {
enqueue(&LI);
}
+void RAGreedy::LRE_DidCloneVirtReg(unsigned New, unsigned Old) {
+ // LRE may clone a virtual register because dead code elimination causes it to
+ // be split into connected components. Ensure that the new register gets the
+ // same stage as the parent.
+ LRStage.grow(New);
+ LRStage[New] = LRStage[Old];
+}
+
void RAGreedy::releaseMemory() {
SpillerInstance.reset(0);
LRStage.clear();
@@ -281,6 +294,9 @@ void RAGreedy::enqueue(LiveInterval *LI) {
unsigned Prio;
LRStage.grow(Reg);
+ if (LRStage[Reg] == RS_New)
+ LRStage[Reg] = RS_First;
+
if (LRStage[Reg] == RS_Second)
// Unsplit ranges that couldn't be allocated immediately are deferred until
// everything else has been allocated. Long ranges are allocated last so
@@ -1146,7 +1162,7 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
// Wait until the second time, when all smaller ranges have been allocated.
// This gives a better picture of the interference to split around.
LiveRangeStage Stage = getStage(VirtReg);
- if (Stage == RS_Original) {
+ if (Stage == RS_First) {
LRStage[VirtReg.reg] = RS_Second;
DEBUG(dbgs() << "wait for second round\n");
NewVRegs.push_back(&VirtReg);