aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/LiveInterval.h23
-rw-r--r--include/llvm/CodeGen/LiveStackAnalysis.h14
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h27
-rw-r--r--lib/CodeGen/InlineSpiller.cpp3
-rw-r--r--lib/CodeGen/LiveInterval.cpp7
-rw-r--r--lib/CodeGen/LiveStackAnalysis.cpp16
-rw-r--r--lib/CodeGen/Spiller.cpp2
-rw-r--r--lib/CodeGen/StackSlotColoring.cpp10
-rw-r--r--lib/Target/TargetRegisterInfo.cpp4
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<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; }
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<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.
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;