<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 1, 2016 at 11:20 AM, David Majnemer via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: majnemer<br>
Date: Tue Mar 1 13:20:23 2016<br>
New Revision: 262370<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=262370&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=262370&view=rev</a><br>
Log:<br>
[X86] Elide references to _chkstk for dynamic allocas<br>
<br>
The _chkstk function is called by the compiler to probe the stack in an<br>
order consistent with Windows' expectations. However, it is possible to<br>
elide the call to _chkstk and manually adjust the stack pointer if we<br>
can prove that the allocation is fixed size and smaller than the probe<br>
size.<br>
<br>
This shrinks chrome.dll, chrome_child.dll and chrome.exe by a<br>
cummulative ~133 KB.<br></blockquote><div><br></div><div>Out of what total?</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Differential Revision: <a href="http://reviews.llvm.org/D17679" rel="noreferrer" target="_blank">http://reviews.llvm.org/D17679</a><br>
<br>
Modified:<br>
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll<br>
llvm/trunk/test/CodeGen/X86/dynamic-alloca-in-entry.ll<br>
llvm/trunk/test/CodeGen/X86/inalloca-ctor.ll<br>
llvm/trunk/test/CodeGen/X86/inalloca-invoke.ll<br>
llvm/trunk/test/CodeGen/X86/inalloca-stdcall.ll<br>
llvm/trunk/test/CodeGen/X86/inalloca.ll<br>
llvm/trunk/test/CodeGen/X86/shrink-wrap-chkstk.ll<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=262370&r1=262369&r2=262370&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=262370&r1=262369&r2=262370&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Mar 1 13:20:23 2016<br>
@@ -16366,9 +16366,8 @@ SDValue<br>
X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,<br>
SelectionDAG &DAG) const {<br>
MachineFunction &MF = DAG.getMachineFunction();<br>
+ const Function *F = MF.getFunction();<br>
bool SplitStack = MF.shouldSplitStack();<br>
- bool Lower = (Subtarget.isOSWindows() && !Subtarget.isTargetMachO()) ||<br>
- SplitStack;<br>
SDLoc dl(Op);<br>
<br>
// Get the inputs.<br>
@@ -16382,21 +16381,45 @@ X86TargetLowering::LowerDYNAMIC_STACKALL<br>
// pointer when other instructions are using the stack.<br>
Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, dl, true), dl);<br>
<br>
+ const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();<br>
bool Is64Bit = Subtarget.is64Bit();<br>
MVT SPTy = getPointerTy(DAG.getDataLayout());<br>
<br>
+ bool CheckStack = SplitStack;<br>
+ if (!CheckStack && Subtarget.isOSWindows() && !Subtarget.isTargetMachO()) {<br>
+ // The Windows ABI requires us to probe the stack for allocations beyond<br>
+ // the probe size.<br>
+ if (auto *SizeC = dyn_cast<ConstantSDNode>(Size)) {<br>
+ // Try to elide the probe if we can prove that this dynamic allocation is<br>
+ // smaller than the probe size.<br>
+ unsigned StackProbeSize = 4096;<br>
+ if (F->hasFnAttribute("stack-probe-size"))<br>
+ F->getFnAttribute("stack-probe-size")<br>
+ .getValueAsString()<br>
+ .getAsInteger(0, StackProbeSize);<br>
+ unsigned AlignedAlloc = SizeC->getZExtValue();<br>
+ // Round the dynamic alloca's size up to it's alignment.<br>
+ if (Align)<br>
+ AlignedAlloc = alignTo(AlignedAlloc, Align);<br>
+<br>
+ // If the aligned allocation is smaller than the probe size, then we don't<br>
+ // need to probe the stack.<br>
+ CheckStack = AlignedAlloc >= StackProbeSize;<br>
+ } else {<br>
+ // We cannot tell how big this dynamic alloca will be, probe the stack.<br>
+ CheckStack = true;<br>
+ }<br>
+ }<br>
+<br>
SDValue Result;<br>
- if (!Lower) {<br>
+ if (!CheckStack) {<br>
const TargetLowering &TLI = DAG.getTargetLoweringInfo();<br>
unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore();<br>
assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and"<br>
" not tell us which reg is the stack pointer!");<br>
- EVT VT = Node->getValueType(0);<br>
- SDValue Tmp3 = Node->getOperand(2);<br>
<br>
SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);<br>
Chain = SP.getValue(1);<br>
- unsigned Align = cast<ConstantSDNode>(Tmp3)->getZExtValue();<br>
const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();<br>
unsigned StackAlign = TFI.getStackAlignment();<br>
Result = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value<br>
@@ -16410,8 +16433,6 @@ X86TargetLowering::LowerDYNAMIC_STACKALL<br>
if (Is64Bit) {<br>
// The 64 bit implementation of segmented stacks needs to clobber both r10<br>
// r11. This makes it impossible to use it along with nested parameters.<br>
- const Function *F = MF.getFunction();<br>
-<br>
for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();<br>
I != E; ++I)<br>
if (I->hasNestAttr())<br>
@@ -16434,7 +16455,6 @@ X86TargetLowering::LowerDYNAMIC_STACKALL<br>
<br>
Chain = DAG.getNode(X86ISD::WIN_ALLOCA, dl, NodeTys, Chain, Flag);<br>
<br>
- const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();<br>
unsigned SPReg = RegInfo->getStackRegister();<br>
SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, SPTy);<br>
Chain = SP.getValue(1);<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll?rev=262370&r1=262369&r2=262370&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll?rev=262370&r1=262369&r2=262370&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll Tue Mar 1 13:20:23 2016<br>
@@ -38,8 +38,9 @@ ehcleanup:<br>
; CHECK: pushl %ebp<br>
; CHECK: movl %esp, %ebp<br>
; CHECK: subl ${{[0-9]+}}, %esp<br>
-; CHECK: movl $8, %eax<br>
-; CHECK: calll __chkstk<br>
+; CHECK: movl %esp, %[[tmp_sp1:.*]]<br>
+; CHECK: leal -8(%[[tmp_sp1]]), %[[tmp_sp2:.*]]<br>
+; CHECK: %[[tmp_sp2]], %esp<br>
; CHECK: calll "??0A@@QAE@XZ"<br>
; CHECK: calll "??0A@@QAE@XZ"<br>
; CHECK: calll _takes_two<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/dynamic-alloca-in-entry.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dynamic-alloca-in-entry.ll?rev=262370&r1=262369&r2=262370&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dynamic-alloca-in-entry.ll?rev=262370&r1=262369&r2=262370&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/dynamic-alloca-in-entry.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/dynamic-alloca-in-entry.ll Tue Mar 1 13:20:23 2016<br>
@@ -15,5 +15,8 @@ define void @bar() {<br>
ret void<br>
}<br>
; CHECK-LABEL: _bar:<br>
-; CHECK: calll __chkstk<br>
+; CHECK: movl %esp, %ebp<br>
+; CHECK: movl %esp, %[[sp_tmp:.*]]<br>
+; CHECK: addl $-4, %[[sp_tmp]]<br>
+; CHECK: movl %[[sp_tmp]], %esp<br>
; CHECK: retl<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/inalloca-ctor.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inalloca-ctor.ll?rev=262370&r1=262369&r2=262370&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inalloca-ctor.ll?rev=262370&r1=262369&r2=262370&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/inalloca-ctor.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/inalloca-ctor.ll Tue Mar 1 13:20:23 2016<br>
@@ -10,13 +10,14 @@ declare void @Foo_ctor(%Foo* %this)<br>
<br>
define void @g() {<br>
entry:<br>
+; CHECK: movl %esp, %ebp<br>
%args = alloca inalloca %frame<br>
%c = getelementptr %frame, %frame* %args, i32 0, i32 2<br>
-; CHECK: movl $20, %eax<br>
-; CHECK: calll __chkstk<br>
-; CHECK: movl %esp,<br>
+; CHECK: movl %esp, %[[tmp_sp1:.*]]<br>
+; CHECK: leal -20(%[[tmp_sp1]]), %[[tmp_sp2:.*]]<br>
+; CHECK: movl %[[tmp_sp2]], %esp<br>
call void @Foo_ctor(%Foo* %c)<br>
-; CHECK: leal 12(%{{.*}}),<br>
+; CHECK: leal -8(%[[tmp_sp1]]),<br>
; CHECK-NEXT: pushl<br>
; CHECK-NEXT: calll _Foo_ctor<br>
; CHECK: addl $4, %esp<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/inalloca-invoke.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inalloca-invoke.ll?rev=262370&r1=262369&r2=262370&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inalloca-invoke.ll?rev=262370&r1=262369&r2=262370&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/inalloca-invoke.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/inalloca-invoke.ll Tue Mar 1 13:20:23 2016<br>
@@ -12,6 +12,7 @@ declare void @plus(%Iter* sret, %Iter*,<br>
declare void @reverse(%frame.reverse* inalloca align 4)<br>
<br>
define i32 @main() personality i32 (...)* @pers {<br>
+; CHECK: movl %esp, %ebp<br>
%temp.lvalue = alloca %Iter<br>
br label %blah<br>
<br>
@@ -21,9 +22,10 @@ blah:<br>
%beg = getelementptr %frame.reverse, %frame.reverse* %rev_args, i32 0, i32 0<br>
%end = getelementptr %frame.reverse, %frame.reverse* %rev_args, i32 0, i32 1<br>
<br>
-; CHECK: calll __chkstk<br>
-; CHECK: movl %esp, %[[beg:[^ ]*]]<br>
-; CHECK: leal 12(%[[beg]]), %[[end:[^ ]*]]<br>
+; CHECK: movl %esp, %[[end:.*]]<br>
+; CHECK: leal -24(%[[end]]), %[[beg:.*]]<br>
+; CHECK: movl %[[beg]], %esp<br>
+; CHECK: addl $-12, %[[end]]<br>
<br>
call void @begin(%Iter* sret %temp.lvalue)<br>
; CHECK: calll _begin<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/inalloca-stdcall.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inalloca-stdcall.ll?rev=262370&r1=262369&r2=262370&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inalloca-stdcall.ll?rev=262370&r1=262369&r2=262370&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/inalloca-stdcall.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/inalloca-stdcall.ll Tue Mar 1 13:20:23 2016<br>
@@ -7,16 +7,16 @@ declare x86_stdcallcc void @i(i32 %a)<br>
<br>
define void @g() {<br>
; CHECK-LABEL: _g:<br>
+; CHECK: movl %esp, %ebp<br>
%b = alloca inalloca %Foo<br>
-; CHECK: movl $8, %eax<br>
-; CHECK: calll __chkstk<br>
+; CHECK: movl %esp, %[[tmp_sp:.*]]<br>
+; CHECK: leal -8(%[[tmp_sp]]), %esp<br>
%f1 = getelementptr %Foo, %Foo* %b, i32 0, i32 0<br>
%f2 = getelementptr %Foo, %Foo* %b, i32 0, i32 1<br>
store i32 13, i32* %f1<br>
store i32 42, i32* %f2<br>
-; CHECK: movl %esp, %eax<br>
-; CHECK: movl $13, (%eax)<br>
-; CHECK: movl $42, 4(%eax)<br>
+; CHECK: movl $13, -8(%[[tmp_sp]])<br>
+; CHECK: movl $42, -4(%[[tmp_sp]])<br>
call x86_stdcallcc void @f(%Foo* inalloca %b)<br>
; CHECK: calll _f@8<br>
; CHECK-NOT: %esp<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/inalloca.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inalloca.ll?rev=262370&r1=262369&r2=262370&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inalloca.ll?rev=262370&r1=262369&r2=262370&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/inalloca.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/inalloca.ll Tue Mar 1 13:20:23 2016<br>
@@ -7,16 +7,16 @@ declare void @f(%Foo* inalloca %b)<br>
define void @a() {<br>
; CHECK-LABEL: _a:<br>
entry:<br>
+; CHECK: movl %esp, %ebp<br>
%b = alloca inalloca %Foo<br>
-; CHECK: movl $8, %eax<br>
-; CHECK: calll __chkstk<br>
+; CHECK: movl %esp, %[[tmp_sp:.*]]<br>
+; CHECK: leal -8(%[[tmp_sp]]), %esp<br>
%f1 = getelementptr %Foo, %Foo* %b, i32 0, i32 0<br>
%f2 = getelementptr %Foo, %Foo* %b, i32 0, i32 1<br>
store i32 13, i32* %f1<br>
store i32 42, i32* %f2<br>
-; CHECK: movl %esp, %eax<br>
-; CHECK: movl $13, (%eax)<br>
-; CHECK: movl $42, 4(%eax)<br>
+; CHECK: movl $13, -8(%[[tmp_sp]])<br>
+; CHECK: movl $42, -4(%[[tmp_sp]])<br>
call void @f(%Foo* inalloca %b)<br>
; CHECK: calll _f<br>
ret void<br>
@@ -27,16 +27,16 @@ declare void @inreg_with_inalloca(i32 in<br>
define void @b() {<br>
; CHECK-LABEL: _b:<br>
entry:<br>
+; CHECK: movl %esp, %ebp<br>
%b = alloca inalloca %Foo<br>
-; CHECK: movl $8, %eax<br>
-; CHECK: calll __chkstk<br>
+; CHECK: movl %esp, %[[tmp_sp:.*]]<br>
+; CHECK: leal -8(%[[tmp_sp]]), %esp<br>
%f1 = getelementptr %Foo, %Foo* %b, i32 0, i32 0<br>
%f2 = getelementptr %Foo, %Foo* %b, i32 0, i32 1<br>
store i32 13, i32* %f1<br>
store i32 42, i32* %f2<br>
-; CHECK: movl %esp, %eax<br>
-; CHECK: movl $13, (%eax)<br>
-; CHECK: movl $42, 4(%eax)<br>
+; CHECK: movl $13, -8(%[[tmp_sp]])<br>
+; CHECK: movl $42, -4(%[[tmp_sp]])<br>
call void @inreg_with_inalloca(i32 inreg 1, %Foo* inalloca %b)<br>
; CHECK: movl $1, %eax<br>
; CHECK: calll _inreg_with_inalloca<br>
@@ -48,16 +48,16 @@ declare x86_thiscallcc void @thiscall_wi<br>
define void @c() {<br>
; CHECK-LABEL: _c:<br>
entry:<br>
+; CHECK: movl %esp, %ebp<br>
%b = alloca inalloca %Foo<br>
-; CHECK: movl $8, %eax<br>
-; CHECK: calll __chkstk<br>
+; CHECK: movl %esp, %[[tmp_sp:.*]]<br>
+; CHECK: leal -8(%[[tmp_sp]]), %esp<br>
%f1 = getelementptr %Foo, %Foo* %b, i32 0, i32 0<br>
%f2 = getelementptr %Foo, %Foo* %b, i32 0, i32 1<br>
store i32 13, i32* %f1<br>
store i32 42, i32* %f2<br>
-; CHECK: movl %esp, %eax<br>
-; CHECK-DAG: movl $13, (%eax)<br>
-; CHECK-DAG: movl $42, 4(%eax)<br>
+; CHECK-DAG: movl $13, -8(%[[tmp_sp]])<br>
+; CHECK-DAG: movl $42, -4(%[[tmp_sp]])<br>
call x86_thiscallcc void @thiscall_with_inalloca(i8* null, %Foo* inalloca %b)<br>
; CHECK-DAG: xorl %ecx, %ecx<br>
; CHECK: calll _thiscall_with_inalloca<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/shrink-wrap-chkstk.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shrink-wrap-chkstk.ll?rev=262370&r1=262369&r2=262370&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shrink-wrap-chkstk.ll?rev=262370&r1=262369&r2=262370&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/shrink-wrap-chkstk.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/shrink-wrap-chkstk.ll Tue Mar 1 13:20:23 2016<br>
@@ -9,7 +9,7 @@ target triple = "i686-pc-windows-msvc18.<br>
<br>
%struct.S = type { [12 x i8] }<br>
<br>
-define x86_thiscallcc void @call_inalloca(i1 %x) {<br>
+define x86_thiscallcc void @call_inalloca(i1 %x) "stack-probe-size"="12" {<br>
entry:<br>
%argmem = alloca inalloca <{ %struct.S }>, align 4<br>
%argidx1 = getelementptr inbounds <{ %struct.S }>, <{ %struct.S }>* %argmem, i32 0, i32 0, i32 0, i32 0<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>