[llvm-commits] [PATCH] Try to figure out <size> argument in llvm.lifetime intrinsics

Alexey Samsonov samsonov at google.com
Fri Nov 9 08:56:56 PST 2012


Hi nicholas,

When optimizer inlines a function, it creates llvm.lifetime.start/end intrinsics to mark
the lifetime of static allocations in inlined functions. However, it doesn't set sizes of these
memory objects. This patch tries to guess them using the information stored in AllocaInst.

http://llvm-reviews.chandlerc.com/D110

Files:
  test/Transforms/Inline/lifetime-no-datalayout.ll
  test/Transforms/Inline/lifetime.ll
  lib/Transforms/Utils/InlineFunction.cpp

Index: test/Transforms/Inline/lifetime-no-datalayout.ll
===================================================================
--- /dev/null
+++ test/Transforms/Inline/lifetime-no-datalayout.ll
@@ -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
+}
+
Index: test/Transforms/Inline/lifetime.ll
===================================================================
--- test/Transforms/Inline/lifetime.ll
+++ test/Transforms/Inline/lifetime.ll
@@ -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
+}
Index: lib/Transforms/Utils/InlineFunction.cpp
===================================================================
--- lib/Transforms/Utils/InlineFunction.cpp
+++ lib/Transforms/Utils/InlineFunction.cpp
@@ -668,10 +668,23 @@
       if (hasLifetimeMarkers(AI))
         continue;
 
-      builder.CreateLifetimeStart(AI);
+      // Try to determine the size of the allocation.
+      ConstantInt *AllocaSize = 0;
+      if (ConstantInt *AllocaArraySize =
+          dyn_cast<ConstantInt>(AI->getArraySize())) {
+        if (IFI.TD != 0) {
+          uint64_t SizeValue = AllocaArraySize->getLimitedValue();
+          Type *AllocaType = AI->getAllocatedType();
+          SizeValue *= IFI.TD->getTypeAllocSize(AllocaType);
+          AllocaSize = ConstantInt::get(Type::getInt64Ty(AI->getContext()),
+                                        SizeValue);
+        }
+      }
+
+      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);
       }
     }
   }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D110.1.patch
Type: text/x-patch
Size: 4432 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121109/81417923/attachment.bin>


More information about the llvm-commits mailing list