Add SplitEditor to SplitKit. This class will be used to edit live intervals and
rewrite instructions for live range splitting.
Still work in progress.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109469 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h
index cd059df..601fc17 100644
--- a/lib/CodeGen/SplitKit.h
+++ b/lib/CodeGen/SplitKit.h
@@ -14,19 +14,22 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/SlotIndexes.h"
namespace llvm {
class LiveInterval;
class LiveIntervals;
-class MachineBasicBlock;
class MachineInstr;
-class MachineFunction;
-class MachineFunctionPass;
class MachineLoop;
class MachineLoopInfo;
+class MachineRegisterInfo;
class TargetInstrInfo;
+class VirtRegMap;
+class VNInfo;
+/// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting
+/// opportunities.
class SplitAnalysis {
const MachineFunction &mf_;
const LiveIntervals &lis_;
@@ -63,6 +66,8 @@
/// split.
void analyze(const LiveInterval *li);
+ const LiveInterval *getCurLI() { return curli_; }
+
/// clear - clear all data structures so SplitAnalysis is ready to analyze a
/// new interval.
void clear();
@@ -113,8 +118,85 @@
const MachineLoop *getBestSplitLoop();
};
-/// splitAroundLoop - Try to split curli into a separate live interval inside
-/// the loop. Retun true on success.
-bool splitAroundLoop(SplitAnalysis&, const MachineLoop*);
+/// SplitEditor - Edit machine code and LiveIntervals for live range
+/// splitting.
+///
+/// 1. Create a SplitEditor from a SplitAnalysis. This will create a new
+/// LiveInterval, dupli, that is identical to SA.curli.
+/// 2. Start a new live interval with openLI.
+/// 3. Insert copies to the new interval with copyTo* and mark the ranges where
+/// it should be used with use*.
+/// 4. Insert back-copies with copyFromLI.
+/// 5. Finish the current LI with closeLI and repeat from 2.
+/// 6. Rewrite instructions with rewrite().
+///
+class SplitEditor {
+ SplitAnalysis &sa_;
+ LiveIntervals &lis_;
+ VirtRegMap &vrm_;
+ MachineRegisterInfo &mri_;
+ const TargetInstrInfo &tii_;
+
+ /// dupli_ - Created as a copy of sa_.curli_, ranges are carved out as new
+ /// intervals get added through openLI / closeLI.
+ LiveInterval *dupli_;
+
+ /// Currently open LiveInterval.
+ LiveInterval *openli_;
+
+ /// createInterval - Create a new virtual register and LiveInterval with same
+ /// register class and spill slot as curli.
+ LiveInterval *createInterval();
+
+ /// valueMap_ - Map values in dupli to values in openli. These are direct 1-1
+ /// mappings, and do not include values created by inserted copies.
+ DenseMap<VNInfo*,VNInfo*> valueMap_;
+
+ /// mapValue - Return the openli value that corresponds to the given dupli
+ /// value.
+ VNInfo *mapValue(VNInfo *dupliVNI);
+
+public:
+ /// Create a new SplitEditor for editing the LiveInterval analyzed by SA.
+ SplitEditor(SplitAnalysis&, LiveIntervals&, VirtRegMap&);
+
+ /// getAnalysis - Get the corresponding analysis.
+ SplitAnalysis &getAnalysis() { return sa_; }
+
+ /// Create a new virtual register and live interval to be used by following
+ /// use* and copy* calls.
+ void openLI();
+
+ /// copyToPHI - Insert a copy to openli at the end of A, and catch it with a
+ /// PHI def at the beginning of the successor B. This call is ignored if dupli
+ /// is not live out of A.
+ void copyToPHI(MachineBasicBlock &A, MachineBasicBlock &B);
+
+ /// useLI - indicate that all instructions in MBB should use openli.
+ void useLI(const MachineBasicBlock &MBB);
+
+ /// useLI - indicate that all instructions in range should use openli.
+ void useLI(SlotIndex Start, SlotIndex End);
+
+ /// copyFromLI - Insert a copy back to dupli from openli at position I.
+ /// This also marks the remainder of MBB as not used by openli.
+ SlotIndex copyFromLI(MachineBasicBlock &MBB, MachineBasicBlock::iterator I);
+
+ /// closeLI - Indicate that we are done editing the currently open
+ /// LiveInterval, and ranges can be trimmed.
+ void closeLI();
+
+ /// rewrite - after all the new live ranges have been created, rewrite
+ /// instructions using curli to use the new intervals.
+ void rewrite();
+
+ // ===--- High level methods ---===
+
+ /// splitAroundLoop - Split curli into a separate live interval inside
+ /// the loop.
+ void splitAroundLoop(const MachineLoop*);
+
+};
+
}