mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 23:32:27 +00:00
Don't insert lifetime.end markers between a musttail call and ret
The allocas going out of scope are immediately killed by the return instruction. Reviewers: chandlerc Differential Revision: http://reviews.llvm.org/D3630 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208912 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
44623e8781
commit
24a50c5797
@ -758,10 +758,15 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
builder.CreateLifetimeStart(AI, AllocaSize);
|
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);
|
IRBuilder<>(RI).CreateLifetimeEnd(AI, AllocaSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the inlined code contained dynamic alloca instructions, wrap the inlined
|
// If the inlined code contained dynamic alloca instructions, wrap the inlined
|
||||||
// code with llvm.stacksave/llvm.stackrestore intrinsics.
|
// code with llvm.stacksave/llvm.stackrestore intrinsics.
|
||||||
@ -777,9 +782,14 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
|
|||||||
|
|
||||||
// Insert a call to llvm.stackrestore before any return instructions in the
|
// Insert a call to llvm.stackrestore before any return instructions in the
|
||||||
// inlined function.
|
// 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);
|
IRBuilder<>(RI).CreateCall(StackRestore, SavedPtr);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we are inlining for an invoke instruction, we must make sure to rewrite
|
// If we are inlining for an invoke instruction, we must make sure to rewrite
|
||||||
// any call instructions into invoke instructions.
|
// any call instructions into invoke instructions.
|
||||||
|
@ -49,6 +49,42 @@ define void @test_musttail_basic_a(i32* %p) {
|
|||||||
ret void
|
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.
|
; We can't merge the returns.
|
||||||
; CHECK: define void @test_multiret_a(
|
; CHECK: define void @test_multiret_a(
|
||||||
; CHECK: musttail call void @test_multiret_c(
|
; CHECK: musttail call void @test_multiret_c(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user