Reapply r110396, with fixes to appease the Linux buildbot gods.
[oota-llvm.git] / include / llvm / CodeGen / LiveIntervalAnalysis.h
index 473cc8e099694acd35a1143580b46a2be7b7dd34..b154bf1b0510488bb301d436c9b055e377149b61 100644 (file)
 #ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
 #define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
 
+#include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/SlotIndexes.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Allocator.h"
 #include <cmath>
-#include <map>
+#include <iterator>
 
 namespace llvm {
 
+  class AliasAnalysis;
   class LiveVariables;
   class MachineLoopInfo;
   class TargetRegisterInfo;
@@ -39,90 +42,43 @@ namespace llvm {
   class TargetInstrInfo;
   class TargetRegisterClass;
   class VirtRegMap;
-  typedef std::pair<unsigned, MachineBasicBlock*> IdxMBBPair;
-
-  inline bool operator<(unsigned V, const IdxMBBPair &IM) {
-    return V < IM.first;
-  }
-
-  inline bool operator<(const IdxMBBPair &IM, unsigned V) {
-    return IM.first < V;
-  }
-
-  struct Idx2MBBCompare {
-    bool operator()(const IdxMBBPair &LHS, const IdxMBBPair &RHS) const {
-      return LHS.first < RHS.first;
-    }
-  };
-
+  
   class LiveIntervals : public MachineFunctionPass {
     MachineFunction* mf_;
     MachineRegisterInfo* mri_;
     const TargetMachine* tm_;
     const TargetRegisterInfo* tri_;
     const TargetInstrInfo* tii_;
+    AliasAnalysis *aa_;
     LiveVariables* lv_;
+    SlotIndexes* indexes_;
 
     /// Special pool allocator for VNInfo's (LiveInterval val#).
     ///
-    BumpPtrAllocator VNInfoAllocator;
-
-    /// MBB2IdxMap - The indexes of the first and last instructions in the
-    /// specified basic block.
-    std::vector<std::pair<unsigned, unsigned> > MBB2IdxMap;
-
-    /// Idx2MBBMap - Sorted list of pairs of index of first instruction
-    /// and MBB id.
-    std::vector<IdxMBBPair> Idx2MBBMap;
-
-    typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
-    Mi2IndexMap mi2iMap_;
-
-    typedef std::vector<MachineInstr*> Index2MiMap;
-    Index2MiMap i2miMap_;
+    VNInfo::Allocator VNInfoAllocator;
 
-    typedef std::map<unsigned, LiveInterval> Reg2IntervalMap;
+    typedef DenseMap<unsigned, LiveInterval*> Reg2IntervalMap;
     Reg2IntervalMap r2iMap_;
 
+    /// allocatableRegs_ - A bit vector of allocatable registers.
     BitVector allocatableRegs_;
 
-    std::vector<MachineInstr*> ClonedMIs;
+    /// CloneMIs - A list of clones as result of re-materialization.
+    std::vector<MachineInstr*> CloneMIs;
 
   public:
     static char ID; // Pass identification, replacement for typeid
-    LiveIntervals() : MachineFunctionPass((intptr_t)&ID) {}
-
-    struct InstrSlots {
-      enum {
-        LOAD  = 0,
-        USE   = 1,
-        DEF   = 2,
-        STORE = 3,
-        NUM   = 4
-      };
-    };
+    LiveIntervals() : MachineFunctionPass(ID) {}
 
-    static unsigned getBaseIndex(unsigned index) {
-      return index - (index % InstrSlots::NUM);
-    }
-    static unsigned getBoundaryIndex(unsigned index) {
-      return getBaseIndex(index + InstrSlots::NUM - 1);
-    }
-    static unsigned getLoadIndex(unsigned index) {
-      return getBaseIndex(index) + InstrSlots::LOAD;
-    }
-    static unsigned getUseIndex(unsigned index) {
-      return getBaseIndex(index) + InstrSlots::USE;
-    }
-    static unsigned getDefIndex(unsigned index) {
-      return getBaseIndex(index) + InstrSlots::DEF;
-    }
-    static unsigned getStoreIndex(unsigned index) {
-      return getBaseIndex(index) + InstrSlots::STORE;
-    }
+    // Calculate the spill weight to assign to a single instruction.
+    static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);
 
-    static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth) {
-      return (isDef + isUse) * powf(10.0F, (float)loopDepth);
+    // After summing the spill weights of all defs and uses, the final weight
+    // should be normalized, dividing the weight of the interval by its size.
+    // This encourages spilling of intervals that are large and have few uses,
+    // and discourages spilling of small intervals with many uses.
+    void normalizeSpillWeight(LiveInterval &li) {
+      li.weight /= getApproximateInstructionCount(li) + 25;
     }
 
     typedef Reg2IntervalMap::iterator iterator;
@@ -136,139 +92,165 @@ namespace llvm {
     LiveInterval &getInterval(unsigned reg) {
       Reg2IntervalMap::iterator I = r2iMap_.find(reg);
       assert(I != r2iMap_.end() && "Interval does not exist for register");
-      return I->second;
+      return *I->second;
     }
 
     const LiveInterval &getInterval(unsigned reg) const {
       Reg2IntervalMap::const_iterator I = r2iMap_.find(reg);
       assert(I != r2iMap_.end() && "Interval does not exist for register");
-      return I->second;
+      return *I->second;
     }
 
     bool hasInterval(unsigned reg) const {
       return r2iMap_.count(reg);
     }
 
-    /// getMBBStartIdx - Return the base index of the first instruction in the
-    /// specified MachineBasicBlock.
-    unsigned getMBBStartIdx(MachineBasicBlock *MBB) const {
-      return getMBBStartIdx(MBB->getNumber());
-    }
-    unsigned getMBBStartIdx(unsigned MBBNo) const {
-      assert(MBBNo < MBB2IdxMap.size() && "Invalid MBB number!");
-      return MBB2IdxMap[MBBNo].first;
+    /// getScaledIntervalSize - get the size of an interval in "units,"
+    /// where every function is composed of one thousand units.  This
+    /// measure scales properly with empty index slots in the function.
+    double getScaledIntervalSize(LiveInterval& I) {
+      return (1000.0 * I.getSize()) / indexes_->getIndexesLength();
     }
 
-    /// getMBBEndIdx - Return the store index of the last instruction in the
-    /// specified MachineBasicBlock.
-    unsigned getMBBEndIdx(MachineBasicBlock *MBB) const {
-      return getMBBEndIdx(MBB->getNumber());
-    }
-    unsigned getMBBEndIdx(unsigned MBBNo) const {
-      assert(MBBNo < MBB2IdxMap.size() && "Invalid MBB number!");
-      return MBB2IdxMap[MBBNo].second;
+    /// getFuncInstructionCount - Return the number of instructions in the
+    /// current function.
+    unsigned getFuncInstructionCount() {
+      return indexes_->getFunctionSize();
     }
-
-    /// getMBBFromIndex - given an index in any instruction of an
-    /// MBB return a pointer the MBB
-    MachineBasicBlock* getMBBFromIndex(unsigned index) const {
-      std::vector<IdxMBBPair>::const_iterator I =
-        std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), index);
-      // Take the pair containing the index
-      std::vector<IdxMBBPair>::const_iterator J =
-        ((I != Idx2MBBMap.end() && I->first > index) ||
-         (I == Idx2MBBMap.end() && Idx2MBBMap.size()>0)) ? (I-1): I;
-
-      assert(J != Idx2MBBMap.end() && J->first < index+1 &&
-             index <= getMBBEndIdx(J->second) &&
-             "index does not correspond to an MBB");
-      return J->second;
-    }
-
-    /// getInstructionIndex - returns the base index of instr
-    unsigned getInstructionIndex(MachineInstr* instr) const {
-      Mi2IndexMap::const_iterator it = mi2iMap_.find(instr);
-      assert(it != mi2iMap_.end() && "Invalid instruction!");
-      return it->second;
-    }
-
-    /// getInstructionFromIndex - given an index in any slot of an
-    /// instruction return a pointer the instruction
-    MachineInstr* getInstructionFromIndex(unsigned index) const {
-      index /= InstrSlots::NUM; // convert index to vector index
-      assert(index < i2miMap_.size() &&
-             "index does not correspond to an instruction");
-      return i2miMap_[index];
+    
+    /// getApproximateInstructionCount - computes an estimate of the number
+    /// of instructions in a given LiveInterval.
+    unsigned getApproximateInstructionCount(LiveInterval& I) {
+      double IntervalPercentage = getScaledIntervalSize(I) / 1000.0;
+      return (unsigned)(IntervalPercentage * indexes_->getFunctionSize());
     }
 
-    /// conflictsWithPhysRegDef - Returns true if the specified register
-    /// is defined during the duration of the specified interval.
-    bool conflictsWithPhysRegDef(const LiveInterval &li, VirtRegMap &vrm,
-                                 unsigned reg);
+    /// conflictsWithPhysReg - Returns true if the specified register is used or
+    /// defined during the duration of the specified interval. Copies to and
+    /// from li.reg are allowed. This method is only able to analyze simple
+    /// ranges that stay within a single basic block. Anything else is
+    /// considered a conflict.
+    bool conflictsWithPhysReg(const LiveInterval &li, VirtRegMap &vrm,
+                              unsigned reg);
 
-    /// findLiveInMBBs - Given a live range, if the value of the range
-    /// is live in any MBB returns true as well as the list of basic blocks
-    /// where the value is live in.
-    bool findLiveInMBBs(const LiveRange &LR,
-                        SmallVectorImpl<MachineBasicBlock*> &MBBs) const;
+    /// conflictsWithAliasRef - Similar to conflictsWithPhysRegRef except
+    /// it checks for alias uses and defs.
+    bool conflictsWithAliasRef(LiveInterval &li, unsigned Reg,
+                                   SmallPtrSet<MachineInstr*,32> &JoinedCopies);
 
     // Interval creation
-
     LiveInterval &getOrCreateInterval(unsigned reg) {
       Reg2IntervalMap::iterator I = r2iMap_.find(reg);
       if (I == r2iMap_.end())
-        I = r2iMap_.insert(I, std::make_pair(reg, createInterval(reg)));
-      return I->second;
+        I = r2iMap_.insert(std::make_pair(reg, createInterval(reg))).first;
+      return *I->second;
     }
+
+    /// dupInterval - Duplicate a live interval. The caller is responsible for
+    /// managing the allocated memory.
+    LiveInterval *dupInterval(LiveInterval *li);
     
     /// addLiveRangeToEndOfBlock - Given a register and an instruction,
     /// adds a live range from that instruction to the end of its MBB.
     LiveRange addLiveRangeToEndOfBlock(unsigned reg,
-                                        MachineInstr* startInst);
+                                       MachineInstr* startInst);
 
     // Interval removal
 
     void removeInterval(unsigned Reg) {
-      r2iMap_.erase(Reg);
+      DenseMap<unsigned, LiveInterval*>::iterator I = r2iMap_.find(Reg);
+      delete I->second;
+      r2iMap_.erase(I);
+    }
+
+    SlotIndex getZeroIndex() const {
+      return indexes_->getZeroIndex();
+    }
+
+    SlotIndex getInvalidIndex() const {
+      return indexes_->getInvalidIndex();
+    }
+
+    /// isNotInMIMap - returns true if the specified machine instr has been
+    /// removed or was never entered in the map.
+    bool isNotInMIMap(const MachineInstr* Instr) const {
+      return !indexes_->hasIndex(Instr);
     }
 
-    /// isRemoved - returns true if the specified machine instr has been
-    /// removed.
-    bool isRemoved(MachineInstr* instr) const {
-      return !mi2iMap_.count(instr);
+    /// Returns the base index of the given instruction.
+    SlotIndex getInstructionIndex(const MachineInstr *instr) const {
+      return indexes_->getInstructionIndex(instr);
+    }
+    
+    /// Returns the instruction associated with the given index.
+    MachineInstr* getInstructionFromIndex(SlotIndex index) const {
+      return indexes_->getInstructionFromIndex(index);
+    }
+
+    /// Return the first index in the given basic block.
+    SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
+      return indexes_->getMBBStartIdx(mbb);
+    } 
+
+    /// Return the last index in the given basic block.
+    SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
+      return indexes_->getMBBEndIdx(mbb);
+    } 
+
+    bool isLiveInToMBB(const LiveInterval &li,
+                       const MachineBasicBlock *mbb) const {
+      return li.liveAt(getMBBStartIdx(mbb));
+    }
+
+    LiveRange* findEnteringRange(LiveInterval &li,
+                                 const MachineBasicBlock *mbb) {
+      return li.getLiveRangeContaining(getMBBStartIdx(mbb));
+    }
+
+    bool isLiveOutOfMBB(const LiveInterval &li,
+                        const MachineBasicBlock *mbb) const {
+      return li.liveAt(getMBBEndIdx(mbb).getPrevSlot());
+    }
+
+    LiveRange* findExitingRange(LiveInterval &li,
+                                const MachineBasicBlock *mbb) {
+      return li.getLiveRangeContaining(getMBBEndIdx(mbb).getPrevSlot());
+    }
+
+    MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
+      return indexes_->getMBBFromIndex(index);
+    }
+
+    SlotIndex getMBBTerminatorGap(const MachineBasicBlock *mbb) {
+      return indexes_->getTerminatorGap(mbb);
+    }
+
+    SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) {
+      return indexes_->insertMachineInstrInMaps(MI);
     }
 
