Skip to content

Commit

Permalink
Move hasFP() and few related hooks to TargetFrameInfo.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119740 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
asl committed Nov 18, 2010
1 parent b9064bb commit d0c3817
Show file tree
Hide file tree
Showing 68 changed files with 492 additions and 461 deletions.
26 changes: 26 additions & 0 deletions include/llvm/Target/TargetFrameInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,32 @@ class TargetFrameInfo {
virtual void emitPrologue(MachineFunction &MF) const = 0;
virtual void emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const = 0;

/// hasFP - Return true if the specified function should have a dedicated
/// frame pointer register. For most targets this is true only if the function
/// has variable sized allocas or if frame pointer elimination is disabled.
virtual bool hasFP(const MachineFunction &MF) const = 0;

/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
/// not required, we reserve argument space for call sites in the function
/// immediately on entry to the current function. This eliminates the need for
/// add/sub sp brackets around call sites. Returns true if the call frame is
/// included as part of the stack frame.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const {
return !hasFP(MF);
}

/// canSimplifyCallFramePseudos - When possible, it's best to simplify the
/// call frame pseudo ops before doing frame index elimination. This is
/// possible only when frame index references between the pseudos won't
/// need adjusting for the call frame adjustments. Normally, that's true
/// if the function has a reserved call frame or a frame pointer. Some
/// targets (Thumb2, for example) may have more complicated criteria,
/// however, and can override this behavior.
virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const {
return hasReservedCallFrame(MF) || hasFP(MF);
}

};

} // End llvm namespace
Expand Down
25 changes: 0 additions & 25 deletions include/llvm/Target/TargetRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,31 +596,6 @@ class TargetRegisterInfo {
return false;
}

/// hasFP - Return true if the specified function should have a dedicated
/// frame pointer register. For most targets this is true only if the function
/// has variable sized allocas or if frame pointer elimination is disabled.
virtual bool hasFP(const MachineFunction &MF) const = 0;

/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
/// not required, we reserve argument space for call sites in the function
/// immediately on entry to the current function. This eliminates the need for
/// add/sub sp brackets around call sites. Returns true if the call frame is
/// included as part of the stack frame.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const {
return !hasFP(MF);
}

/// canSimplifyCallFramePseudos - When possible, it's best to simplify the
/// call frame pseudo ops before doing frame index elimination. This is
/// possible only when frame index references between the pseudos won't
/// need adjusting for the call frame adjustments. Normally, that's true
/// if the function has a reserved call frame or a frame pointer. Some
/// targets (Thumb2, for example) may have more complicated criteria,
/// however, and can override this behavior.
virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const {
return hasReservedCallFrame(MF) || hasFP(MF);
}

