Implement -disable-non-leaf-fp-elim which disable frame pointer elimination

optimization for non-leaf functions. This will be hooked up to gcc's
-momit-leaf-frame-pointer option. rdar://7886181

llvm-svn: 101984
This commit is contained in:
Evan Cheng 2010-04-21 03:18:23 +00:00
parent f29231ece0
commit 4158a0ff6b
15 changed files with 90 additions and 13 deletions

View File

@ -16,6 +16,8 @@
#define LLVM_TARGET_TARGETOPTIONS_H #define LLVM_TARGET_TARGETOPTIONS_H
namespace llvm { namespace llvm {
class MachineFunction;
// Possible float ABI settings. Used with FloatABIType in TargetOptions.h. // Possible float ABI settings. Used with FloatABIType in TargetOptions.h.
namespace FloatABI { namespace FloatABI {
enum ABIType { enum ABIType {
@ -35,6 +37,16 @@ namespace llvm {
/// elimination optimization, this option should disable it. /// elimination optimization, this option should disable it.
extern bool NoFramePointerElim; extern bool NoFramePointerElim;
/// NoFramePointerElimNonLeaf - This flag is enabled when the
/// -disable-non-leaf-fp-elim is specified on the command line. If the target
/// supports the frame pointer elimination optimization, this option should
/// disable it for non-leaf functions.
extern bool NoFramePointerElimNonLeaf;
/// DisableFramePointerElim - This returns true if frame pointer elimination
/// optimization should be disabled for the given machine function.
extern bool DisableFramePointerElim(const MachineFunction &MF);
/// LessPreciseFPMAD - This flag is enabled when the /// LessPreciseFPMAD - This flag is enabled when the
/// -enable-fp-mad is specified on the command line. When this flag is off /// -enable-fp-mad is specified on the command line. When this flag is off
/// (the default), the code generator is not allowed to generate mad /// (the default), the code generator is not allowed to generate mad

View File

@ -1251,7 +1251,7 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
// DW_TAG_inlined_subroutine may refer to this DIE. // DW_TAG_inlined_subroutine may refer to this DIE.
ModuleCU->insertDIE(SP.getNode(), SPDie); ModuleCU->insertDIE(SP.getNode(), SPDie);
if (NoFramePointerElim == false) if (!DisableFramePointerElim(*Asm->MF))
addUInt(SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr, dwarf::DW_FORM_flag, 1); addUInt(SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr, dwarf::DW_FORM_flag, 1);
return SPDie; return SPDie;

View File

@ -481,7 +481,7 @@ ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
/// ///
bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const { bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
return ((NoFramePointerElim && MFI->hasCalls())|| return ((DisableFramePointerElim(MF) && MFI->hasCalls())||
needsStackRealignment(MF) || needsStackRealignment(MF) ||
MFI->hasVarSizedObjects() || MFI->hasVarSizedObjects() ||
MFI->isFrameAddressTaken()); MFI->isFrameAddressTaken());
@ -509,7 +509,7 @@ needsStackRealignment(const MachineFunction &MF) const {
bool ARMBaseRegisterInfo:: bool ARMBaseRegisterInfo::
cannotEliminateFrame(const MachineFunction &MF) const { cannotEliminateFrame(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
if (NoFramePointerElim && MFI->hasCalls()) if (DisableFramePointerElim(MF) && MFI->hasCalls())
return true; return true;
return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken() return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken()
|| needsStackRealignment(MF); || needsStackRealignment(MF);

View File

@ -110,7 +110,8 @@ BlackfinRegisterInfo::getPhysicalRegisterRegClass(unsigned reg, EVT VT) const {
// if frame pointer elimination is disabled. // if frame pointer elimination is disabled.
bool BlackfinRegisterInfo::hasFP(const MachineFunction &MF) const { bool BlackfinRegisterInfo::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
return NoFramePointerElim || MFI->hasCalls() || MFI->hasVarSizedObjects(); return DisableFramePointerElim(MF) ||
MFI->hasCalls() || MFI->hasVarSizedObjects();
} }
bool BlackfinRegisterInfo:: bool BlackfinRegisterInfo::

View File

@ -303,7 +303,7 @@ BitVector SPURegisterInfo::getReservedRegs(const MachineFunction &MF) const {
// //
static bool needsFP(const MachineFunction &MF) { static bool needsFP(const MachineFunction &MF) {
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
return NoFramePointerElim || MFI->hasVarSizedObjects(); return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------

View File

@ -243,7 +243,7 @@ void MBlazeRegisterInfo::adjustMBlazeStackFrame(MachineFunction &MF) const {
// if frame pointer elimination is disabled. // if frame pointer elimination is disabled.
bool MBlazeRegisterInfo::hasFP(const MachineFunction &MF) const { bool MBlazeRegisterInfo::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
return NoFramePointerElim || MFI->hasVarSizedObjects(); return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
} }
// This function eliminate ADJCALLSTACKDOWN, // This function eliminate ADJCALLSTACKDOWN,

View File

@ -138,7 +138,7 @@ MSP430RegisterInfo::getPointerRegClass(unsigned Kind) const {
bool MSP430RegisterInfo::hasFP(const MachineFunction &MF) const { bool MSP430RegisterInfo::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
return (NoFramePointerElim || return (DisableFramePointerElim(MF) ||
MF.getFrameInfo()->hasVarSizedObjects() || MF.getFrameInfo()->hasVarSizedObjects() ||
MFI->isFrameAddressTaken()); MFI->isFrameAddressTaken());
} }

View File

@ -338,7 +338,7 @@ void MipsRegisterInfo::adjustMipsStackFrame(MachineFunction &MF) const
bool MipsRegisterInfo:: bool MipsRegisterInfo::
hasFP(const MachineFunction &MF) const { hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
return NoFramePointerElim || MFI->hasVarSizedObjects(); return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
} }
// This function eliminate ADJCALLSTACKDOWN, // This function eliminate ADJCALLSTACKDOWN,

View File

@ -5531,7 +5531,7 @@ SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op,
MachineFunction &MF = DAG.getMachineFunction(); MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo(); MachineFrameInfo *MFI = MF.getFrameInfo();
bool is31 = (NoFramePointerElim || MFI->hasVarSizedObjects()) bool is31 = (DisableFramePointerElim(MF) || MFI->hasVarSizedObjects())
&& MFI->getStackSize(); && MFI->getStackSize();
if (isPPC64) if (isPPC64)

View File

@ -409,7 +409,7 @@ PPCRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
// //
static bool needsFP(const MachineFunction &MF) { static bool needsFP(const MachineFunction &MF) {
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
return NoFramePointerElim || MFI->hasVarSizedObjects() || return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects() ||
(GuaranteedTailCallOpt && MF.getInfo<PPCFunctionInfo>()->hasFastCall()); (GuaranteedTailCallOpt && MF.getInfo<PPCFunctionInfo>()->hasFastCall());
} }

View File

@ -77,7 +77,7 @@ BitVector SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const
/// allocas or if frame pointer elimination is disabled. /// allocas or if frame pointer elimination is disabled.
bool SystemZRegisterInfo::hasFP(const MachineFunction &MF) const { bool SystemZRegisterInfo::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
return NoFramePointerElim || MFI->hasVarSizedObjects(); return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
} }
void SystemZRegisterInfo:: void SystemZRegisterInfo::

View File

@ -11,6 +11,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetOptions.h"
@ -25,6 +27,7 @@ namespace llvm {
bool LessPreciseFPMADOption; bool LessPreciseFPMADOption;
bool PrintMachineCode; bool PrintMachineCode;
bool NoFramePointerElim; bool NoFramePointerElim;
bool NoFramePointerElimNonLeaf;
bool NoExcessFPPrecision; bool NoExcessFPPrecision;
bool UnsafeFPMath; bool UnsafeFPMath;
bool FiniteOnlyFPMathOption; bool FiniteOnlyFPMathOption;
@ -58,6 +61,11 @@ DisableFPElim("disable-fp-elim",
cl::location(NoFramePointerElim), cl::location(NoFramePointerElim),
cl::init(false)); cl::init(false));
static cl::opt<bool, true> static cl::opt<bool, true>
DisableFPElimNonLeaf("disable-non-leaf-fp-elim",
cl::desc("Disable frame pointer elimination optimization for non-leaf funcs"),
cl::location(NoFramePointerElimNonLeaf),
cl::init(false));
static cl::opt<bool, true>
DisableExcessPrecision("disable-excess-fp-precision", DisableExcessPrecision("disable-excess-fp-precision",
cl::desc("Disable optimizations that may increase FP precision"), cl::desc("Disable optimizations that may increase FP precision"),
cl::location(NoExcessFPPrecision), cl::location(NoExcessFPPrecision),
@ -268,6 +276,18 @@ void TargetMachine::setDataSections(bool V) {
} }
namespace llvm { namespace llvm {
/// DisableFramePointerElim - This returns true if frame pointer elimination
/// optimization should be disabled for the given machine function.
bool DisableFramePointerElim(const MachineFunction &MF) {
if (NoFramePointerElim)
return true;
if (NoFramePointerElimNonLeaf) {
const MachineFrameInfo *MFI = MF.getFrameInfo();
return MFI->hasCalls();
}
return false;
}
/// LessPreciseFPMAD - This flag return true when -enable-fp-mad option /// LessPreciseFPMAD - This flag return true when -enable-fp-mad option
/// is specified on the command line. When this flag is off(default), the /// is specified on the command line. When this flag is off(default), the
/// code generator is not allowed to generate mad (multiply add) if the /// code generator is not allowed to generate mad (multiply add) if the

View File

@ -439,7 +439,7 @@ bool X86RegisterInfo::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
const MachineModuleInfo &MMI = MF.getMMI(); const MachineModuleInfo &MMI = MF.getMMI();
return (NoFramePointerElim || return (DisableFramePointerElim(MF) ||
needsStackRealignment(MF) || needsStackRealignment(MF) ||
MFI->hasVarSizedObjects() || MFI->hasVarSizedObjects() ||
MFI->isFrameAddressTaken() || MFI->isFrameAddressTaken() ||

View File

@ -113,7 +113,7 @@ XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
} }
bool XCoreRegisterInfo::hasFP(const MachineFunction &MF) const { bool XCoreRegisterInfo::hasFP(const MachineFunction &MF) const {
return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects(); return DisableFramePointerElim(MF) || MF.getFrameInfo()->hasVarSizedObjects();
} }
// This function eliminates ADJCALLSTACKDOWN, // This function eliminates ADJCALLSTACKDOWN,

View File

@ -0,0 +1,44 @@
; RUN: llc < %s -march=x86 -asm-verbose=false | FileCheck %s -check-prefix=FP-ELIM
; RUN: llc < %s -march=x86 -asm-verbose=false -disable-fp-elim | FileCheck %s -check-prefix=NO-ELIM
; RUN: llc < %s -march=x86 -asm-verbose=false -disable-non-leaf-fp-elim | FileCheck %s -check-prefix=NON-LEAF
; Implement -momit-leaf-frame-pointer
; rdar://7886181
define i32 @t1() nounwind readnone {
entry:
; FP-ELIM: t1:
; FP-ELIM-NEXT: movl
; FP-ELIM-NEXT: ret
; NO-ELIM: t1:
; NO-ELIM-NEXT: pushl %ebp
; NO-ELIM: popl %ebp
; NO-ELIM-NEXT: ret
; NON-LEAF: t1:
; NON-LEAF-NEXT: movl
; NON-LEAF-NEXT: ret
ret i32 10
}
define void @t2() nounwind {
entry:
; FP-ELIM: t2:
; FP-ELIM-NOT: pushl %ebp
; FP-ELIM: ret
; NO-ELIM: t2:
; NO-ELIM-NEXT: pushl %ebp
; NO-ELIM: popl %ebp
; NO-ELIM-NEXT: ret
; NON-LEAF: t2:
; NON-LEAF-NEXT: pushl %ebp
; NON-LEAF: popl %ebp
; NON-LEAF-NEXT: ret
tail call void @foo(i32 0) nounwind
ret void
}
declare void @foo(i32)