Index: include/llvm/Target/TargetFrameLowering.h =================================================================== --- include/llvm/Target/TargetFrameLowering.h +++ include/llvm/Target/TargetFrameLowering.h @@ -18,6 +18,8 @@ #include #include +extern llvm::cl::opt UseIPRA; + namespace llvm { class BitVector; class CalleeSavedInfo; Index: lib/CodeGen/TargetFrameLoweringImpl.cpp =================================================================== --- lib/CodeGen/TargetFrameLoweringImpl.cpp +++ lib/CodeGen/TargetFrameLoweringImpl.cpp @@ -59,6 +59,14 @@ void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const { + // When interprocedural register allocation is enabled caller saved registers + // are preferred over callee saved registers. + if (UseIPRA) { + Function *F = const_cast(MF.getFunction()); + if (F->hasLocalLinkage() && !F->hasAddressTaken()) + return; + } + // Get the callee saved register list... const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF); Index: test/CodeGen/X86/ipra-local-linkage.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/ipra-local-linkage.ll @@ -0,0 +1,22 @@ +; RUN: llc < %s | FileCheck %s -check-prefix=NOIPRA +; RUN: llc -enable-ipra < %s | FileCheck %s + +target triple = "x86_64--" + +define void @bar() #0 { + call void @foo() + ret void +} + +define internal void @foo() #0 { +; When IPRA is not enabled R15 will be saved by foo as it is callee saved reg. +; NOIPRA-LABEL: foo: +; NOIPRA: pushq %r15 +; When IPRA is enabled none register should be saved as foo() is local function +; so we optimize it to save no registers. +; CHECK: foo: +; CHECK-NOT: pushq %r15 + call void asm sideeffect "", "~{eax},~{ecx},~{edi},~{r15}"() #0 + ret void +} +attributes #0 = {nounwind}