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
This commit is contained in:
Jakob Stoklund Olesen
2011-01-09 21:17:37 +00:00
parent 96b1b6c135
commit be97e906e0
9 changed files with 58 additions and 48 deletions

View File

@ -205,8 +205,7 @@ namespace llvm {
typedef SmallVector<LiveRange,4> Ranges; typedef SmallVector<LiveRange,4> Ranges;
typedef SmallVector<VNInfo*,4> VNInfoList; typedef SmallVector<VNInfo*,4> VNInfoList;
unsigned reg; // the register or stack slot of this interval const unsigned reg; // the register or stack slot of this interval.
// if the top bits is set, it represents a stack slot.
float weight; // weight of this interval float weight; // weight of this interval
Ranges ranges; // the ranges in which this register is live Ranges ranges; // the ranges in which this register is live
VNInfoList valnos; // value#'s VNInfoList valnos; // value#'s
@ -222,11 +221,8 @@ namespace llvm {
}; };
LiveInterval(unsigned Reg, float Weight, bool IsSS = false) LiveInterval(unsigned Reg, float Weight)
: reg(Reg), weight(Weight) { : reg(Reg), weight(Weight) {}
if (IsSS)
reg = reg | (1U << (sizeof(unsigned)*CHAR_BIT-1));
}
typedef Ranges::iterator iterator; typedef Ranges::iterator iterator;
iterator begin() { return ranges.begin(); } iterator begin() { return ranges.begin(); }
@ -275,19 +271,6 @@ namespace llvm {
ranges.clear(); 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 hasAtLeastOneValue() const { return !valnos.empty(); }
bool containsOneValue() const { return valnos.size() == 1; } bool containsOneValue() const { return valnos.size() == 1; }

View File

@ -52,19 +52,7 @@ namespace llvm {
unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); } unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC) { 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 &getInterval(int Slot) { LiveInterval &getInterval(int Slot) {
assert(Slot >= 0 && "Spill slot indice must be >= 0"); assert(Slot >= 0 && "Spill slot indice must be >= 0");

View File

@ -307,6 +307,31 @@ public:
FirstVirtualRegister = 16384 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 /// isPhysicalRegister - Return true if the specified register number is in
/// the physical register namespace. /// the physical register namespace.
static bool isPhysicalRegister(unsigned Reg) { static bool isPhysicalRegister(unsigned Reg) {
@ -317,7 +342,7 @@ public:
/// isVirtualRegister - Return true if the specified register number is in /// isVirtualRegister - Return true if the specified register number is in
/// the virtual register namespace. /// the virtual register namespace.
static bool isVirtualRegister(unsigned Reg) { static bool isVirtualRegister(unsigned Reg) {
assert(Reg && "this is not a register!"); assert(!isStackSlot(Reg) && "this is not a register!");
return Reg >= FirstVirtualRegister; return Reg >= FirstVirtualRegister;
} }

View File

@ -334,7 +334,8 @@ void InlineSpiller::spill(LiveInterval *li,
void InlineSpiller::spill(LiveRangeEdit &edit) { void InlineSpiller::spill(LiveRangeEdit &edit) {
edit_ = &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 " DEBUG(dbgs() << "Inline spilling "
<< mri_.getRegClass(edit.getReg())->getName() << mri_.getRegClass(edit.getReg())->getName()
<< ':' << edit.getParent() << "\n"); << ':' << edit.getParent() << "\n");

View File

@ -650,12 +650,7 @@ void LiveRange::dump() const {
} }
void LiveInterval::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const { void LiveInterval::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const {
if (isStackSlot()) OS << PrintReg(reg, TRI) << ',' << weight;
OS << "SS#" << getStackSlotIndex();
else
OS << PrintReg(reg, TRI);
OS << ',' << weight;
if (empty()) if (empty())
OS << " EMPTY"; OS << " EMPTY";

View File

@ -50,6 +50,22 @@ bool LiveStacks::runOnMachineFunction(MachineFunction &) {
return false; 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. /// print - Implement the dump method.
void LiveStacks::print(raw_ostream &OS, const Module*) const { void LiveStacks::print(raw_ostream &OS, const Module*) const {

View File

@ -80,7 +80,7 @@ protected:
assert(li->weight != HUGE_VALF && assert(li->weight != HUGE_VALF &&
"Attempting to spill already spilled value."); "Attempting to spill already spilled value.");
assert(!li->isStackSlot() && assert(!TargetRegisterInfo::isStackSlot(li->reg) &&
"Trying to spill a stack slot."); "Trying to spill a stack slot.");
DEBUG(dbgs() << "Trivial spill everywhere of reg" << li->reg << "\n"); DEBUG(dbgs() << "Trivial spill everywhere of reg" << li->reg << "\n");

View File

@ -218,7 +218,7 @@ void StackSlotColoring::InitializeSlots() {
for (LiveStacks::iterator i = LS->begin(), e = LS->end(); i != e; ++i) { for (LiveStacks::iterator i = LS->begin(), e = LS->end(); i != e; ++i) {
LiveInterval &li = i->second; LiveInterval &li = i->second;
DEBUG(li.dump()); DEBUG(li.dump());
int FI = li.getStackSlotIndex(); int FI = TargetRegisterInfo::stackSlot2Index(li.reg);
if (MFI->isDeadObjectIndex(FI)) if (MFI->isDeadObjectIndex(FI))
continue; continue;
SSIntervals.push_back(&li); SSIntervals.push_back(&li);
@ -261,7 +261,7 @@ StackSlotColoring::ColorSlotsWithFreeRegs(SmallVector<int, 16> &SlotMapping,
DEBUG(dbgs() << "Assigning unused registers to spill slots:\n"); DEBUG(dbgs() << "Assigning unused registers to spill slots:\n");
for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) { for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
LiveInterval *li = SSIntervals[i]; LiveInterval *li = SSIntervals[i];
int SS = li->getStackSlotIndex(); int SS = TargetRegisterInfo::stackSlot2Index(li->reg);
if (!UsedColors[SS] || li->weight < 20) if (!UsedColors[SS] || li->weight < 20)
// If the weight is < 20, i.e. two references in a loop with depth 1, // If the weight is < 20, i.e. two references in a loop with depth 1,
// don't bother with it. // don't bother with it.
@ -350,7 +350,7 @@ int StackSlotColoring::ColorSlot(LiveInterval *li) {
// Record the assignment. // Record the assignment.
Assignments[Color].push_back(li); Assignments[Color].push_back(li);
int FI = li->getStackSlotIndex(); int FI = TargetRegisterInfo::stackSlot2Index(li->reg);
DEBUG(dbgs() << "Assigning fi#" << FI << " to fi#" << Color << "\n"); DEBUG(dbgs() << "Assigning fi#" << FI << " to fi#" << Color << "\n");
// Change size and alignment of the allocated slot. If there are multiple // Change size and alignment of the allocated slot. If there are multiple
@ -379,7 +379,7 @@ bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
bool Changed = false; bool Changed = false;
for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) { for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
LiveInterval *li = SSIntervals[i]; LiveInterval *li = SSIntervals[i];
int SS = li->getStackSlotIndex(); int SS = TargetRegisterInfo::stackSlot2Index(li->reg);
int NewSS = ColorSlot(li); int NewSS = ColorSlot(li);
assert(NewSS >= 0 && "Stack coloring failed?"); assert(NewSS >= 0 && "Stack coloring failed?");
SlotMapping[SS] = NewSS; SlotMapping[SS] = NewSS;
@ -392,7 +392,7 @@ bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
DEBUG(dbgs() << "\nSpill slots after coloring:\n"); DEBUG(dbgs() << "\nSpill slots after coloring:\n");
for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) { for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
LiveInterval *li = SSIntervals[i]; LiveInterval *li = SSIntervals[i];
int SS = li->getStackSlotIndex(); int SS = TargetRegisterInfo::stackSlot2Index(li->reg);
li->weight = SlotWeights[SS]; li->weight = SlotWeights[SS];
} }
// Sort them by new weight. // Sort them by new weight.

View File

@ -43,9 +43,11 @@ TargetRegisterInfo::~TargetRegisterInfo() {}
void PrintReg::print(raw_ostream &OS) const { void PrintReg::print(raw_ostream &OS) const {
if (!Reg) if (!Reg)
OS << "%noreg"; OS << "%noreg";
else if (TargetRegisterInfo::isStackSlot(Reg))
OS << "SS#" << TargetRegisterInfo::stackSlot2Index(Reg);
else if (TargetRegisterInfo::isVirtualRegister(Reg)) else if (TargetRegisterInfo::isVirtualRegister(Reg))
OS << "%vreg" << TargetRegisterInfo::virtReg2Index(Reg); OS << "%vreg" << TargetRegisterInfo::virtReg2Index(Reg);
else if (TRI) else if (TRI && Reg < TRI->getNumRegs())
OS << '%' << TRI->getName(Reg); OS << '%' << TRI->getName(Reg);
else else
OS << "%physreg" << Reg; OS << "%physreg" << Reg;