-    /// RemoveMachineInstrFromMaps - This marks the specified machine instr as
-    /// deleted.
     void RemoveMachineInstrFromMaps(MachineInstr *MI) {
-      // remove index -> MachineInstr and
-      // MachineInstr -> index mappings
-      Mi2IndexMap::iterator mi2i = mi2iMap_.find(MI);
-      if (mi2i != mi2iMap_.end()) {
-        i2miMap_[mi2i->second/InstrSlots::NUM] = 0;
-        mi2iMap_.erase(mi2i);
-      }
+      indexes_->removeMachineInstrFromMaps(MI);
     }
 
-    /// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in
-    /// maps used by register allocator.
     void ReplaceMachineInstrInMaps(MachineInstr *MI, MachineInstr *NewMI) {
-      Mi2IndexMap::iterator mi2i = mi2iMap_.find(MI);
-      if (mi2i == mi2iMap_.end())
-        return;
-      i2miMap_[mi2i->second/InstrSlots::NUM] = NewMI;
-      Mi2IndexMap::iterator it = mi2iMap_.find(MI);
-      assert(it != mi2iMap_.end() && "Invalid instruction!");
-      unsigned Index = it->second;
-      mi2iMap_.erase(it);
-      mi2iMap_[NewMI] = Index;
+      indexes_->replaceMachineInstrInMaps(MI, NewMI);
+    }
+
+    void InsertMBBInMaps(MachineBasicBlock *MBB) {
+      indexes_->insertMBBInMaps(MBB);
+    }
+
+    bool findLiveInMBBs(SlotIndex Start, SlotIndex End,
+                        SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
+      return indexes_->findLiveInMBBs(Start, End, MBBs);
     }
 
