diff options
Diffstat (limited to 'lib/CodeGen/SplitKit.h')
-rw-r--r-- | lib/CodeGen/SplitKit.h | 94 |
1 files changed, 88 insertions, 6 deletions
diff --git a/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h index cd059dffd6..601fc17092 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 @@ public: /// 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 @@ public: 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*); + +}; + } |