llvm.org GIT mirror llvm / 1ca4f6f
[DSE] Enable removal of lifetime intrinsics in terminating blocks Usually DSE is not supposed to remove lifetime intrinsics, but it's actually ok to remove them for dead objects in terminating blocks, because they convey no extra information there. Until we hit a lifetime start that cannot be removed, that is. Because from that point on the lifetime intrinsics become interesting again, e.g. for stack coloring. Reviewers: reames Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D11710 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245542 91177308-0d34-0410-b5e6-96231b3b80d8 Bjorn Steinbrink 4 years ago
2 changed file(s) with 81 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
787787
788788 const DataLayout &DL = BB.getModule()->getDataLayout();
789789
790 // becomes false once lifetime intrinsics are observable or useful for stack
791 // coloring
792 bool canRemoveLifetimeIntrinsics = true;
793
790794 // Scan the basic block backwards
791795 for (BasicBlock::iterator BBI = BB.end(); BBI != BB.begin(); ){
792796 --BBI;
793797
794 // If we find a store, check to see if it points into a dead stack value.
795 if (hasMemoryWrite(BBI, *TLI) && isRemovable(BBI)) {
798 Value *V = nullptr;
799 if (canRemoveLifetimeIntrinsics)
800 if (IntrinsicInst *II = dyn_cast(BBI))
801 switch (II->getIntrinsicID()) {
802 default: break;
803 case Intrinsic::lifetime_start:
804 case Intrinsic::lifetime_end:
805 V = II->getArgOperand(1);
806 break;
807 }
808
809 if (!V && hasMemoryWrite(BBI, *TLI) && isRemovable(BBI))
810 V = getStoredPointerOperand(BBI);
811
812 // If we found a store, check to see if it points into a dead stack value.
813 if (V) {
796814 // See through pointer-to-pointer bitcasts
797815 SmallVector Pointers;
798 GetUnderlyingObjects(getStoredPointerOperand(BBI), Pointers, DL);
816 GetUnderlyingObjects(V, Pointers, DL);
799817
800818 // Stores to stack values are valid candidates for removal.
801819 bool AllDead = true;
842860 DeadStackObjects.remove(BBI);
843861 continue;
844862 }
863
864 if (IntrinsicInst *II = dyn_cast(BBI))
865 if (II->getIntrinsicID() == Intrinsic::lifetime_start) {
866 // We found a lifetime start for a live object, which we could not
867 // remove. So we must stop removing lifetime intrinsics from this block
868 // because they're useful for stack coloring again
869 canRemoveLifetimeIntrinsics = false;
870 continue;
871 }
845872
846873 if (auto CS = CallSite(BBI)) {
847874 // Remove allocation function calls from the list of dead stack objects;
44 declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind
55 declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind
66 declare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i32, i1) nounwind
7 declare void @callee(i8*)
78
89 define void @test1() {
910 ; CHECK-LABEL: @test1(
1011 %A = alloca i8
1112
1213 store i8 0, i8* %A ;; Written to by memset
14 ; CHECK-NOT: store
1315 call void @llvm.lifetime.end(i64 1, i8* %A)
14 ; CHECK: lifetime.end
16 ; CHECK-NOT: lifetime.end
1517
1618 call void @llvm.memset.p0i8.i8(i8* %A, i8 0, i8 -1, i32 0, i1 false)
1719 ; CHECK-NOT: memset
2123 }
2224
2325 define void @test2(i32* %P) {
24 ; CHECK: test2
26 ; CHECK-LABEL: test2
2527 %Q = getelementptr i32, i32* %P, i32 1
2628 %R = bitcast i32* %Q to i8*
2729 call void @llvm.lifetime.start(i64 4, i8* %R)
3335 ret void
3436 }
3537
38 define void @test3(i8*) {
39 ; CHECK-LABEL: test3
40 %a = alloca i8
41 call void @llvm.lifetime.start(i64 1, i8* %a)
42 ; CHECK-NOT: lifetime.start
43 call void @llvm.lifetime.end(i64 1, i8* %a)
44 ; CHECK-NOT: lifetime.end
45 call void @llvm.lifetime.start(i64 1, i8* undef)
46 ; CHECK-NOT: lifetime.start
47 call void @llvm.lifetime.end(i64 1, i8* undef)
48 ; CHECK-NOT: lifetime.end
49 ret void
50 }
3651
52 define void @test4(i8*) {
53 ; CHECK-LABEL: test4
54 %a = alloca i8
55 call void @llvm.lifetime.start(i64 1, i8* %a)
56 ; CHECK: lifetime.start
57 call void @llvm.lifetime.end(i64 1, i8* %a)
58 ; CHECK: lifetime.end
59 call void @llvm.lifetime.start(i64 1, i8* %0)
60 ; CHECK: lifetime.start
61 call void @llvm.lifetime.end(i64 1, i8* %0)
62 ; CHECK: lifetime.end
63 call void @llvm.lifetime.start(i64 1, i8* %a)
64 ; CHECK-NOT: lifetime.start
65 call void @llvm.lifetime.end(i64 1, i8* %a)
66 ; CHECK-NOT: lifetime.end
67 ret void
68 }
69
70 define void @test5() {
71 ; CHECK-LABEL: test5
72 %a = alloca i8
73 %b = alloca i8
74 call void @llvm.lifetime.start(i64 1, i8* %a)
75 ; CHECK: lifetime.start
76 call void @llvm.lifetime.end(i64 1, i8* %a)
77 ; CHECK: lifetime.end
78 call void @llvm.lifetime.start(i64 1, i8* %b)
79 ; CHECK: lifetime.start
80 call void @callee(i8* %b)
81 ; CHECK: call void @callee
82 call void @llvm.lifetime.end(i64 1, i8* %b)
83 ; CHECK-NOT: lifetime.end
84 ret void
85 }