[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