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
};
- 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(); }
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; }
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");
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) {
/// 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;
}
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");
}
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";
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 {
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");
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);
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.
// 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
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;
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.
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;