From dbfb7dc4380d2491fdcfb5e1b3b65fb79d49e209 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 21 Apr 2010 03:18:23 +0000 Subject: [PATCH] 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 --- include/llvm/Target/TargetOptions.h | 12 ++++++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 2 +- lib/Target/ARM/ARMBaseRegisterInfo.cpp | 4 +- lib/Target/Blackfin/BlackfinRegisterInfo.cpp | 3 +- lib/Target/CellSPU/SPURegisterInfo.cpp | 2 +- lib/Target/MBlaze/MBlazeRegisterInfo.cpp | 2 +- lib/Target/MSP430/MSP430RegisterInfo.cpp | 2 +- lib/Target/Mips/MipsRegisterInfo.cpp | 2 +- lib/Target/PowerPC/PPCISelLowering.cpp | 2 +- lib/Target/PowerPC/PPCRegisterInfo.cpp | 2 +- lib/Target/SystemZ/SystemZRegisterInfo.cpp | 2 +- lib/Target/TargetMachine.cpp | 20 +++++++++ lib/Target/X86/X86RegisterInfo.cpp | 2 +- lib/Target/XCore/XCoreRegisterInfo.cpp | 2 +- test/CodeGen/X86/fp-elim.ll | 44 ++++++++++++++++++++ 15 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 test/CodeGen/X86/fp-elim.ll diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index a01a67f14da..fb5698f1afb 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -16,6 +16,8 @@ #define LLVM_TARGET_TARGETOPTIONS_H namespace llvm { + class MachineFunction; + // Possible float ABI settings. Used with FloatABIType in TargetOptions.h. namespace FloatABI { enum ABIType { @@ -35,6 +37,16 @@ namespace llvm { /// elimination optimization, this option should disable it. 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 /// -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 diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 684a409c9ff..c31aec17590 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1251,7 +1251,7 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) { // DW_TAG_inlined_subroutine may refer to this DIE. 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); return SPDie; diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 46c50f990b7..2a4e1a853ab 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -481,7 +481,7 @@ ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg, /// bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); - return ((NoFramePointerElim && MFI->hasCalls())|| + return ((DisableFramePointerElim(MF) && MFI->hasCalls())|| needsStackRealignment(MF) || MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken()); @@ -509,7 +509,7 @@ needsStackRealignment(const MachineFunction &MF) const { bool ARMBaseRegisterInfo:: cannotEliminateFrame(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); - if (NoFramePointerElim && MFI->hasCalls()) + if (DisableFramePointerElim(MF) && MFI->hasCalls()) return true; return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken() || needsStackRealignment(MF); diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.cpp b/lib/Target/Blackfin/BlackfinRegisterInfo.cpp index 6fd610fa3b5..2512c9b7fb1 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.cpp +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.cpp @@ -110,7 +110,8 @@ BlackfinRegisterInfo::getPhysicalRegisterRegClass(unsigned reg, EVT VT) const { // if frame pointer elimination is disabled. bool BlackfinRegisterInfo::hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasCalls() || MFI->hasVarSizedObjects(); + return DisableFramePointerElim(MF) || + MFI->hasCalls() || MFI->hasVarSizedObjects(); } bool BlackfinRegisterInfo:: diff --git a/lib/Target/CellSPU/SPURegisterInfo.cpp b/lib/Target/CellSPU/SPURegisterInfo.cpp index 9a9c9f74362..fdbe10f84a7 100644 --- a/lib/Target/CellSPU/SPURegisterInfo.cpp +++ b/lib/Target/CellSPU/SPURegisterInfo.cpp @@ -303,7 +303,7 @@ BitVector SPURegisterInfo::getReservedRegs(const MachineFunction &MF) const { // static bool needsFP(const MachineFunction &MF) { const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasVarSizedObjects(); + return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects(); } //-------------------------------------------------------------------------- diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp index a12310a2bd3..e15176eb06b 100644 --- a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp +++ b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp @@ -243,7 +243,7 @@ void MBlazeRegisterInfo::adjustMBlazeStackFrame(MachineFunction &MF) const { // if frame pointer elimination is disabled. bool MBlazeRegisterInfo::hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasVarSizedObjects(); + return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects(); } // This function eliminate ADJCALLSTACKDOWN, diff --git a/lib/Target/MSP430/MSP430RegisterInfo.cpp b/lib/Target/MSP430/MSP430RegisterInfo.cpp index d91783a80c8..0cae26714bf 100644 --- a/lib/Target/MSP430/MSP430RegisterInfo.cpp +++ b/lib/Target/MSP430/MSP430RegisterInfo.cpp @@ -138,7 +138,7 @@ MSP430RegisterInfo::getPointerRegClass(unsigned Kind) const { bool MSP430RegisterInfo::hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); - return (NoFramePointerElim || + return (DisableFramePointerElim(MF) || MF.getFrameInfo()->hasVarSizedObjects() || MFI->isFrameAddressTaken()); } diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index f43e69b3545..478da84cad0 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -338,7 +338,7 @@ void MipsRegisterInfo::adjustMipsStackFrame(MachineFunction &MF) const bool MipsRegisterInfo:: hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasVarSizedObjects(); + return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects(); } // This function eliminate ADJCALLSTACKDOWN, diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 894436c558c..b825d647ee5 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -5531,7 +5531,7 @@ SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op, MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - bool is31 = (NoFramePointerElim || MFI->hasVarSizedObjects()) + bool is31 = (DisableFramePointerElim(MF) || MFI->hasVarSizedObjects()) && MFI->getStackSize(); if (isPPC64) diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 889acde2236..8048df21b7d 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -409,7 +409,7 @@ PPCRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { // static bool needsFP(const MachineFunction &MF) { const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasVarSizedObjects() || + return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects() || (GuaranteedTailCallOpt && MF.getInfo()->hasFastCall()); } diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/lib/Target/SystemZ/SystemZRegisterInfo.cpp index 5e325c08c36..638fd17c995 100644 --- a/lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ b/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -77,7 +77,7 @@ BitVector SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const /// allocas or if frame pointer elimination is disabled. bool SystemZRegisterInfo::hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasVarSizedObjects(); + return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects(); } void SystemZRegisterInfo:: diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp index 871b148adb3..d90755a3b33 100644 --- a/lib/Target/TargetMachine.cpp +++ b/lib/Target/TargetMachine.cpp @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -25,6 +27,7 @@ namespace llvm { bool LessPreciseFPMADOption; bool PrintMachineCode; bool NoFramePointerElim; + bool NoFramePointerElimNonLeaf; bool NoExcessFPPrecision; bool UnsafeFPMath; bool FiniteOnlyFPMathOption; @@ -58,6 +61,11 @@ DisableFPElim("disable-fp-elim", cl::location(NoFramePointerElim), cl::init(false)); static cl::opt +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 DisableExcessPrecision("disable-excess-fp-precision", cl::desc("Disable optimizations that may increase FP precision"), cl::location(NoExcessFPPrecision), @@ -268,6 +276,18 @@ void TargetMachine::setDataSections(bool V) { } 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 /// 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 diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index abb9aca78e9..6bf9be5b276 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -439,7 +439,7 @@ bool X86RegisterInfo::hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineModuleInfo &MMI = MF.getMMI(); - return (NoFramePointerElim || + return (DisableFramePointerElim(MF) || needsStackRealignment(MF) || MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken() || diff --git a/lib/Target/XCore/XCoreRegisterInfo.cpp b/lib/Target/XCore/XCoreRegisterInfo.cpp index 0db867f2d11..0cfb358617e 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.cpp +++ b/lib/Target/XCore/XCoreRegisterInfo.cpp @@ -113,7 +113,7 @@ XCoreRegisterInfo::requiresRegisterScavenging(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, diff --git a/test/CodeGen/X86/fp-elim.ll b/test/CodeGen/X86/fp-elim.ll new file mode 100644 index 00000000000..60892a2352f --- /dev/null +++ b/test/CodeGen/X86/fp-elim.ll @@ -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)