[llvm-commits] CVS: llvm/lib/Target/ARM/ARMRegisterInfo.cpp ARMRegisterInfo.h
Evan Cheng
evan.cheng at apple.com
Tue Mar 6 02:04:13 PST 2007
Changes in directory llvm/lib/Target/ARM:
ARMRegisterInfo.cpp updated: 1.79 -> 1.80
ARMRegisterInfo.h updated: 1.15 -> 1.16
---
Log message:
Scavenge a register using the register scavenger when needed.
---
Diffs of the changes: (+111 -14)
ARMRegisterInfo.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++++++++----
ARMRegisterInfo.h | 10 +---
2 files changed, 111 insertions(+), 14 deletions(-)
Index: llvm/lib/Target/ARM/ARMRegisterInfo.cpp
diff -u llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.79 llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.80
--- llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.79 Thu Mar 1 19:17:17 2007
+++ llvm/lib/Target/ARM/ARMRegisterInfo.cpp Tue Mar 6 04:03:56 2007
@@ -85,11 +85,6 @@
: ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
TII(tii), STI(sti),
FramePtr(STI.useThumbBacktraces() ? ARM::R7 : ARM::R11) {
- RS = (EnableScavenging) ? new RegScavenger() : NULL;
-}
-
-ARMRegisterInfo::~ARMRegisterInfo() {
- delete RS;
}
bool ARMRegisterInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
@@ -329,6 +324,25 @@
}
bool
+ARMRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
+ switch (Reg) {
+ default: break;
+ case ARM::SP:
+ case ARM::PC:
+ return true;
+ case ARM::R7:
+ case ARM::R11:
+ if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF)))
+ return true;
+ break;
+ case ARM::R9:
+ return STI.isR9Reserved();
+ }
+
+ return false;
+}
+
+bool
ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
return EnableScavenging && !AFI->isThumbFunction();
@@ -918,15 +932,34 @@
// to form it with a series of ADDri's. Do this by taking 8-bit chunks
// out of 'Offset'.
unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
- assert(ScratchReg && "Unable to find a free register!");
+ if (ScratchReg == 0)
+ // No register is "free". Scavenge a register.
+ ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II);
emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
isSub ? -Offset : Offset, TII);
MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
}
}
-void ARMRegisterInfo::
-processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
+static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
+ const MachineFrameInfo *FFI = MF.getFrameInfo();
+ int Offset = 0;
+ for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
+ int FixedOff = -FFI->getObjectOffset(i);
+ if (FixedOff > Offset) Offset = FixedOff;
+ }
+ for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
+ Offset += FFI->getObjectSize(i);
+ unsigned Align = FFI->getObjectAlignment(i);
+ // Adjust to alignment boundary
+ Offset = (Offset+Align-1)/Align*Align;
+ }
+ return (unsigned)Offset;
+}
+
+void
+ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ RegScavenger *RS) const {
// This tells PEI to spill the FP as if it is any other callee-save register
// to take advantage the eliminateFrameIndex machinery. This also ensures it
// is spilled in the order specified by getCalleeSavedRegs() to make it easier
@@ -1020,6 +1053,7 @@
}
}
+ bool ExtraCSSpill = false;
if (!CanEliminateFrame || hasFP(MF)) {
AFI->setHasStackFrame(true);
@@ -1032,6 +1066,7 @@
UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
ForceLRSpill = false;
+ ExtraCSSpill = true;
}
// Darwin ABI requires FP to point to the stack slot that contains the
@@ -1050,10 +1085,74 @@
unsigned Reg = UnspilledCS1GPRs.front();
MF.changePhyRegUsed(Reg, true);
AFI->setCSRegisterIsSpilled(Reg);
+ if (!isReservedReg(MF, Reg))
+ ExtraCSSpill = true;
} else if (!UnspilledCS2GPRs.empty()) {
unsigned Reg = UnspilledCS2GPRs.front();
MF.changePhyRegUsed(Reg, true);
AFI->setCSRegisterIsSpilled(Reg);
+ if (!isReservedReg(MF, Reg))
+ ExtraCSSpill = true;
+ }
+ }
+
+ // Estimate if we might need to scavenge a register at some point in order
+ // to materialize a stack offset. If so, either spill one additiona
+ // callee-saved register or reserve a special spill slot to facilitate
+ // register scavenging.
+ if (RS && !ExtraCSSpill && !AFI->isThumbFunction()) {
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ unsigned Size = estimateStackSize(MF, MFI);
+ unsigned Limit = (1 << 12) - 1;
+ for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB)
+ for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) {
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+ if (I->getOperand(i).isFrameIndex()) {
+ unsigned Opcode = I->getOpcode();
+ const TargetInstrDescriptor &Desc = TII.get(Opcode);
+ unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
+ if (AddrMode == ARMII::AddrMode3) {
+ Limit = (1 << 8) - 1;
+ goto DoneEstimating;
+ } else if (AddrMode == ARMII::AddrMode5) {
+ Limit = ((1 << 8) - 1) * 4;
+ goto DoneEstimating;
+ }
+ }
+ }
+ DoneEstimating:
+ if (Size >= Limit) {
+ // If any non-reserved CS register isn't spilled, just spill one or two
+ // extra. That should take care of it!
+ unsigned NumExtras = TargetAlign / 4;
+ SmallVector<unsigned, 2> Extras;
+ while (NumExtras && !UnspilledCS1GPRs.empty()) {
+ unsigned Reg = UnspilledCS1GPRs.back();
+ UnspilledCS1GPRs.pop_back();
+ if (!isReservedReg(MF, Reg)) {
+ Extras.push_back(Reg);
+ NumExtras--;
+ }
+ }
+ while (NumExtras && !UnspilledCS2GPRs.empty()) {
+ unsigned Reg = UnspilledCS2GPRs.back();
+ UnspilledCS2GPRs.pop_back();
+ if (!isReservedReg(MF, Reg)) {
+ Extras.push_back(Reg);
+ NumExtras--;
+ }
+ }
+ if (Extras.size() && NumExtras == 0) {
+ for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
+ MF.changePhyRegUsed(Extras[i], true);
+ AFI->setCSRegisterIsSpilled(Extras[i]);
+ }
+ } else {
+ // Reserve a slot closest to SP or frame pointer.
+ const TargetRegisterClass *RC = &ARM::GPRRegClass;
+ RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
+ RC->getAlignment()));
+ }
}
}
}
Index: llvm/lib/Target/ARM/ARMRegisterInfo.h
diff -u llvm/lib/Target/ARM/ARMRegisterInfo.h:1.15 llvm/lib/Target/ARM/ARMRegisterInfo.h:1.16
--- llvm/lib/Target/ARM/ARMRegisterInfo.h:1.15 Tue Feb 27 18:59:19 2007
+++ llvm/lib/Target/ARM/ARMRegisterInfo.h Tue Mar 6 04:03:56 2007
@@ -27,17 +27,12 @@
const TargetInstrInfo &TII;
const ARMSubtarget &STI;
private:
- /// RS - An instance of the register scavenger.
- RegScavenger *RS;
-
/// FramePtr - ARM physical register used as frame ptr.
unsigned FramePtr;
public:
ARMRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
- ~ARMRegisterInfo();
-
/// getRegisterNumbering - Given the enum value for some register, e.g.
/// ARM::LR, return the number that it corresponds to (e.g. 14).
static unsigned getRegisterNumbering(unsigned RegEnum);
@@ -74,6 +69,8 @@
BitVector getReservedRegs(const MachineFunction &MF) const;
+ bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
+
bool requiresRegisterScavenging(const MachineFunction &MF) const;
bool hasFP(const MachineFunction &MF) const;
@@ -85,7 +82,8 @@
void eliminateFrameIndex(MachineBasicBlock::iterator II,
RegScavenger *RS = NULL) const;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const;
+ void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ RegScavenger *RS = NULL) const;
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
More information about the llvm-commits
mailing list