<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>