Index: lib/CodeGen/SplitKit.h =================================================================== --- lib/CodeGen/SplitKit.h +++ lib/CodeGen/SplitKit.h @@ -38,6 +38,43 @@ class VNInfo; class raw_ostream; +/// Analyze the last point in BB to insert split with respect to current +/// LiveInterval. HoistSpillHelper also depends on the same analysis to find +/// the last point to insert spill. +class LLVM_LIBRARY_VISIBILITY LSplitPointAnalysis { +private: + const MachineFunction &MF; + const VirtRegMap &VRM; + const LiveIntervals &LIS; + + // Current LiveInterval to split or spill. + const LiveInterval *CurLI; + /// LastSplitPoint - Last legal split point in each basic block in the current + /// function. The first entry is the first terminator, the second entry is the + /// last valid split point for a variable that is live in to a landing pad + /// successor. + SmallVector, 8> LastSplitPoint; + + SlotIndex computeLastSplitPoint(unsigned Num); +public: + LSplitPointAnalysis(const VirtRegMap &vrm, const LiveIntervals &lis); + + void setInterval(const LiveInterval *LI) { CurLI = LI; } + + /// getLastSplitPoint - Return the base index of the last valid split point + /// in the basic block numbered Num. + SlotIndex getLastSplitPoint(unsigned Num) { + // Inline the common simple case. + if (LastSplitPoint[Num].first.isValid() && + !LastSplitPoint[Num].second.isValid()) + return LastSplitPoint[Num].first; + return computeLastSplitPoint(Num); + } + + /// getLastSplitPointIter - Returns the last split point as an iterator. + MachineBasicBlock::iterator getLastSplitPointIter(MachineBasicBlock *); +}; + /// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting /// opportunities. class LLVM_LIBRARY_VISIBILITY SplitAnalysis { @@ -84,15 +121,12 @@ // Current live interval. const LiveInterval *CurLI; + // Last Split Point Analysis. + LSplitPointAnalysis LSPA; + // Sorted slot indexes of using instructions. SmallVector UseSlots; - /// LastSplitPoint - Last legal split point in each basic block in the current - /// function. The first entry is the first terminator, the second entry is the - /// last valid split point for a variable that is live in to a landing pad - /// successor. - SmallVector, 8> LastSplitPoint; - /// UseBlocks - Blocks where CurLI has uses. SmallVector UseBlocks; @@ -109,8 +143,6 @@ /// DidRepairRange - analyze was forced to shrinkToUses(). bool DidRepairRange; - SlotIndex computeLastSplitPoint(unsigned Num); - // Sumarize statistics by counting instructions using CurLI. void analyzeUses(); @@ -137,19 +169,6 @@ /// getParent - Return the last analyzed interval. const LiveInterval &getParent() const { return *CurLI; } - /// getLastSplitPoint - Return the base index of the last valid split point - /// in the basic block numbered Num. - SlotIndex getLastSplitPoint(unsigned Num) { - // Inline the common simple case. - if (LastSplitPoint[Num].first.isValid() && - !LastSplitPoint[Num].second.isValid()) - return LastSplitPoint[Num].first; - return computeLastSplitPoint(Num); - } - - /// getLastSplitPointIter - Returns the last split point as an iterator. - MachineBasicBlock::iterator getLastSplitPointIter(MachineBasicBlock*); - /// 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. @@ -195,6 +214,14 @@ /// @param BI The block to be isolated. /// @param SingleInstrs True when single instructions should be isolated. bool shouldSplitSingleBlock(const BlockInfo &BI, bool SingleInstrs) const; + + SlotIndex getLastSplitPoint(unsigned Num) { + return LSPA.getLastSplitPoint(Num); + } + + MachineBasicBlock::iterator getLastSplitPointIter(MachineBasicBlock *BB) { + return LSPA.getLastSplitPointIter(BB); + } }; Index: lib/CodeGen/SplitKit.cpp =================================================================== --- lib/CodeGen/SplitKit.cpp +++ lib/CodeGen/SplitKit.cpp @@ -38,24 +38,14 @@ STATISTIC(NumRepairs, "Number of invalid live ranges repaired"); //===----------------------------------------------------------------------===// -// Split Analysis +// Last Split Point Analysis //===----------------------------------------------------------------------===// - -SplitAnalysis::SplitAnalysis(const VirtRegMap &vrm, const LiveIntervals &lis, - const MachineLoopInfo &mli) - : MF(vrm.getMachineFunction()), VRM(vrm), LIS(lis), Loops(mli), - TII(*MF.getSubtarget().getInstrInfo()), CurLI(nullptr), +LSplitPointAnalysis::LSplitPointAnalysis(const VirtRegMap &vrm, + const LiveIntervals &lis) + : MF(vrm.getMachineFunction()), VRM(vrm), LIS(lis), CurLI(nullptr), LastSplitPoint(MF.getNumBlockIDs()) {} -void SplitAnalysis::clear() { - UseSlots.clear(); - UseBlocks.clear(); - ThroughBlocks.clear(); - CurLI = nullptr; - DidRepairRange = false; -} - -SlotIndex SplitAnalysis::computeLastSplitPoint(unsigned Num) { +SlotIndex LSplitPointAnalysis::computeLastSplitPoint(unsigned Num) { const MachineBasicBlock *MBB = MF.getBlockNumbered(Num); // FIXME: Handle multiple EH pad successors. const MachineBasicBlock *LPad = MBB->getLandingPadSuccessor(); @@ -109,13 +99,31 @@ } MachineBasicBlock::iterator -SplitAnalysis::getLastSplitPointIter(MachineBasicBlock *MBB) { +LSplitPointAnalysis::getLastSplitPointIter(MachineBasicBlock *MBB) { SlotIndex LSP = getLastSplitPoint(MBB->getNumber()); if (LSP == LIS.getMBBEndIdx(MBB)) return MBB->end(); return LIS.getInstructionFromIndex(LSP); } +//===----------------------------------------------------------------------===// +// Split Analysis +//===----------------------------------------------------------------------===// + +SplitAnalysis::SplitAnalysis(const VirtRegMap &vrm, const LiveIntervals &lis, + const MachineLoopInfo &mli) + : MF(vrm.getMachineFunction()), VRM(vrm), LIS(lis), Loops(mli), + TII(*MF.getSubtarget().getInstrInfo()), CurLI(nullptr), LSPA(vrm, lis) {} + +void SplitAnalysis::clear() { + UseSlots.clear(); + UseBlocks.clear(); + ThroughBlocks.clear(); + CurLI = nullptr; + LSPA.setInterval(nullptr); + DidRepairRange = false; +} + /// analyzeUses - Count instructions, basic blocks, and loops using CurLI. void SplitAnalysis::analyzeUses() { assert(UseSlots.empty() && "Call clear first"); @@ -310,6 +318,7 @@ void SplitAnalysis::analyze(const LiveInterval *li) { clear(); CurLI = li; + LSPA.setInterval(li); analyzeUses(); }