Clean up ARM PEI code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33389 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2007-01-20 02:09:25 +00:00
parent 0327863a73
commit 75e18c403e
4 changed files with 74 additions and 90 deletions

View File

@ -32,11 +32,11 @@ class ARMFunctionInfo : public MachineFunctionInfo {
///
unsigned VarArgsRegSaveSize;
/// FramePtrSpilled - True if FP register is spilled. Set by
/// HasStackFrame - True if this function has a stack frame. Set by
/// processFunctionBeforeCalleeSavedScan().
bool FramePtrSpilled;
bool HasStackFrame;
/// FramePtrSpillOffset - If FramePtrSpilled, this records the frame pointer
/// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
/// spill stack offset.
unsigned FramePtrSpillOffset;
@ -71,13 +71,13 @@ class ARMFunctionInfo : public MachineFunctionInfo {
public:
ARMFunctionInfo() :
isThumb(false),
VarArgsRegSaveSize(0), FramePtrSpilled(false), FramePtrSpillOffset(0),
VarArgsRegSaveSize(0), HasStackFrame(false), FramePtrSpillOffset(0),
GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
ARMFunctionInfo(MachineFunction &MF) :
isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
VarArgsRegSaveSize(0), FramePtrSpilled(false), FramePtrSpillOffset(0),
VarArgsRegSaveSize(0), HasStackFrame(false), FramePtrSpillOffset(0),
GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
@ -86,8 +86,8 @@ public:
unsigned getVarArgsRegSaveSize() const { return VarArgsRegSaveSize; }
void setVarArgsRegSaveSize(unsigned s) { VarArgsRegSaveSize = s; }
bool isFramePtrSpilled() const { return FramePtrSpilled; }
void setFramePtrSpilled(bool s) { FramePtrSpilled = s; }
bool hasStackFrame() const { return HasStackFrame; }
void setHasStackFrame(bool s) { HasStackFrame = s; }
unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }

View File

@ -411,7 +411,7 @@ void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
void ARMRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
if (MF.getFrameInfo()->hasVarSizedObjects()) {
if (hasFP(MF)) {
// If we have alloca, convert as follows:
// ADJCALLSTACKDOWN -> sub, sp, sp, amount
// ADJCALLSTACKUP -> add, sp, sp, amount
@ -480,7 +480,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
Offset -= AFI->getGPRCalleeSavedArea2Offset();
else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex))
Offset -= AFI->getDPRCalleeSavedAreaOffset();
else if (MF.getFrameInfo()->hasVarSizedObjects()) {
else if (hasFP(MF)) {
// There is alloca()'s in this function, must reference off the frame
// pointer instead.
FrameReg = getFrameRegister(MF);
@ -689,76 +689,75 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
void ARMRegisterInfo::
processFunctionBeforeCalleeSavedScan(MachineFunction &MF) 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
// 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
// to combine multiple loads / stores.
bool FramePtrSpilled = MF.getFrameInfo()->hasVarSizedObjects();
bool CanEliminateFrame = true;
bool CS1Spilled = false;
bool LRSpilled = false;
unsigned NumGPRSpills = 0;
SmallVector<unsigned, 4> UnspilledCS1GPRs;
SmallVector<unsigned, 4> UnspilledCS2GPRs;
if (!FramePtrSpilled && NoFramePointerElim) {
// Don't spill FP if the frame can be eliminated. This is determined
// by scanning the callee-save registers to see if any is used.
const unsigned *CSRegs = getCalleeSavedRegs();
const TargetRegisterClass* const *CSRegClasses = getCalleeSavedRegClasses();
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
bool Spilled = false;
if (MF.isPhysRegUsed(Reg)) {
Spilled = true;
FramePtrSpilled = true;
} else {
// Check alias registers too.
for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) {
if (MF.isPhysRegUsed(*Aliases)) {
Spilled = true;
FramePtrSpilled = true;
}
// Don't spill FP if the frame can be eliminated. This is determined
// by scanning the callee-save registers to see if any is used.
const unsigned *CSRegs = getCalleeSavedRegs();
const TargetRegisterClass* const *CSRegClasses = getCalleeSavedRegClasses();
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
bool Spilled = false;
if (MF.isPhysRegUsed(Reg)) {
Spilled = true;
CanEliminateFrame = false;
} else {
// Check alias registers too.
for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) {
if (MF.isPhysRegUsed(*Aliases)) {
Spilled = true;
CanEliminateFrame = false;
}
}
}
if (CSRegClasses[i] == &ARM::GPRRegClass) {
if (Spilled) {
NumGPRSpills++;
if (CSRegClasses[i] == &ARM::GPRRegClass) {
if (Spilled) {
NumGPRSpills++;
// Keep track if LR and any of R4, R5, R6, and R7 is spilled.
switch (Reg) {
case ARM::LR:
LRSpilled = true;
// Fallthrough
case ARM::R4:
case ARM::R5:
case ARM::R6:
case ARM::R7:
CS1Spilled = true;
break;
default:
break;
}
} else {
switch (Reg) {
case ARM::R4:
case ARM::R5:
case ARM::R6:
case ARM::R7:
case ARM::LR:
UnspilledCS1GPRs.push_back(Reg);
break;
default:
UnspilledCS2GPRs.push_back(Reg);
break;
}
// Keep track if LR and any of R4, R5, R6, and R7 is spilled.
switch (Reg) {
case ARM::LR:
LRSpilled = true;
// Fallthrough
case ARM::R4:
case ARM::R5:
case ARM::R6:
case ARM::R7:
CS1Spilled = true;
break;
default:
break;
}
} else {
switch (Reg) {
case ARM::R4:
case ARM::R5:
case ARM::R6:
case ARM::R7:
case ARM::LR:
UnspilledCS1GPRs.push_back(Reg);
break;
default:
UnspilledCS2GPRs.push_back(Reg);
break;
}
}
}
}
if (FramePtrSpilled) {
if (!CanEliminateFrame) {
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
AFI->setFramePtrSpilled(true);
AFI->setHasStackFrame(true);
// If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
// Spill LR as well so we can fold BX_RET to the registers restore (LDM).
@ -796,27 +795,15 @@ static void movePastCSLoadStoreOps(MachineBasicBlock &MBB,
bool Done = false;
unsigned Category = 0;
switch (MBBI->getOperand(0).getReg()) {
case ARM::R4:
case ARM::R5:
case ARM::R6:
case ARM::R7:
case ARM::R4: case ARM::R5: case ARM::R6: case ARM::R7:
case ARM::LR:
Category = 1;
break;
case ARM::R8:
case ARM::R9:
case ARM::R10:
case ARM::R11:
case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
Category = STI.isTargetDarwin() ? 2 : 1;
break;
case ARM::D8:
case ARM::D9:
case ARM::D10:
case ARM::D11:
case ARM::D12:
case ARM::D13:
case ARM::D14:
case ARM::D15:
case ARM::D8: case ARM::D9: case ARM::D10: case ARM::D11:
case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15:
Category = 3;
break;
default:
@ -846,7 +833,7 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
// belongs to which callee-save spill areas.
unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
int FramePtrSpillFI = 0;
if (AFI->isFramePtrSpilled()) {
if (AFI->hasStackFrame()) {
if (VARegSaveSize)
emitSPUpdate(MBB, MBBI, -VARegSaveSize, isThumb, TII);
@ -909,19 +896,18 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
// If necessary, add one more SUBri to account for the call frame
// and/or local storage, alloca area.
if (MFI->hasCalls())
if (MFI->hasCalls() && !hasFP(MF))
// We reserve argument space for call sites in the function immediately on
// entry to the current function. This eliminates the need for add/sub
// brackets around call sites.
if (!MF.getFrameInfo()->hasVarSizedObjects())
NumBytes += MFI->getMaxCallFrameSize();
NumBytes += MFI->getMaxCallFrameSize();
// Round the size to a multiple of the alignment.
NumBytes = (NumBytes+Align-1)/Align*Align;
MFI->setStackSize(NumBytes);
// Determine starting offsets of spill areas.
if (AFI->isFramePtrSpilled()) {
if (AFI->hasStackFrame()) {
unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
@ -973,7 +959,7 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
bool isThumb = AFI->isThumbFunction();
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
int NumBytes = (int)MFI->getStackSize();
if (AFI->isFramePtrSpilled()) {
if (AFI->hasStackFrame()) {
// Unwind MBBI to point to first LDR / FLDD.
const unsigned *CSRegs = getCalleeSavedRegs();
if (MBBI != MBB.begin()) {

View File

@ -166,7 +166,8 @@ def GPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
I = ARM_GPR_AO_1 + (sizeof(ARM_GPR_AO_1)/sizeof(unsigned));
}
return hasFP(MF) ? I-1 : I;
// Mac OS X requires FP not to be clobbered for backtracing purpose.
return (Subtarget.isTargetDarwin() || hasFP(MF)) ? I-1 : I;
}
}];
}

View File

@ -34,10 +34,7 @@ namespace {
///
ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS)
: Subtarget(M, FS), DataLayout("e-p:32:32-d:32"), InstrInfo(Subtarget),
FrameInfo(Subtarget) {
if (Subtarget.isTargetDarwin())
NoFramePointerElim = true;
}
FrameInfo(Subtarget) {}
unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) {
std::string TT = M.getTargetTriple();