Teach TargetRegisterInfo how to cram stack slot indexes in with the virtual and
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Sun, 9 Jan 2011 21:17:37 +0000 (21:17 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Sun, 9 Jan 2011 21:17:37 +0000 (21:17 +0000)
physical register numbers.

This makes the hack used in LiveInterval official, and lets LiveInterval be
oblivious of stack slots.

The isPhysicalRegister() and isVirtualRegister() predicates don't know about
this, so when a variable may contain a stack slot, isStackSlot() should always
be tested first.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123128 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/LiveInterval.h
include/llvm/CodeGen/LiveStackAnalysis.h
include/llvm/Target/TargetRegisterInfo.h
lib/CodeGen/InlineSpiller.cpp
lib/CodeGen/LiveInterval.cpp
lib/CodeGen/LiveStackAnalysis.cpp
lib/CodeGen/Spiller.cpp
lib/CodeGen/StackSlotColoring.cpp
lib/Target/TargetRegisterInfo.cpp

index 192f07ec569fe32bbe59b60f3708b711a09f654b..b2915cee97d4ad2a64a18ca2618a486a76ff0d83 100644 (file)
@@ -205,8 +205,7 @@ namespace llvm {
     typedef SmallVector<LiveRange,4> Ranges;
     typedef SmallVector<VNInfo*,4> VNInfoList;
 
-    unsigned reg;        // the register or stack slot of this interval
-                         // if the top bits is set, it represents a stack slot.
+    const unsigned reg;  // the register or stack slot of this interval.
     float weight;        // weight of this interval
     Ranges ranges;       // the ranges in which this register is live
     VNInfoList valnos;   // value#'s
@@ -222,11 +221,8 @@ namespace llvm {
 
     };
 
-    LiveInterval(unsigned Reg, float Weight, bool IsSS = false)
-      : reg(Reg), weight(Weight) {
-      if (IsSS)
-        reg = reg | (1U << (sizeof(unsigned)*CHAR_BIT-1));
-    }
+    LiveInterval(unsigned Reg, float Weight)
+      : reg(Reg), weight(Weight) {}
 
     typedef Ranges::iterator iterator;
     iterator begin() { return ranges.begin(); }
@@ -275,19 +271,6 @@ namespace llvm {
       ranges.clear();
     }
 
-    /// isStackSlot - Return true if this is a stack slot interval.
-    ///
-    bool isStackSlot() const {
-      return reg & (1U << (sizeof(unsigned)*CHAR_BIT-1));
-    }
-
-    /// getStackSlotIndex - Return stack slot index if this is a stack slot
-    /// interval.
-    int getStackSlotIndex() const {
-      assert(isStackSlot() && "Interval is not a stack slot interval!");
-      return reg & ~(1U << (sizeof(unsigned)*CHAR_BIT-1));
-    }
-
     bool hasAtLeastOneValue() const { return !valnos.empty(); }
 
     bool containsOneValue() const { return valnos.size() == 1; }
index 9310a30a4d23165817d8ba8a8df10f1471beb4e8..8a8dcaf5728f08be9b9a8dbbee0bcf0fb0b08a0f 100644 (file)
@@ -52,19 +52,7 @@ namespace llvm {
 
     unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
 
-    LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC) {
-      assert(Slot >= 0 && "Spill slot indice must be >= 0");
-      SS2IntervalMap::iterator I = S2IMap.find(Slot);
-      if (I == S2IMap.end()) {
-        I = S2IMap.insert(I,std::make_pair(Slot, LiveInterval(Slot,0.0F,true)));
-        S2RCMap.insert(std::make_pair(Slot, RC));
-      } else {
-        // Use the largest common subclass register class.
-        const TargetRegisterClass *OldRC = S2RCMap[Slot];
-        S2RCMap[Slot] = getCommonSubClass(OldRC, RC);
-      }
-      return I->second;
-    }
+    LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC);
 
     LiveInterval &getInterval(int Slot) {
       assert(Slot >= 0 && "Spill slot indice must be >= 0");
index b8fa8a07dc797ac00d3855f9b5cf7895cfe9443c..c2a973e0db0cccde1f897a863852a6a6bd403a94 100644 (file)
@@ -307,6 +307,31 @@ public:
     FirstVirtualRegister = 16384
   };
 
+  /// isStackSlot - Sometimes it is useful the be able to store a non-negative
+  /// frame index in a variable that normally holds a register. isStackSlot()
+  /// returns true if Reg is in the range used for stack slots.
+  ///
+  /// Note that isVirtualRegister() and isPhysicalRegister() may also return
+  /// true for such a value. In that case, isStackSlot() takes precedence.
+  ///
+  static bool isStackSlot(unsigned Reg) {
+    return Reg >= (1u << 31);
+  }
+
+  /// stackSlot2Index - Compute the frame index from a register value
+  /// representing a stack slot.
+  static int stackSlot2Index(unsigned Reg) {
+    assert(isStackSlot(Reg) && "Not a stack slot");
+    return int(Reg - (1u << 31));
+  }
+
+  /// index2StackSlot - Convert a non-negative frame index to a stack slot
+  /// register value.
+  static unsigned index2StackSlot(int FI) {
+    assert(FI >= 0 && "Cannot hold a negative frame index.");
+    return FI + (1u << 31);
+  }
+
   /// isPhysicalRegister - Return true if the specified register number is in
   /// the physical register namespace.
   static bool isPhysicalRegister(unsigned Reg) {
@@ -317,7 +342,7 @@ public:
   /// isVirtualRegister - Return true if the specified register number is in
   /// the virtual register namespace.
   static bool isVirtualRegister(unsigned Reg) {
-    assert(Reg && "this is not a register!");
+    assert(!isStackSlot(Reg) && "this is not a register!");
     return Reg >= FirstVirtualRegister;
   }
 
index f5a27b24177c04f9b0f9deadafe10fe615deef37..3e4f6c83036b2d4a8de6ba27da21f609d8e29fdf 100644 (file)
@@ -334,7 +334,8 @@ void InlineSpiller::spill(LiveInterval *li,
 
 void InlineSpiller::spill(LiveRangeEdit &edit) {
   edit_ = &edit;
-  assert(!edit.getParent().isStackSlot() && "Trying to spill a stack slot.");
+  assert(!TargetRegisterInfo::isStackSlot(edit.getReg())
+         && "Trying to spill a stack slot.");
   DEBUG(dbgs() << "Inline spilling "
                << mri_.getRegClass(edit.getReg())->getName()
                << ':' << edit.getParent() << "\n");
index 65a4d2b19dd501dcb94ddbd7f53ac742c0a66112..c6a014951636ce0884110c2ef11c5f26a5c0bf2e 100644 (file)
@@ -650,12 +650,7 @@ void LiveRange::dump() const {
 }
 
 void LiveInterval::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const {
-  if (isStackSlot())
-    OS << "SS#" << getStackSlotIndex();
-  else
-    OS << PrintReg(reg, TRI);
-
-  OS << ',' << weight;
+  OS << PrintReg(reg, TRI) << ',' << weight;
 
   if (empty())
     OS << " EMPTY";
index 895bd2e4b132e02d16d6b2f8e2a0afe745366db1..c75196a472100679f7b24ee6936fb92f2297caca 100644 (file)
@@ -50,6 +50,22 @@ bool LiveStacks::runOnMachineFunction(MachineFunction &) {
   return false;
 }
 
+LiveInterval &
+LiveStacks::getOrCreateInterval(int Slot, const TargetRegisterClass *RC) {
+  assert(Slot >= 0 && "Spill slot indice must be >= 0");
+  SS2IntervalMap::iterator I = S2IMap.find(Slot);
+  if (I == S2IMap.end()) {
+    I = S2IMap.insert(I, std::make_pair(Slot,
+            LiveInterval(TargetRegisterInfo::index2StackSlot(Slot), 0.0F)));
+    S2RCMap.insert(std::make_pair(Slot, RC));
+  } else {
+    // Use the largest common subclass register class.
+    const TargetRegisterClass *OldRC = S2RCMap[Slot];
+    S2RCMap[Slot] = getCommonSubClass(OldRC, RC);
+  }
+  return I->second;
+}
+
 /// print - Implement the dump method.
 void LiveStacks::print(raw_ostream &OS, const Module*) const {
 
index c7df369583c25a4d66a709aeab69900b974fd850..fd385824aff915faccae96c1a9467b051029a6c9 100644 (file)
@@ -80,7 +80,7 @@ protected:
     assert(li->weight != HUGE_VALF &&
            "Attempting to spill already spilled value.");
 
-    assert(!li->isStackSlot() &&
+    assert(!TargetRegisterInfo::isStackSlot(li->reg) &&
            "Trying to spill a stack slot.");
 
     DEBUG(dbgs() << "Trivial spill everywhere of reg" << li->reg << "\n");
index 4a6ae60b9a8b30ebc0426900a03f27a86aecb97d..01f5b5627f4f4499e10ec647a7ec0d6a28928782 100644 (file)
@@ -218,7 +218,7 @@ void StackSlotColoring::InitializeSlots() {
   for (LiveStacks::iterator i = LS->begin(), e = LS->end(); i != e; ++i) {
     LiveInterval &li = i->second;
     DEBUG(li.dump());
-    int FI = li.getStackSlotIndex();
+    int FI = TargetRegisterInfo::stackSlot2Index(li.reg);
     if (MFI->isDeadObjectIndex(FI))
       continue;
     SSIntervals.push_back(&li);
@@ -261,7 +261,7 @@ StackSlotColoring::ColorSlotsWithFreeRegs(SmallVector<int, 16> &SlotMapping,
   DEBUG(dbgs() << "Assigning unused registers to spill slots:\n");
   for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
     LiveInterval *li = SSIntervals[i];
-    int SS = li->getStackSlotIndex();
+    int SS = TargetRegisterInfo::stackSlot2Index(li->reg);
     if (!UsedColors[SS] || li->weight < 20)
       // If the weight is < 20, i.e. two references in a loop with depth 1,
       // don't bother with it.
@@ -350,7 +350,7 @@ int StackSlotColoring::ColorSlot(LiveInterval *li) {
 
   // Record the assignment.
   Assignments[Color].push_back(li);
-  int FI = li->getStackSlotIndex();
+  int FI = TargetRegisterInfo::stackSlot2Index(li->reg);
   DEBUG(dbgs() << "Assigning fi#" << FI << " to fi#" << Color << "\n");
 
   // Change size and alignment of the allocated slot. If there are multiple
@@ -379,7 +379,7 @@ bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
   bool Changed = false;
   for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
     LiveInterval *li = SSIntervals[i];
-    int SS = li->getStackSlotIndex();
+    int SS = TargetRegisterInfo::stackSlot2Index(li->reg);
     int NewSS = ColorSlot(li);
     assert(NewSS >= 0 && "Stack coloring failed?");
     SlotMapping[SS] = NewSS;
@@ -392,7 +392,7 @@ bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
   DEBUG(dbgs() << "\nSpill slots after coloring:\n");
   for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
     LiveInterval *li = SSIntervals[i];
-    int SS = li->getStackSlotIndex();
+    int SS = TargetRegisterInfo::stackSlot2Index(li->reg);
     li->weight = SlotWeights[SS];
   }
   // Sort them by new weight.
index 9c0bfa11b0e1d998a49f671b84a2453cc110dc5e..11d57fe2b0c6111de4c5818d12ca32274611b810 100644 (file)
@@ -43,9 +43,11 @@ TargetRegisterInfo::~TargetRegisterInfo() {}
 void PrintReg::print(raw_ostream &OS) const {
   if (!Reg)
     OS << "%noreg";
+  else if (TargetRegisterInfo::isStackSlot(Reg))
+    OS << "SS#" << TargetRegisterInfo::stackSlot2Index(Reg);
   else if (TargetRegisterInfo::isVirtualRegister(Reg))
     OS << "%vreg" << TargetRegisterInfo::virtReg2Index(Reg);
-  else if (TRI)
+  else if (TRI && Reg < TRI->getNumRegs())
     OS << '%' << TRI->getName(Reg);
   else
     OS << "%physreg" << Reg;