[PATCH] Don't insert lifetime.end markers between a musttail call and ret

Chandler Carruth chandlerc at gmail.com
Thu May 15 14:06:24 PDT 2014


This is fine, and explains it better IMO. Seeing them together also helps
me think about it in the right (and more obvious) direction. Thanks!


On Thu, May 15, 2014 at 2:58 PM, Reid Kleckner <rnk at google.com> wrote:

> Hi chandlerc,
>
> The allocas going out of scope are immediately killed by the return
> instruction.
>
> This is a resend of r208912, which was committed accidentally.
>
> http://reviews.llvm.org/D3792
>
> Files:
>   lib/Transforms/Utils/InlineFunction.cpp
>   test/Transforms/Inline/inline-tail.ll
>
> Index: lib/Transforms/Utils/InlineFunction.cpp
> ===================================================================
> --- lib/Transforms/Utils/InlineFunction.cpp
> +++ lib/Transforms/Utils/InlineFunction.cpp
> @@ -755,8 +755,13 @@
>        }
>
>        builder.CreateLifetimeStart(AI, AllocaSize);
> -      for (ReturnInst *RI : Returns)
> +      for (ReturnInst *RI : Returns) {
> +        // Don't insert llvm.lifetime.end calls between a musttail call
> and a
> +        // return.  The return kills all local allocas.
> +        if (InlinedMustTailCalls && getPrecedingMustTailCall(RI))
> +          continue;
>          IRBuilder<>(RI).CreateLifetimeEnd(AI, AllocaSize);
> +      }
>      }
>    }
>
> @@ -774,8 +779,13 @@
>
>      // Insert a call to llvm.stackrestore before any return instructions
> in the
>      // inlined function.
> -    for (ReturnInst *RI : Returns)
> +    for (ReturnInst *RI : Returns) {
> +      // Don't insert llvm.stackrestore calls between a musttail call and
> a
> +      // return.  The return will restore the stack pointer.
> +      if (InlinedMustTailCalls && getPrecedingMustTailCall(RI))
> +        continue;
>        IRBuilder<>(RI).CreateCall(StackRestore, SavedPtr);
> +    }
>    }
>
>    // If we are inlining for an invoke instruction, we must make sure to
> rewrite
> Index: test/Transforms/Inline/inline-tail.ll
> ===================================================================
> --- test/Transforms/Inline/inline-tail.ll
> +++ test/Transforms/Inline/inline-tail.ll
> @@ -49,6 +49,42 @@
>    ret void
>  }
>
> +; Don't insert lifetime end markers here, the lifetime is trivially over
> due
> +; the return.
> +; CHECK: define void @test_byval_a(
> +; CHECK: musttail call void @test_byval_c(
> +; CHECK-NEXT: ret void
> +
> +declare void @test_byval_c(i32* byval %p)
> +define internal void @test_byval_b(i32* byval %p) {
> +  musttail call void @test_byval_c(i32* byval %p)
> +  ret void
> +}
> +define void @test_byval_a(i32* byval %p) {
> +  musttail call void @test_byval_b(i32* byval %p)
> +  ret void
> +}
> +
> +; Don't insert a stack restore, we're about to return.
> +; CHECK: define void @test_dynalloca_a(
> +; CHECK: call i8* @llvm.stacksave(
> +; CHECK: alloca i8, i32 %n
> +; CHECK: musttail call void @test_dynalloca_c(
> +; CHECK-NEXT: ret void
> +
> +declare void @escape(i8* %buf)
> +declare void @test_dynalloca_c(i32* byval %p, i32 %n)
> +define internal void @test_dynalloca_b(i32* byval %p, i32 %n)
> alwaysinline {
> +  %buf = alloca i8, i32 %n              ; dynamic alloca
> +  call void @escape(i8* %buf)           ; escape it
> +  musttail call void @test_dynalloca_c(i32* byval %p, i32 %n)
> +  ret void
> +}
> +define void @test_dynalloca_a(i32* byval %p, i32 %n) {
> +  musttail call void @test_dynalloca_b(i32* byval %p, i32 %n)
> +  ret void
> +}
> +
>  ; We can't merge the returns.
>  ; CHECK: define void @test_multiret_a(
>  ; CHECK: musttail call void @test_multiret_c(
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140515/64306869/attachment.html>


More information about the llvm-commits mailing list