[llvm-commits] [llvm] r167821 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/lifetime-no-datalayout.ll test/Transforms/Inline/lifetime.ll
Nick Lewycky
nicholas at mxc.ca
Tue Nov 13 13:11:58 PST 2012
Duncan Sands wrote:
> Hi Alexey,
>
>> Figure out <size> argument of llvm.lifetime intrinsics at the moment
>> they are created (during function inlining)
>
> wouldn't it be better to do this in instcombine?
Whoever creates it in the first place already has a handle on it and
should do the best job they can. Same reason passes run
SimplifyInstruction on instructions they just emitted, or
PromoteMemToReg on allocas they just emitted. There's no reason to
create the wrong thing and then have that pass through some number of
passes before it gets corrected.
However, I agree that we should consider adding similar logic to
instcombine, if that's also useful. Is it useful? I'm sure that the
inliner isn't introducing lifetime intrinsics with sizes it can't solve
itself, but if we're going to teach clang to emit them then certainly we
will want to solve their sizes in instcombine too.
Nick
For example, suppose
> you have
> a dynamically sized alloca with an associated lifetime intrinsic with a
> size of
> -1. Instcombine may be able to (and often does) simplify the size of the
> alloca
> to a constant, in which case the size of the lifetime intrinsic could be
> fixed
> up to be that constant too. I'm just saying that this optimization
> doesn't have
> anything much to do with inlining, it seems to be generally useful, so
> would be
> better off in instcombine probably.
>
> Ciao, Duncan.
>
>>
>> Added:
>> llvm/trunk/test/Transforms/Inline/lifetime-no-datalayout.ll
>> Modified:
>> llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
>> llvm/trunk/test/Transforms/Inline/lifetime.ll
>>
>> Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=167821&r1=167820&r2=167821&view=diff
>>
>> ==============================================================================
>>
>> --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Tue Nov 13
>> 01:15:32 2012
>> @@ -668,10 +668,29 @@
>> if (hasLifetimeMarkers(AI))
>> continue;
>>
>> - builder.CreateLifetimeStart(AI);
>> + // Try to determine the size of the allocation.
>> + ConstantInt *AllocaSize = 0;
>> + if (ConstantInt *AIArraySize =
>> + dyn_cast<ConstantInt>(AI->getArraySize())) {
>> + if (IFI.TD) {
>> + Type *AllocaType = AI->getAllocatedType();
>> + uint64_t AllocaTypeSize = IFI.TD->getTypeAllocSize(AllocaType);
>> + uint64_t AllocaArraySize = AIArraySize->getLimitedValue();
>> + assert(AllocaArraySize > 0 && "array size of AllocaInst is zero");
>> + // Check that array size doesn't saturate uint64_t and doesn't
>> + // overflow when it's multiplied by type size.
>> + if (AllocaArraySize != ~0ULL &&
>> + UINT64_MAX / AllocaArraySize >= AllocaTypeSize) {
>> + AllocaSize = ConstantInt::get(Type::getInt64Ty(AI->getContext()),
>> + AllocaArraySize * AllocaTypeSize);
>> + }
>> + }
>> + }
>> +
>> + builder.CreateLifetimeStart(AI, AllocaSize);
>> for (unsigned ri = 0, re = Returns.size(); ri != re; ++ri) {
>> IRBuilder<> builder(Returns[ri]);
>> - builder.CreateLifetimeEnd(AI);
>> + builder.CreateLifetimeEnd(AI, AllocaSize);
>> }
>> }
>> }
>>
>> Added: llvm/trunk/test/Transforms/Inline/lifetime-no-datalayout.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/lifetime-no-datalayout.ll?rev=167821&view=auto
>>
>> ==============================================================================
>>
>> --- llvm/trunk/test/Transforms/Inline/lifetime-no-datalayout.ll (added)
>> +++ llvm/trunk/test/Transforms/Inline/lifetime-no-datalayout.ll Tue
>> Nov 13 01:15:32 2012
>> @@ -0,0 +1,23 @@
>> +; RUN: opt -inline %s -S -o - | FileCheck %s
>> +
>> +declare void @use(i8* %a)
>> +
>> +define void @helper() {
>> + %a = alloca i8
>> + call void @use(i8* %a)
>> + ret void
>> +}
>> +
>> +; Size in llvm.lifetime.X should be -1 (unknown).
>> +define void @test() {
>> +; CHECK: @test
>> +; CHECK-NOT: lifetime
>> +; CHECK: llvm.lifetime.start(i64 -1
>> +; CHECK-NOT: lifetime
>> +; CHECK: llvm.lifetime.end(i64 -1
>> + call void @helper()
>> +; CHECK-NOT: lifetime
>> +; CHECK: ret void
>> + ret void
>> +}
>> +
>>
>> Modified: llvm/trunk/test/Transforms/Inline/lifetime.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/lifetime.ll?rev=167821&r1=167820&r2=167821&view=diff
>>
>> ==============================================================================
>>
>> --- llvm/trunk/test/Transforms/Inline/lifetime.ll (original)
>> +++ llvm/trunk/test/Transforms/Inline/lifetime.ll Tue Nov 13 01:15:32
>> 2012
>> @@ -1,22 +1,25 @@
>> ; RUN: opt -inline %s -S -o - | FileCheck %s
>> +target datalayout =
>> "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
>>
>>
>> declare void @llvm.lifetime.start(i64, i8*)
>> declare void @llvm.lifetime.end(i64, i8*)
>>
>> define void @helper_both_markers() {
>> %a = alloca i8
>> - call void @llvm.lifetime.start(i64 1, i8* %a)
>> - call void @llvm.lifetime.end(i64 1, i8* %a)
>> + ; Size in llvm.lifetime.start / llvm.lifetime.end differs from
>> + ; allocation size. We should use the former.
>> + call void @llvm.lifetime.start(i64 2, i8* %a)
>> + call void @llvm.lifetime.end(i64 2, i8* %a)
>> ret void
>> }
>>
>> define void @test_both_markers() {
>> ; CHECK: @test_both_markers
>> -; CHECK: llvm.lifetime.start(i64 1
>> -; CHECK-NEXT: llvm.lifetime.end(i64 1
>> +; CHECK: llvm.lifetime.start(i64 2
>> +; CHECK-NEXT: llvm.lifetime.end(i64 2
>> call void @helper_both_markers()
>> -; CHECK-NEXT: llvm.lifetime.start(i64 1
>> -; CHECK-NEXT: llvm.lifetime.end(i64 1
>> +; CHECK-NEXT: llvm.lifetime.start(i64 2
>> +; CHECK-NEXT: llvm.lifetime.end(i64 2
>> call void @helper_both_markers()
>> ; CHECK-NEXT: ret void
>> ret void
>> @@ -27,7 +30,7 @@
>> declare void @use(i8* %a)
>>
>> define void @helper_no_markers() {
>> - %a = alloca i8
>> + %a = alloca i8 ; Allocation size is 1 byte.
>> call void @use(i8* %a)
>> ret void
>> }
>> @@ -37,14 +40,14 @@
>> define void @test_no_marker() {
>> ; CHECK: @test_no_marker
>> ; CHECK-NOT: lifetime
>> -; CHECK: llvm.lifetime.start(i64 -1
>> +; CHECK: llvm.lifetime.start(i64 1
>> ; CHECK-NOT: lifetime
>> -; CHECK: llvm.lifetime.end(i64 -1
>> +; CHECK: llvm.lifetime.end(i64 1
>> call void @helper_no_markers()
>> ; CHECK-NOT: lifetime
>> -; CHECK: llvm.lifetime.start(i64 -1
>> +; CHECK: llvm.lifetime.start(i64 1
>> ; CHECK-NOT: lifetime
>> -; CHECK: llvm.lifetime.end(i64 -1
>> +; CHECK: llvm.lifetime.end(i64 1
>> call void @helper_no_markers()
>> ; CHECK-NOT: lifetime
>> ; CHECK: ret void
>> @@ -76,3 +79,22 @@
>> ; CHECK: ret void
>> ret void
>> }
>> +
>> +define void @helper_arrays_alloca() {
>> + %a = alloca [10 x i32], align 16
>> + %1 = bitcast [10 x i32]* %a to i8*
>> + call void @use(i8* %1)
>> + ret void
>> +}
>> +
>> +define void @test_arrays_alloca() {
>> +; CHECK: @test_arrays_alloca
>> +; CHECK-NOT: lifetime
>> +; CHECK: llvm.lifetime.start(i64 40,
>> +; CHECK-NOT: lifetime
>> +; CHECK: llvm.lifetime.end(i64 40,
>> + call void @helper_arrays_alloca()
>> +; CHECK-NOT: lifetime
>> +; CHECK: ret void
>> + ret void
>> +}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list