[llvm] r216294 - ARM / x86_64 varargs: Don't save regparms in prologue without va_start
Reid Kleckner
reid at kleckner.net
Fri Aug 22 14:59:28 PDT 2014
Author: rnk
Date: Fri Aug 22 16:59:26 2014
New Revision: 216294
URL: http://llvm.org/viewvc/llvm-project?rev=216294&view=rev
Log:
ARM / x86_64 varargs: Don't save regparms in prologue without va_start
There's no need to do this if the user doesn't call va_start. In the
future, we're going to have thunks that forward these register
parameters with musttail calls, and they won't need these spills for
handling va_start.
Most of the test suite changes are adding va_start calls to existing
tests to keep things working.
Added:
llvm/trunk/test/CodeGen/ARM/vararg_no_start.ll
llvm/trunk/test/CodeGen/X86/vararg_no_start.ll
Modified:
llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h
llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/test/CodeGen/ARM/fold-stack-adjust.ll
llvm/trunk/test/CodeGen/ARM/thumb1_return_sequence.ll
llvm/trunk/test/CodeGen/ARM/vargs_align.ll
llvm/trunk/test/CodeGen/Thumb/pop.ll
llvm/trunk/test/CodeGen/Thumb2/2009-08-06-SpDecBug.ll
llvm/trunk/test/CodeGen/X86/vastart-defs-eflags.ll
Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h?rev=216294&r1=216293&r2=216294&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Fri Aug 22 16:59:26 2014
@@ -236,6 +236,9 @@ class MachineFrameInfo {
/// pointer.
bool HasInlineAsmWithSPAdjust;
+ /// True if the function contains a call to the llvm.vastart intrinsic.
+ bool HasVAStart;
+
const TargetFrameLowering *getFrameLowering() const;
public:
explicit MachineFrameInfo(const TargetMachine &TM, bool RealignOpt)
@@ -256,6 +259,7 @@ public:
LocalFrameMaxAlign = 0;
UseLocalStackAllocationBlock = false;
HasInlineAsmWithSPAdjust = false;
+ HasVAStart = false;
}
/// hasStackObjects - Return true if there are any stack objects in this
@@ -475,6 +479,10 @@ public:
bool hasInlineAsmWithSPAdjust() const { return HasInlineAsmWithSPAdjust; }
void setHasInlineAsmWithSPAdjust(bool B) { HasInlineAsmWithSPAdjust = B; }
+ /// Returns true if the function calls the llvm.va_start intrinsic.
+ bool hasVAStart() const { return HasVAStart; }
+ void setHasVAStart(bool B) { HasVAStart = B; }
+
/// getMaxCallFrameSize - Return the maximum size of a call frame that must be
/// allocated for an outgoing function call. This is only available if
/// CallFrameSetup/Destroy pseudo instructions are used by the target, and
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp?rev=216294&r1=216293&r2=216294&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp Fri Aug 22 16:59:26 2014
@@ -138,6 +138,14 @@ void FunctionLoweringInfo::set(const Fun
}
}
+ // Look for calls to the @llvm.va_start intrinsic. We can omit some
+ // prologue boilerplate for variadic functions that don't examine their
+ // arguments.
+ if (const auto *II = dyn_cast<IntrinsicInst>(I)) {
+ if (II->getIntrinsicID() == Intrinsic::vastart)
+ MF->getFrameInfo()->setHasVAStart(true);
+ }
+
// Mark values used outside their block as exported, by allocating
// a virtual register for them.
if (isUsedOutsideOfDefiningBlock(I))
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=216294&r1=216293&r2=216294&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Aug 22 16:59:26 2014
@@ -3080,7 +3080,7 @@ ARMTargetLowering::LowerFormalArguments(
}
CCInfo.rewindByValRegsInfo();
lastInsIndex = -1;
- if (isVarArg) {
+ if (isVarArg && MFI->hasVAStart()) {
unsigned ExtraArgRegsSize;
unsigned ExtraArgRegsSaveSize;
computeRegArea(CCInfo, MF, CCInfo.getInRegsParamsCount(), 0,
@@ -3222,7 +3222,7 @@ ARMTargetLowering::LowerFormalArguments(
}
// varargs
- if (isVarArg)
+ if (isVarArg && MFI->hasVAStart())
VarArgStyleRegisters(CCInfo, DAG, dl, Chain,
CCInfo.getNextStackOffset(),
TotalArgRegsSaveSize);
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=216294&r1=216293&r2=216294&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Aug 22 16:59:26 2014
@@ -2405,8 +2405,9 @@ X86TargetLowering::LowerFormalArguments(
StackSize = GetAlignedArgumentStackSize(StackSize, DAG);
// If the function takes variable number of arguments, make a frame index for
- // the start of the first vararg value... for expansion of llvm.va_start.
- if (isVarArg) {
+ // the start of the first vararg value... for expansion of llvm.va_start. We
+ // can skip this if there are no va_start calls.
+ if (isVarArg && MFI->hasVAStart()) {
if (Is64Bit || (CallConv != CallingConv::X86_FastCall &&
CallConv != CallingConv::X86_ThisCall)) {
FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, StackSize,true));
Modified: llvm/trunk/test/CodeGen/ARM/fold-stack-adjust.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fold-stack-adjust.ll?rev=216294&r1=216293&r2=216294&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/fold-stack-adjust.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/fold-stack-adjust.ll Fri Aug 22 16:59:26 2014
@@ -183,6 +183,7 @@ define void @test_varsize(...) minsize {
; CHECK: bx lr
%var = alloca i8, i32 8
+ call void @llvm.va_start(i8* %var)
call void @bar(i8* %var)
ret void
}
@@ -216,3 +217,5 @@ if.then:
exit: ; preds = %if.then, %entry
ret float %call1
}
+
+declare void @llvm.va_start(i8*) nounwind
Modified: llvm/trunk/test/CodeGen/ARM/thumb1_return_sequence.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/thumb1_return_sequence.ll?rev=216294&r1=216293&r2=216294&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/thumb1_return_sequence.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/thumb1_return_sequence.ll Fri Aug 22 16:59:26 2014
@@ -46,6 +46,7 @@ entry:
store <4 x i32> <i32 42, i32 42, i32 42, i32 42>, <4 x i32>* %b, align 16
store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16
%0 = load <4 x i32>* %a, align 16
+ call void @llvm.va_start(i8* null)
ret <4 x i32> %0
; Epilogue
@@ -154,6 +155,7 @@ entry:
%7 = load i32* %d, align 4
%add5 = add nsw i32 %add4, %7
%add6 = add nsw i32 %add5, %i
+ call void @llvm.va_start(i8* null)
ret i32 %add6
; Epilogue
@@ -198,7 +200,8 @@ entry:
; CHECK-V5T: sub sp,
; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr}
- ret i32 %i;
+ call void @llvm.va_start(i8* null)
+ ret i32 %i;
; Epilogue
; --------
; CHECK-V4T: pop {[[SAVED]]}
@@ -210,3 +213,5 @@ entry:
; CHECK-V5T-NEXT: add sp,
; CHECK-V5T-NEXT: bx r3
}
+
+declare void @llvm.va_start(i8*) nounwind
Added: llvm/trunk/test/CodeGen/ARM/vararg_no_start.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vararg_no_start.ll?rev=216294&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/vararg_no_start.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/vararg_no_start.ll Fri Aug 22 16:59:26 2014
@@ -0,0 +1,10 @@
+; RUN: llc -mtriple=arm-darwin < %s | FileCheck %s
+; RUN: llc -O0 -mtriple=arm-darwin < %s | FileCheck %s
+
+define void @foo(i8*, ...) {
+ ret void
+}
+; CHECK-LABEL: {{^_?}}foo:
+; CHECK-NOT: str
+; CHECK: {{bx lr|mov pc, lr}}
+declare void @llvm.va_start(i8*) nounwind
Modified: llvm/trunk/test/CodeGen/ARM/vargs_align.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vargs_align.ll?rev=216294&r1=216293&r2=216294&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/vargs_align.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/vargs_align.ll Fri Aug 22 16:59:26 2014
@@ -10,6 +10,7 @@ entry:
store i32 0, i32* %tmp
%tmp1 = load i32* %tmp ; <i32> [#uses=1]
store i32 %tmp1, i32* %retval
+ call void @llvm.va_start(i8* null)
br label %return
return: ; preds = %entry
@@ -20,3 +21,5 @@ return: ; preds = %entry
; OABI: add sp, sp, #12
; OABI: add sp, sp, #12
}
+
+declare void @llvm.va_start(i8*) nounwind
Modified: llvm/trunk/test/CodeGen/Thumb/pop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb/pop.ll?rev=216294&r1=216293&r2=216294&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb/pop.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb/pop.ll Fri Aug 22 16:59:26 2014
@@ -7,7 +7,9 @@ define void @t(i8* %a, ...) nounwind {
; CHECK-NEXT: add sp, #12
; CHECK-NEXT: bx r3
entry:
- %a.addr = alloca i8*
- store i8* %a, i8** %a.addr
+ %a.addr = alloca i8, i32 4
+ call void @llvm.va_start(i8* %a.addr)
ret void
}
+
+declare void @llvm.va_start(i8*) nounwind
Modified: llvm/trunk/test/CodeGen/Thumb2/2009-08-06-SpDecBug.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/2009-08-06-SpDecBug.ll?rev=216294&r1=216293&r2=216294&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/2009-08-06-SpDecBug.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/2009-08-06-SpDecBug.ll Fri Aug 22 16:59:26 2014
@@ -13,6 +13,7 @@ entry:
; CHECK-NOT: mov sp, r7
; CHECK: add sp, #8
call void @__gcov_flush() nounwind
+ call void @llvm.va_start(i8* null)
br i1 undef, label %bb5, label %bb
bb: ; preds = %bb, %entry
@@ -27,3 +28,5 @@ bb5: ; preds = %bb, %entry
declare hidden void @__gcov_flush()
declare i32 @execvp(i8*, i8**) nounwind
+
+declare void @llvm.va_start(i8*) nounwind
Added: llvm/trunk/test/CodeGen/X86/vararg_no_start.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vararg_no_start.ll?rev=216294&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/vararg_no_start.ll (added)
+++ llvm/trunk/test/CodeGen/X86/vararg_no_start.ll Fri Aug 22 16:59:26 2014
@@ -0,0 +1,9 @@
+; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s
+; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
+
+define void @foo(i8*, ...) {
+ ret void
+}
+; CHECK-LABEL: {{^_?}}foo:
+; CHECK-NOT: movq
+; CHECK: retq
Modified: llvm/trunk/test/CodeGen/X86/vastart-defs-eflags.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vastart-defs-eflags.ll?rev=216294&r1=216293&r2=216294&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/vastart-defs-eflags.ll (original)
+++ llvm/trunk/test/CodeGen/X86/vastart-defs-eflags.ll Fri Aug 22 16:59:26 2014
@@ -14,6 +14,7 @@ entry:
br i1 %tobool, label %if.end, label %if.then
if.then: ; preds = %entry
+ call void @llvm.va_start(i8* null)
br label %if.end
if.end: ; preds = %entry, %if.then
@@ -21,3 +22,4 @@ if.end:
ret i32 %hasflag
}
+declare void @llvm.va_start(i8*) nounwind
More information about the llvm-commits
mailing list