-    BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; }
+    void renumber() {
+      indexes_->renumberIndexes();
+    }
 
-    /// getVNInfoSourceReg - Helper function that parses the specified VNInfo
-    /// copy field and returns the source register that defines it.
-    unsigned getVNInfoSourceReg(const VNInfo *VNI) const;
+    VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
 
     virtual void getAnalysisUsage(AnalysisUsage &AU) const;
     virtual void releaseMemory();
@@ -277,28 +259,33 @@ namespace llvm {
     virtual bool runOnMachineFunction(MachineFunction&);
 
     /// print - Implement the dump method.
-    virtual void print(std::ostream &O, const Module* = 0) const;
-    void print(std::ostream *O, const Module* M = 0) const {
-      if (O) print(*O, M);
-    }
+    virtual void print(raw_ostream &O, const Module* = 0) const;
 
     /// addIntervalsForSpills - Create new intervals for spilled defs / uses of
     /// the given interval. FIXME: It also returns the weight of the spill slot
     /// (if any is created) by reference. This is temporary.
     std::vector<LiveInterval*>
     addIntervalsForSpills(const LiveInterval& i,
-                          const MachineLoopInfo *loopInfo, VirtRegMap& vrm,
-                          float &SSWeight);
+                          SmallVectorImpl<LiveInterval*> &SpillIs,
+                          const MachineLoopInfo *loopInfo, VirtRegMap& vrm);
 
     /// spillPhysRegAroundRegDefsUses - Spill the specified physical register
