Handle load/store of misaligned vectors that are the
[oota-llvm.git] / lib / CodeGen / VirtRegMap.h
index 7ca06bbd1a348076a3ba078b9228e1e051dc14d5..d1c14f662eef8da85c2c1f451772f44dcff162bb 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #ifndef LLVM_CODEGEN_VIRTREGMAP_H
 #define LLVM_CODEGEN_VIRTREGMAP_H
 
-#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/Streams.h"
 #include <map>
 
@@ -66,6 +67,10 @@ namespace llvm {
     /// mapping.
     IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap;
 
+    /// Virt2SplitKillMap - This is splitted virtual register to its last use
+    /// (kill) index mapping.
+    IndexedMap<unsigned> Virt2SplitKillMap;
+
     /// ReMatMap - This is virtual register to re-materialized instruction
     /// mapping. Each virtual register whose definition is going to be
     /// re-materialized has an entry in it.
@@ -80,7 +85,8 @@ namespace llvm {
     /// SpillPt2VirtMap - This records the virtual registers which should
     /// be spilled right after the MachineInstr due to live interval
     /// splitting.
-    std::map<MachineInstr*, std::vector<unsigned> > SpillPt2VirtMap;
+    std::map<MachineInstr*, std::vector<std::pair<unsigned,bool> > >
+    SpillPt2VirtMap;
 
     /// RestorePt2VirtMap - This records the virtual registers which should
     /// be restored right before the MachineInstr due to live interval
@@ -93,6 +99,12 @@ namespace llvm {
     /// conflicts with stack slot numbers.
     int ReMatId;
 
+    /// LowSpillSlot, HighSpillSlot - Lowest and highest spill slot indexes.
+    int LowSpillSlot, HighSpillSlot;
+
+    /// SpillSlotToUsesMap - Records uses for each register spill slot.
+    SmallVector<SmallPtrSet<MachineInstr*, 4>, 8> SpillSlotToUsesMap;
+
     VirtRegMap(const VirtRegMap&);     // DO NOT IMPLEMENT
     void operator=(const VirtRegMap&); // DO NOT IMPLEMENT
 
@@ -110,15 +122,15 @@ namespace llvm {
     /// @brief returns the physical register mapped to the specified
     /// virtual register
     unsigned getPhys(unsigned virtReg) const {
-      assert(MRegisterInfo::isVirtualRegister(virtReg));
+      assert(TargetRegisterInfo::isVirtualRegister(virtReg));
       return Virt2PhysMap[virtReg];
     }
 
     /// @brief creates a mapping for the specified virtual register to
     /// the specified physical register
     void assignVirt2Phys(unsigned virtReg, unsigned physReg) {
-      assert(MRegisterInfo::isVirtualRegister(virtReg) &&
-             MRegisterInfo::isPhysicalRegister(physReg));
+      assert(TargetRegisterInfo::isVirtualRegister(virtReg) &&
+             TargetRegisterInfo::isPhysicalRegister(physReg));
       assert(Virt2PhysMap[virtReg] == NO_PHYS_REG &&
              "attempt to assign physical register to already mapped "
              "virtual register");
@@ -128,7 +140,7 @@ namespace llvm {
     /// @brief clears the specified virtual register's, physical
     /// register mapping
     void clearVirt(unsigned virtReg) {
-      assert(MRegisterInfo::isVirtualRegister(virtReg));
+      assert(TargetRegisterInfo::isVirtualRegister(virtReg));
       assert(Virt2PhysMap[virtReg] != NO_PHYS_REG &&
              "attempt to clear a not assigned virtual register");
       Virt2PhysMap[virtReg] = NO_PHYS_REG;
@@ -164,14 +176,14 @@ namespace llvm {
     /// @brief returns the stack slot mapped to the specified virtual
     /// register
     int getStackSlot(unsigned virtReg) const {
-      assert(MRegisterInfo::isVirtualRegister(virtReg));
+      assert(TargetRegisterInfo::isVirtualRegister(virtReg));
       return Virt2StackSlotMap[virtReg];
     }
 
     /// @brief returns the rematerialization id mapped to the specified virtual
     /// register
     int getReMatId(unsigned virtReg) const {
-      assert(MRegisterInfo::isVirtualRegister(virtReg));
+      assert(TargetRegisterInfo::isVirtualRegister(virtReg));
       return Virt2ReMatIdMap[virtReg];
     }
 
@@ -209,6 +221,20 @@ namespace llvm {
       ReMatMap[virtReg] = def;
     }
 
+    /// @brief record the last use (kill) of a split virtual register.
+    void addKillPoint(unsigned virtReg, unsigned index) {
+      Virt2SplitKillMap[virtReg] = index;
+    }
+
+    unsigned getKillPoint(unsigned virtReg) const {
+      return Virt2SplitKillMap[virtReg];
+    }
+
+    /// @brief remove the last use (kill) of a split virtual register.
+    void removeKillPoint(unsigned virtReg) {
+      Virt2SplitKillMap[virtReg] = 0;
+    }
+
     /// @brief returns true if the specified MachineInstr is a spill point.
     bool isSpillPt(MachineInstr *Pt) const {
       return SpillPt2VirtMap.find(Pt) != SpillPt2VirtMap.end();
@@ -216,30 +242,31 @@ namespace llvm {
 
     /// @brief returns the virtual registers that should be spilled due to
     /// splitting right after the specified MachineInstr.
-    std::vector<unsigned> &getSpillPtSpills(MachineInstr *Pt) {
+    std::vector<std::pair<unsigned,bool> > &getSpillPtSpills(MachineInstr *Pt) {
       return SpillPt2VirtMap[Pt];
     }
 
     /// @brief records the specified MachineInstr as a spill point for virtReg.
-    void addSpillPoint(unsigned virtReg, MachineInstr *Pt) {
+    void addSpillPoint(unsigned virtReg, bool isKill, MachineInstr *Pt) {
       if (SpillPt2VirtMap.find(Pt) != SpillPt2VirtMap.end())
-        SpillPt2VirtMap[Pt].push_back(virtReg);
+        SpillPt2VirtMap[Pt].push_back(std::make_pair(virtReg, isKill));
       else {
-        std::vector<unsigned> Virts;
-        Virts.push_back(virtReg);
+        std::vector<std::pair<unsigned,bool> > Virts;
+        Virts.push_back(std::make_pair(virtReg, isKill));
         SpillPt2VirtMap.insert(std::make_pair(Pt, Virts));
       }
     }
 
     void transferSpillPts(MachineInstr *Old, MachineInstr *New) {
-      std::map<MachineInstr*,std::vector<unsigned> >::iterator I =
-        SpillPt2VirtMap.find(Old);
+      std::map<MachineInstr*,std::vector<std::pair<unsigned,bool> > >::iterator
+        I = SpillPt2VirtMap.find(Old);
       if (I == SpillPt2VirtMap.end())
         return;
       while (!I->second.empty()) {
-        unsigned virtReg = I->second.back();
+        unsigned virtReg = I->second.back().first;
+        bool isKill = I->second.back().second;
         I->second.pop_back();
-        addSpillPoint(virtReg, New);
+        addSpillPoint(virtReg, isKill, New);
       }
       SpillPt2VirtMap.erase(I);
     }
@@ -279,11 +306,29 @@ namespace llvm {
       RestorePt2VirtMap.erase(I);
     }
 
+    /// @brief Return lowest spill slot index.
+    int getLowSpillSlot() const {
+      return LowSpillSlot;
+    }
+
+    /// @brief Return highest spill slot index.
+    int getHighSpillSlot() const {
+      return HighSpillSlot;
+    }
+
+    /// @brief Records a spill slot use.
+    void addSpillSlotUse(int FrameIndex, MachineInstr *MI);
+
+    /// @brief Returns true if spill slot has been used.
+    bool isSpillSlotUsed(int FrameIndex) const {
+      assert(FrameIndex >= 0 && "Spill slot index should not be negative!");
+      return !SpillSlotToUsesMap[FrameIndex-LowSpillSlot].empty();
+    }
+
     /// @brief Updates information about the specified virtual register's value
-    /// folded into newMI machine instruction.  The OpNum argument indicates the
-    /// operand number of OldMI that is folded.
-    void virtFolded(unsigned VirtReg, MachineInstr *OldMI, unsigned OpNum,
-                    MachineInstr *NewMI);
+    /// folded into newMI machine instruction.
+    void virtFolded(unsigned VirtReg, MachineInstr *OldMI, MachineInstr *NewMI,
+                    ModRef MRInfo);
 
     /// @brief Updates information about the specified virtual register's value
     /// folded into the specified machine instruction.
@@ -298,11 +343,7 @@ namespace llvm {
     
     /// RemoveMachineInstrFromMaps - MI is being erased, remove it from the
     /// the folded instruction map and spill point map.
-    void RemoveMachineInstrFromMaps(MachineInstr *MI) {
-      MI2VirtMap.erase(MI);
-      SpillPt2VirtMap.erase(MI);
-      RestorePt2VirtMap.erase(MI);
-    }
+    void RemoveMachineInstrFromMaps(MachineInstr *MI);
 
     void print(std::ostream &OS) const;
     void print(std::ostream *OS) const { if (OS) print(*OS); }