/// hasReservedSpillSlot - Return true if target has reserved a spill slot in
/// the stack frame of the given function for the specified register. e.g. On
/// x86, if the frame register is required, the first fixed stack object is
Expand Down
9 changes: 5 additions & 4 deletions lib/CodeGen/PrologEpilogInserter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ void PEI::getAnalysisUsage(AnalysisUsage &AU) const {
/// pseudo instructions.
void PEI::calculateCallsInformation(MachineFunction &Fn) {
const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo();
MachineFrameInfo *MFI = Fn.getFrameInfo();

unsigned MaxCallFrameSize = 0;
Expand Down Expand Up @@ -184,7 +185,7 @@ void PEI::calculateCallsInformation(MachineFunction &Fn) {
// the target doesn't indicate otherwise, remove the call frame pseudos
// here. The sub/add sp instruction pairs are still inserted, but we don't
// need to track the SP adjustment for frame index elimination.
if (RegInfo->canSimplifyCallFramePseudos(Fn))
if (TFI->canSimplifyCallFramePseudos(Fn))
RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
}
}
Expand Down Expand Up @@ -553,7 +554,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
// Make sure the special register scavenging spill slot is closest to the
// frame pointer if a frame pointer is required.
const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
if (RS && RegInfo->hasFP(Fn) && !RegInfo->needsStackRealignment(Fn)) {
if (RS && TFI.hasFP(Fn) && !RegInfo->needsStackRealignment(Fn)) {
int SFI = RS->getScavengingFrameIndex();
if (SFI >= 0)
AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign);
Expand Down Expand Up @@ -635,7 +636,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {

// Make sure the special register scavenging spill slot is closest to the
// stack pointer.
if (RS && (!RegInfo->hasFP(Fn) || RegInfo->needsStackRealignment(Fn))) {
if (RS && (!TFI.hasFP(Fn) || RegInfo->needsStackRealignment(Fn))) {
int SFI = RS->getScavengingFrameIndex();
if (SFI >= 0)
AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign);
Expand All @@ -645,7 +646,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
// If we have reserved argument space for call sites in the function
// immediately on entry to the current function, count it as part of the
// overall stack size.
if (MFI->adjustsStack() && RegInfo->hasReservedCallFrame(Fn))
if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn))
Offset += MFI->getMaxCallFrameSize();

// Round up the size to a multiple of the alignment. If the function has
Expand Down
83 changes: 25 additions & 58 deletions lib/Target/ARM/ARMBaseRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,14 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {

BitVector ARMBaseRegisterInfo::
getReservedRegs(const MachineFunction &MF) const {
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();

// FIXME: avoid re-calculating this everytime.
BitVector Reserved(getNumRegs());
Reserved.set(ARM::SP);
Reserved.set(ARM::PC);
Reserved.set(ARM::FPSCR);
if (hasFP(MF))
if (TFI->hasFP(MF))
Reserved.set(FramePtr);
if (hasBasePointer(MF))
Reserved.set(BasePtr);
Expand All @@ -102,6 +104,8 @@ getReservedRegs(const MachineFunction &MF) const {

bool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
unsigned Reg) const {
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();

switch (Reg) {
default: break;
case ARM::SP:
Expand All @@ -113,7 +117,7 @@ bool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
break;
case ARM::R7:
case ARM::R11:
if (FramePtr == Reg && hasFP(MF))
if (FramePtr == Reg && TFI->hasFP(MF))
return true;
break;
case ARM::R9:
Expand Down Expand Up @@ -349,6 +353,7 @@ std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
ARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
unsigned HintType, unsigned HintReg,
const MachineFunction &MF) const {
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
// Alternative register allocation orders when favoring even / odd registers
// of register pairs.

Expand Down Expand Up @@ -430,7 +435,7 @@ ARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
return std::make_pair(RC->allocation_order_begin(MF),
RC->allocation_order_end(MF));

if (!hasFP(MF)) {
if (!TFI->hasFP(MF)) {
if (!STI.isR9Reserved())
return std::make_pair(GPREven1,
GPREven1 + (sizeof(GPREven1)/sizeof(unsigned)));
Expand Down Expand Up @@ -459,7 +464,7 @@ ARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
return std::make_pair(RC->allocation_order_begin(MF),
RC->allocation_order_end(MF));

if (!hasFP(MF)) {
if (!TFI->hasFP(MF)) {
if (!STI.isR9Reserved())
return std::make_pair(GPROdd1,
GPROdd1 + (sizeof(GPROdd1)/sizeof(unsigned)));
Expand Down Expand Up @@ -524,23 +529,6 @@ ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
}
}

/// hasFP - Return true if the specified function should have a dedicated frame
/// pointer register. This is true if the function has variable sized allocas
/// or if frame pointer elimination is disabled.
///
bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
// Mac OS X requires FP not to be clobbered for backtracing purpose.
if (STI.isTargetDarwin())
return true;

const MachineFrameInfo *MFI = MF.getFrameInfo();
// Always eliminate non-leaf frame pointers.
return ((DisableFramePointerElim(MF) && MFI->hasCalls()) ||
needsStackRealignment(MF) ||
MFI->hasVarSizedObjects() ||
MFI->isFrameAddressTaken());
}

bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
Expand Down Expand Up @@ -626,6 +614,7 @@ static unsigned estimateStackSize(MachineFunction &MF) {
/// instructions will require a scratch register during their expansion later.
unsigned
ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned Limit = (1 << 12) - 1;
for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
Expand Down Expand Up @@ -654,7 +643,7 @@ ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
case ARMII::AddrModeT2_i12:
// i12 supports only positive offset so these will be converted to
// i8 opcodes. See llvm::rewriteT2FrameIndex.
if (hasFP(MF) && AFI->hasStackFrame())
if (TFI->hasFP(MF) && AFI->hasStackFrame())
Limit = std::min(Limit, (1U << 8) - 1);
break;
case ARMII::AddrMode4:
Expand Down Expand Up @@ -699,6 +688,7 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
unsigned NumGPRSpills = 0;
SmallVector<unsigned, 4> UnspilledCS1GPRs;
SmallVector<unsigned, 4> UnspilledCS2GPRs;
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
MachineFrameInfo *MFI = MF.getFrameInfo();

Expand Down Expand Up @@ -813,10 +803,10 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
// worth the effort and added fragility?
bool BigStack =
(RS &&
(estimateStackSize(MF) + ((hasFP(MF) && AFI->hasStackFrame()) ? 4:0) >=
(estimateStackSize(MF) + ((TFI->hasFP(MF) && AFI->hasStackFrame()) ? 4:0) >=
estimateRSStackSizeLimit(MF)))
|| MFI->hasVarSizedObjects()
|| (MFI->adjustsStack() && !canSimplifyCallFramePseudos(MF));
|| (MFI->adjustsStack() && !TFI->canSimplifyCallFramePseudos(MF));

bool ExtraCSSpill = false;
if (BigStack || !CanEliminateFrame || cannotEliminateFrame(MF)) {
Expand All @@ -834,7 +824,7 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
ExtraCSSpill = true;
}

if (hasFP(MF)) {
if (TFI->hasFP(MF)) {
MF.getRegInfo().setPhysRegUsed(FramePtr);
NumGPRSpills++;
}
Expand Down Expand Up @@ -927,7 +917,9 @@ unsigned ARMBaseRegisterInfo::getRARegister() const {

unsigned
ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
if (hasFP(MF))
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();

if (TFI->hasFP(MF))
return FramePtr;
return ARM::SP;
}
Expand All @@ -948,6 +940,7 @@ ARMBaseRegisterInfo::ResolveFrameIndexReference(const MachineFunction &MF,
unsigned &FrameReg,
int SPAdj) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
int Offset = MFI->getObjectOffset(FI) + MFI->getStackSize();
int FPOffset = Offset - AFI->getFramePtrSpillOffset();
Expand All @@ -965,7 +958,7 @@ ARMBaseRegisterInfo::ResolveFrameIndexReference(const MachineFunction &MF,
// When dynamically realigning the stack, use the frame pointer for
// parameters, and the stack/base pointer for locals.
if (needsStackRealignment(MF)) {
assert (hasFP(MF) && "dynamic stack realignment without a FP!");
assert (TFI->hasFP(MF) && "dynamic stack realignment without a FP!");
if (isFixed) {
FrameReg = getFrameRegister(MF);
Offset = FPOffset;
Expand All @@ -978,7 +971,7 @@ ARMBaseRegisterInfo::ResolveFrameIndexReference(const MachineFunction &MF,
}

// If there is a frame pointer, use it when we can.
if (hasFP(MF) && AFI->hasStackFrame()) {
if (TFI->hasFP(MF) && AFI->hasStackFrame()) {
// Use frame pointer to reference fixed objects. Use it for locals if
// there are VLAs (and thus the SP isn't reliable as a base).
if (isFixed || (MFI->hasVarSizedObjects() && !hasBasePointer(MF))) {
Expand Down Expand Up @@ -1252,34 +1245,6 @@ requiresVirtualBaseRegisters(const MachineFunction &MF) const {
return EnableLocalStackAlloc;
}

// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
// not required, we reserve argument space for call sites in the function
// immediately on entry to the current function. This eliminates the need for
// add/sub sp brackets around call sites. Returns true if the call frame is
// included as part of the stack frame.
bool ARMBaseRegisterInfo::
hasReservedCallFrame(const MachineFunction &MF) const {
const MachineFrameInfo *FFI = MF.getFrameInfo();
unsigned CFSize = FFI->getMaxCallFrameSize();
// It's not always a good idea to include the call frame as part of the
// stack frame. ARM (especially Thumb) has small immediate offset to
// address the stack frame. So a large call frame can cause poor codegen
// and may even makes it impossible to scavenge a register.
if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
return false;

return !MF.getFrameInfo()->hasVarSizedObjects();
}

// canSimplifyCallFramePseudos - If there is a reserved call frame, the
// call frame pseudos can be simplified. Unlike most targets, having a FP
// is not sufficient here since we still may reference some objects via SP
// even when FP is available in Thumb2 mode.
bool ARMBaseRegisterInfo::
canSimplifyCallFramePseudos(const MachineFunction &MF) const {
return hasReservedCallFrame(MF) || MF.getFrameInfo()->hasVarSizedObjects();
}

static void
emitSPUpdate(bool isARM,
MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
Expand All @@ -1298,7 +1263,8 @@ emitSPUpdate(bool isARM,
void ARMBaseRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
if (!hasReservedCallFrame(MF)) {
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
if (!TFI->hasReservedCallFrame(MF)) {
// If we have alloca, convert as follows:
// ADJCALLSTACKDOWN -> sub, sp, sp, amount
// ADJCALLSTACKUP -> add, sp, sp, amount
Expand Down Expand Up @@ -1429,6 +1395,7 @@ needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
// Note that the incoming offset is based on the SP value at function entry,
// so it'll be negative.
MachineFunction &MF = *MI->getParent()->getParent();
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
MachineFrameInfo *MFI = MF.getFrameInfo();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();

Expand Down Expand Up @@ -1456,7 +1423,7 @@ needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
// don't know for sure yet whether we'll need that, so we guess based
// on whether there are any local variables that would trigger it.
unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
if (hasFP(MF) &&
if (TFI->hasFP(MF) &&
!((MFI->getLocalFrameMaxAlign() > StackAlign) && canRealignStack(MF))) {
if (isFrameOffsetLegal(MI, FPOffset))
return false;
Expand Down
4 changes: 0 additions & 4 deletions lib/Target/ARM/ARMBaseRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ class ARMBaseRegisterInfo : public ARMGenRegisterInfo {
void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
MachineFunction &MF) const;

bool hasFP(const MachineFunction &MF) const;
bool hasBasePointer(const MachineFunction &MF) const;

bool canRealignStack(const MachineFunction &MF) const;
Expand Down Expand Up @@ -196,9 +195,6 @@ class ARMBaseRegisterInfo : public ARMGenRegisterInfo {

virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const;

virtual bool hasReservedCallFrame(const MachineFunction &MF) const;
virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const;

virtual void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
Expand Down
4 changes: 3 additions & 1 deletion lib/Target/ARM/ARMExpandPseudoInsts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/raw_ostream.h" // FIXME: for debug only. remove!
using namespace llvm;
Expand Down Expand Up @@ -600,6 +601,7 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {

case ARM::Int_eh_sjlj_dispatchsetup: {
MachineFunction &MF = *MI.getParent()->getParent();
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
const ARMBaseInstrInfo *AII =
static_cast<const ARMBaseInstrInfo*>(TII);
const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
Expand All @@ -610,7 +612,7 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
int32_t NumBytes = AFI->getFramePtrSpillOffset();
unsigned FramePtr = RI.getFrameRegister(MF);
assert (RI.hasFP(MF) && "base pointer without frame pointer?");
assert (TFI->hasFP(MF) && "base pointer without frame pointer?");

if (AFI->isThumb2Function()) {
llvm::emitT2RegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
Expand Down
Loading

0 comments on commit d0c3817

Please sign in to comment.