-    /// around all defs and uses of the specified interval.
-    void spillPhysRegAroundRegDefsUses(const LiveInterval &li,
+    /// around all defs and uses of the specified interval. Return true if it
+    /// was able to cut its interval.
+    bool spillPhysRegAroundRegDefsUses(const LiveInterval &li,
                                        unsigned PhysReg, VirtRegMap &vrm);
 
     /// isReMaterializable - Returns true if every definition of MI of every
     /// val# of the specified interval is re-materializable. Also returns true
     /// by reference if all of the defs are load instructions.
-    bool isReMaterializable(const LiveInterval &li, bool &isLoad);
+    bool isReMaterializable(const LiveInterval &li,
+                            SmallVectorImpl<LiveInterval*> &SpillIs,
+                            bool &isLoad);
+
+    /// isReMaterializable - Returns true if the definition MI of the specified
+    /// val# of the specified interval is re-materializable.
+    bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo,
+                            MachineInstr *MI);
 
     /// getRepresentativeReg - Find the largest super register of the specified
     /// physical register.
@@ -309,38 +296,47 @@ namespace llvm {
     unsigned getNumConflictsWithPhysReg(const LiveInterval &li,
                                         unsigned PhysReg) const;
 
-    /// computeNumbering - Compute the index numbering.
-    void computeNumbering();
+    /// intervalIsInOneMBB - Returns true if the specified interval is entirely
+    /// within a single basic block.
+    bool intervalIsInOneMBB(const LiveInterval &li) const;
 
   private:      
     /// computeIntervals - Compute live intervals.
     void computeIntervals();
-    
+
     /// handleRegisterDef - update intervals for a register def
     /// (calls handlePhysicalRegisterDef and
     /// handleVirtualRegisterDef)
     void handleRegisterDef(MachineBasicBlock *MBB,
-                           MachineBasicBlock::iterator MI, unsigned MIIdx,
-                           unsigned reg);
+                           MachineBasicBlock::iterator MI,
+                           SlotIndex MIIdx,
+                           MachineOperand& MO, unsigned MOIdx);
+
+    /// isPartialRedef - Return true if the specified def at the specific index
+    /// is partially re-defining the specified live interval. A common case of
+    /// this is a definition of the sub-register. 
+    bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
+                        LiveInterval &interval);
 
     /// handleVirtualRegisterDef - update intervals for a virtual
     /// register def
     void handleVirtualRegisterDef(MachineBasicBlock *MBB,
                                   MachineBasicBlock::iterator MI,
-                                  unsigned MIIdx,
+                                  SlotIndex MIIdx, MachineOperand& MO,
+                                  unsigned MOIdx,
                                   LiveInterval& interval);
 
     /// handlePhysicalRegisterDef - update intervals for a physical register
     /// def.
     void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
                                    MachineBasicBlock::iterator mi,
