From be97e906e03dd9b22e14f6749157c9d5f9701dd5 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sun, 9 Jan 2011 21:17:37 +0000 Subject: Teach TargetRegisterInfo how to cram stack slot indexes in with the virtual and 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 | 23 +++-------------------- include/llvm/CodeGen/LiveStackAnalysis.h | 14 +------------- include/llvm/Target/TargetRegisterInfo.h | 27 ++++++++++++++++++++++++++- lib/CodeGen/InlineSpiller.cpp | 3 ++- lib/CodeGen/LiveInterval.cpp | 7 +------ lib/CodeGen/LiveStackAnalysis.cpp | 16 ++++++++++++++++ lib/CodeGen/Spiller.cpp | 2 +- lib/CodeGen/StackSlotColoring.cpp | 10 +++++----- lib/Target/TargetRegisterInfo.cpp | 4 +++- 9 files changed, 58 insertions(+), 48 deletions(-) diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 192f07ec56..b2915cee97 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -205,8 +205,7 @@ namespace llvm { typedef SmallVector Ranges; typedef SmallVector 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; } diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h index 9310a30a4d..8a8dcaf572 100644 --- a/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/include/llvm/CodeGen/LiveStackAnalysis.h @@ -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"); diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index b8fa8a07dc..c2a973e0db 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -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; } diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index f5a27b2417..3e4f6c8303 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -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"); diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 65a4d2b19d..c6a0149516 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -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"; diff --git a/lib/CodeGen/LiveStackAnalysis.cpp b/lib/CodeGen/LiveStackAnalysis.cpp index 895bd2e4b1..c75196a472 100644 --- a/lib/CodeGen/LiveStackAnalysis.cpp +++ b/lib/CodeGen/LiveStackAnalysis.cpp @@ -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 { diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index c7df369583..fd385824af 100644 --- a/lib/CodeGen/Spiller.cpp +++ b/lib/CodeGen/Spiller.cpp @@ -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"); diff --git a/lib/CodeGen/StackSlotColoring.cpp b/lib/CodeGen/StackSlotColoring.cpp index 4a6ae60b9a..01f5b5627f 100644 --- a/lib/CodeGen/StackSlotColoring.cpp +++ b/lib/CodeGen/StackSlotColoring.cpp @@ -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 &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. diff --git a/lib/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp index 9c0bfa11b0..11d57fe2b0 100644 --- a/lib/Target/TargetRegisterInfo.cpp +++ b/lib/Target/TargetRegisterInfo.cpp @@ -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; -- cgit v1.2.3