Implement -disable-non-leaf-fp-elim which disable frame pointer elimination
authorEvan Cheng <evan.cheng@apple.com>
Wed, 21 Apr 2010 03:18:23 +0000 (03:18 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 21 Apr 2010 03:18:23 +0000 (03:18 +0000)
optimization for non-leaf functions. This will be hooked up to gcc's
-momit-leaf-frame-pointer option. rdar://7886181

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101984 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
include/llvm/Target/TargetOptions.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/Target/ARM/ARMBaseRegisterInfo.cpp
lib/Target/Blackfin/BlackfinRegisterInfo.cpp
lib/Target/CellSPU/SPURegisterInfo.cpp
lib/Target/MBlaze/MBlazeRegisterInfo.cpp
lib/Target/MSP430/MSP430RegisterInfo.cpp
lib/Target/Mips/MipsRegisterInfo.cpp
lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCRegisterInfo.cpp
lib/Target/SystemZ/SystemZRegisterInfo.cpp
lib/Target/TargetMachine.cpp
lib/Target/X86/X86RegisterInfo.cpp
lib/Target/XCore/XCoreRegisterInfo.cpp
test/CodeGen/X86/fp-elim.ll [new file with mode: 0644]

index a01a67f14daed5794b564ce9032e98b15941469f..fb5698f1afb8a5e2cef2b30fbb4d52b86805e624 100644 (file)
@@ -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
index 684a409c9ffc5c041608f7595947e050b4e36918..c31aec17590486735db76c42b923ee83d680a5bf 100644 (file)
@@ -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;
index 46c50f990b7bf45d990473b12b59aac12fd1c6b9..2a4e1a853ab56d11f4f36791d48fb91801bc4082 100644 (file)
@@ -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);
index 6fd610fa3b537b9c70ce0701a1f7df39c3193931..2512c9b7fb1de52a08da5453d19c4fb31f6d3d8b 100644 (file)
@@ -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::
index 9a9c9f7436294ccfc85e34fd00588f37391a5260..fdbe10f84a7aece280034b094522fa1c6cb71317 100644 (file)
@@ -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();
 }
 
 //--------------------------------------------------------------------------
index a12310a2bd32680bfb2fe5140a858b86c3bfcce6..e15176eb06bec8d17df01adbf3e2a387233a69be 100644 (file)
@@ -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,
index d91783a80c8313839c11d9d6befdbea2b2d45e67..0cae26714bfc770174f7ca44d272f0ab6634572b 100644 (file)
@@ -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());
 }
index f43e69b354575501a529cc621ea146d5e68c8f94..478da84cad0ce356ddf039a5af3b4ca712216681 100644 (file)
@@ -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, 
index 894436c558c7ebef649507c70bdfda20bf7b64a3..b825d647ee5ca044db842cd817beb8e0cff32d46 100644 (file)
@@ -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)
index 889acde2236a9d589575a720e502173f7afa7e3d..8048df21b7d6d06a21a031cb0477077068614884 100644 (file)
@@ -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<PPCFunctionInfo>()->hasFastCall());
 }
 
index 5e325c08c36091954522fe7efabc81524bd62347..638fd17c9953ee05e32b791a9bb1482496bfed35 100644 (file)
@@ -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::
index 871b148adb395773412769a0d8c8c1d3ea100eb2..d90755a3b3342da49e0b386cc091531cdedf120d 100644 (file)
@@ -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<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",
   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
index abb9aca78e9c70a7e477a749b801ad66286c614f..6bf9be5b276702277a44a94a970368cbfaf47557 100644 (file)
@@ -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() ||
index 0db867f2d11b3c1c9d52ffa160dd5a471628ba53..0cfb358617e8235b57a5c8cd88e3d5a5fb8c053e 100644 (file)
@@ -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 (file)
index 0000000..60892a2
--- /dev/null
@@ -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)