-                                   unsigned MIIdx,
+                                   SlotIndex MIIdx, MachineOperand& MO,
                                    LiveInterval &interval,
                                    MachineInstr *CopyMI);
 
     /// handleLiveInRegister - Create interval for a livein register.
     void handleLiveInRegister(MachineBasicBlock* mbb,
-                              unsigned MIIdx,
+                              SlotIndex MIIdx,
                               LiveInterval &interval, bool isAlias = false);
 
     /// getReMatImplicitUse - If the remat definition MI has one (for now, we
@@ -353,22 +349,24 @@ namespace llvm {
     /// which reaches the given instruction also reaches the specified use
     /// index.
     bool isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI,
-                            unsigned UseIdx) const;
+                            SlotIndex UseIdx) const;
 
     /// isReMaterializable - Returns true if the definition MI of the specified
     /// val# of the specified interval is re-materializable. Also returns true
     /// by reference if the def is a load.
     bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo,
-                            MachineInstr *MI, bool &isLoad);
+                            MachineInstr *MI,
+                            SmallVectorImpl<LiveInterval*> &SpillIs,
+                            bool &isLoad);
 
     /// tryFoldMemoryOperand - Attempts to fold either a spill / restore from
     /// slot / to reg or any rematerialized load into ith operand of specified
     /// MI. If it is successul, MI is updated with the newly created MI and
     /// returns true.
     bool tryFoldMemoryOperand(MachineInstr* &MI, VirtRegMap &vrm,
-                              MachineInstr *DefMI, unsigned InstrIdx,
+                              MachineInstr *DefMI, SlotIndex InstrIdx,
                               SmallVector<unsigned, 2> &Ops,
-                              bool isSS, int Slot, unsigned Reg);
+                              bool isSS, int FrameIndex, unsigned Reg);
 
     /// canFoldMemoryOperand - Return true if the specified load / store
     /// folding is possible.
@@ -379,11 +377,8 @@ namespace llvm {
     /// anyKillInMBBAfterIdx - Returns true if there is a kill of the specified
     /// VNInfo that's after the specified index but is within the basic block.
     bool anyKillInMBBAfterIdx(const LiveInterval &li, const VNInfo *VNI,
-                              MachineBasicBlock *MBB, unsigned Idx) const;
-
-    /// intervalIsInOneMBB - Returns true if the specified interval is entirely
-    /// within a single basic block.
-    bool intervalIsInOneMBB(const LiveInterval &li) const;
+                              MachineBasicBlock *MBB,
+                              SlotIndex Idx) const;
 
     /// hasAllocatableSuperReg - Return true if the specified physical register
     /// has any super register that's allocatable.
