forked from OSchip/llvm-project
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:
parent
f29231ece0
commit
4158a0ff6b
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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::
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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::
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() ||
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue