diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/CodeGen/RegAllocGreedy.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SplitKit.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SplitKit.h | 7 |
3 files changed, 32 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index c1372cd038c..378219b97be 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -426,8 +426,13 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) { if (!IntI.valid()) break; // Not live in, but before the first use. - if (IntI.start() < BI.FirstUse) + if (IntI.start() < BI.FirstUse) { BC.Entry = SpillPlacement::PrefSpill; + // If the block contains a kill from an earlier split, never split + // again in the same block. + if (!BI.LiveThrough && !SA->isOriginalEndpoint(BI.Kill)) + BC.Entry = SpillPlacement::MustSpill; + } } // Does interference overlap the uses in the entry segment @@ -458,8 +463,12 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) { IntI.advanceTo(BI.LastUse); if (!IntI.valid()) break; - if (IntI.start() < Stop) + if (IntI.start() < Stop) { BC.Exit = SpillPlacement::PrefSpill; + // Avoid splitting twice in the same block. + if (!BI.LiveThrough && !SA->isOriginalEndpoint(BI.Def)) + BC.Exit = SpillPlacement::MustSpill; + } } } } diff --git a/llvm/lib/CodeGen/SplitKit.cpp b/llvm/lib/CodeGen/SplitKit.cpp index 5663936bf3a..a97d890c25b 100644 --- a/llvm/lib/CodeGen/SplitKit.cpp +++ b/llvm/lib/CodeGen/SplitKit.cpp @@ -167,6 +167,20 @@ void SplitAnalysis::calcLiveBlockInfo() { } } +bool SplitAnalysis::isOriginalEndpoint(SlotIndex Idx) const { + unsigned OrigReg = VRM.getOriginal(CurLI->reg); + const LiveInterval &Orig = LIS.getInterval(OrigReg); + assert(!Orig.empty() && "Splitting empty interval?"); + LiveInterval::const_iterator I = Orig.find(Idx); + + // Range containing Idx should begin at Idx. + if (I != Orig.end() && I->start <= Idx) + return I->start == Idx; + + // Range does not contain Idx, previous must end at Idx. + return I != Orig.begin() && (--I)->end == Idx; +} + void SplitAnalysis::print(const BlockPtrSet &B, raw_ostream &OS) const { for (BlockPtrSet::const_iterator I = B.begin(), E = B.end(); I != E; ++I) { unsigned count = UsingBlocks.lookup(*I); diff --git a/llvm/lib/CodeGen/SplitKit.h b/llvm/lib/CodeGen/SplitKit.h index 5c34afd1c81..e02e6297035 100644 --- a/llvm/lib/CodeGen/SplitKit.h +++ b/llvm/lib/CodeGen/SplitKit.h @@ -125,6 +125,13 @@ public: return UsingBlocks.lookup(MBB); } + /// isOriginalEndpoint - Return true if the original live range was killed or + /// (re-)defined at Idx. Idx should be the 'def' slot for a normal kill/def, + /// and 'use' for an early-clobber def. + /// This can be used to recognize code inserted by earlier live range + /// splitting. + bool isOriginalEndpoint(SlotIndex Idx) const; + typedef SmallPtrSet<const MachineBasicBlock*, 16> BlockPtrSet; // Print a set of blocks with use counts. |