@@ -391,18 +386,19 @@ namespace llvm {
 
     /// SRInfo - Spill / restore info.
     struct SRInfo {
-      int index;
+      SlotIndex index;
       unsigned vreg;
       bool canFold;
-      SRInfo(int i, unsigned vr, bool f) : index(i), vreg(vr), canFold(f) {};
+      SRInfo(SlotIndex i, unsigned vr, bool f)
+        : index(i), vreg(vr), canFold(f) {}
     };
 
-    bool alsoFoldARestore(int Id, int index, unsigned vr,
+    bool alsoFoldARestore(int Id, SlotIndex index, unsigned vr,
                           BitVector &RestoreMBBs,
-                          std::map<unsigned,std::vector<SRInfo> >&RestoreIdxes);
-    void eraseRestoreInfo(int Id, int index, unsigned vr,
+                          DenseMap<unsigned,std::vector<SRInfo> >&RestoreIdxes);
+    void eraseRestoreInfo(int Id, SlotIndex index, unsigned vr,
                           BitVector &RestoreMBBs,
-                          std::map<unsigned,std::vector<SRInfo> >&RestoreIdxes);
+                          DenseMap<unsigned,std::vector<SRInfo> >&RestoreIdxes);
 
     /// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
     /// spilled and create empty intervals for their uses.
@@ -419,14 +415,15 @@ namespace llvm {
     /// functions for addIntervalsForSpills to rewrite uses / defs for the given
     /// live range.
     bool rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
-        bool TrySplit, unsigned index, unsigned end, MachineInstr *MI,
-        MachineInstr *OrigDefMI, MachineInstr *DefMI, unsigned Slot, int LdSlot,
+        bool TrySplit, SlotIndex index, SlotIndex end,
+        MachineInstr *MI, MachineInstr *OrigDefMI, MachineInstr *DefMI,
+        unsigned Slot, int LdSlot,
         bool isLoad, bool isLoadSS, bool DefIsReMat, bool CanDelete,
         VirtRegMap &vrm, const TargetRegisterClass* rc,
         SmallVector<int, 4> &ReMatIds, const MachineLoopInfo *loopInfo,
         unsigned &NewVReg, unsigned ImpUse, bool &HasDef, bool &HasUse,
-        std::map<unsigned,unsigned> &MBBVRegsMap,
-        std::vector<LiveInterval*> &NewLIs, float &SSWeight);
+        DenseMap<unsigned,unsigned> &MBBVRegsMap,
+        std::vector<LiveInterval*> &NewLIs);
     void rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
         LiveInterval::Ranges::const_iterator &I,
         MachineInstr *OrigDefMI, MachineInstr *DefMI, unsigned Slot, int LdSlot,
@@ -434,17 +431,20 @@ namespace llvm {
         VirtRegMap &vrm, const TargetRegisterClass* rc,
         SmallVector<int, 4> &ReMatIds, const MachineLoopInfo *loopInfo,
         BitVector &SpillMBBs,
-        std::map<unsigned,std::vector<SRInfo> > &SpillIdxes,
+        DenseMap<unsigned,std::vector<SRInfo> > &SpillIdxes,
         BitVector &RestoreMBBs,
-        std::map<unsigned,std::vector<SRInfo> > &RestoreIdxes,
-        std::map<unsigned,unsigned> &MBBVRegsMap,
-        std::vector<LiveInterval*> &NewLIs, float &SSWeight);
+        DenseMap<unsigned,std::vector<SRInfo> > &RestoreIdxes,
+        DenseMap<unsigned,unsigned> &MBBVRegsMap,
+        std::vector<LiveInterval*> &NewLIs);
 
-    static LiveInterval createInterval(unsigned Reg);
+    // Normalize the spill weight of all the intervals in NewLIs.
+    void normalizeSpillWeights(std::vector<LiveInterval*> &NewLIs);
 
-    void printRegName(unsigned reg) const;
-  };
+    static LiveInterval* createInterval(unsigned Reg);
 
+    void printInstrs(raw_ostream &O) const;
+    void dumpInstrs() const;
+  };
 } // End llvm namespace
 
 #endif