From 20d56d957f5b3c3ae4ea6316b6eef8b5df2daebb Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 20 Jul 2010 15:41:07 +0000 Subject: Beginning SplitKit - utility classes for live range splitting. This is a work in progress. So far we have some basic loop analysis to help determine where it is useful to split a live range around a loop. The actual loop splitting code from Splitter.cpp is also going to move in here. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108842 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/InlineSpiller.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/InlineSpiller.cpp') diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index 3c6c761..fc0357e 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -14,6 +14,7 @@ #define DEBUG_TYPE "spiller" #include "Spiller.h" +#include "SplitKit.h" #include "VirtRegMap.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -39,6 +40,8 @@ class InlineSpiller : public Spiller { const TargetRegisterInfo &tri_; const BitVector reserved_; + SplitAnalysis splitAnalysis_; + // Variables that are valid during spill(), but used by multiple methods. LiveInterval *li_; std::vector *newIntervals_; @@ -62,7 +65,8 @@ public: mri_(mf->getRegInfo()), tii_(*mf->getTarget().getInstrInfo()), tri_(*mf->getTarget().getRegisterInfo()), - reserved_(tri_.getReservedRegs(mf_)) {} + reserved_(tri_.getReservedRegs(mf_)), + splitAnalysis_(mf, lis, mli) {} void spill(LiveInterval *li, std::vector &newIntervals, @@ -70,6 +74,8 @@ public: SlotIndex *earliestIndex); private: + bool split(); + bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, SlotIndex UseIdx); bool reMaterializeFor(MachineBasicBlock::iterator MI); @@ -91,6 +97,22 @@ Spiller *createInlineSpiller(MachineFunction *mf, } } +/// split - try splitting the current interval into pieces that may allocate +/// separately. Return true if successful. +bool InlineSpiller::split() { + // FIXME: Add intra-MBB splitting. + if (lis_.intervalIsInOneMBB(*li_)) + return false; + + splitAnalysis_.analyze(li_); + + if (const MachineLoop *loop = splitAnalysis_.getBestSplitLoop()) { + if (splitAroundLoop(splitAnalysis_, loop)) + return true; + } + return false; +} + /// allUsesAvailableAt - Return true if all registers used by OrigMI at /// OrigIdx are also available with the same value at UseIdx. bool InlineSpiller::allUsesAvailableAt(const MachineInstr *OrigMI, @@ -338,6 +360,9 @@ void InlineSpiller::spill(LiveInterval *li, rc_ = mri_.getRegClass(li->reg); spillIs_ = &spillIs; + if (split()) + return; + reMaterializeAll(); // Remat may handle everything. -- cgit v1.1