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*);
+
+};
+
 
 }