summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp7
-rw-r--r--llvm/lib/Transforms/ObjCARC/PtrState.cpp1
-rw-r--r--llvm/test/Transforms/ObjCARC/basic.ll117
-rw-r--r--llvm/test/Transforms/ObjCARC/nested.ll10
4 files changed, 67 insertions, 68 deletions
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
index 31c5666b202..a517ffb1e5e 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -1617,11 +1617,8 @@ bool ObjCARCOpt::PairUpRetainsAndReleases(
if (NewRetains.empty()) break;
}
- // If the pointer is known incremented in 1 direction and we do not have
- // MultipleOwners, we can safely remove the retain/releases. Otherwise we need
- // to be known safe in both directions.
- bool UnconditionallySafe = (KnownSafeTD && KnownSafeBU) ||
- ((KnownSafeTD || KnownSafeBU) && !MultipleOwners);
+ // We can only remove pointers if we are known safe in both directions.
+ bool UnconditionallySafe = KnownSafeTD && KnownSafeBU;
if (UnconditionallySafe) {
RetainsToMove.ReverseInsertPts.clear();
ReleasesToMove.ReverseInsertPts.clear();
diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.cpp b/llvm/lib/Transforms/ObjCARC/PtrState.cpp
index d360179fee2..35818961933 100644
--- a/llvm/lib/Transforms/ObjCARC/PtrState.cpp
+++ b/llvm/lib/Transforms/ObjCARC/PtrState.cpp
@@ -221,7 +221,6 @@ bool BottomUpPtrState::HandlePotentialAlterRefCount(Instruction *Inst,
return false;
DEBUG(dbgs() << "CanAlterRefCount: Seq: " << Seq << "; " << *Ptr << "\n");
- ClearKnownPositiveRefCount();
switch (Seq) {
case S_Use:
SetSeq(S_CanRelease);
diff --git a/llvm/test/Transforms/ObjCARC/basic.ll b/llvm/test/Transforms/ObjCARC/basic.ll
index 8bb0244dda8..dc5f0b35337 100644
--- a/llvm/test/Transforms/ObjCARC/basic.ll
+++ b/llvm/test/Transforms/ObjCARC/basic.ll
@@ -900,13 +900,14 @@ entry:
ret i8* %x
}
-; Trivial retain,release pair with intervening call, but it's dominated
-; by another retain - delete!
+; We can not delete this retain, release since we do not have a post-dominating
+; use of the release.
; CHECK-LABEL: define void @test12(
; CHECK-NEXT: entry:
; CHECK-NEXT: @objc_retain(i8* %x)
-; CHECK-NOT: @objc_
+; CHECK-NEXT: @objc_retain
+; CHECK: @objc_release
; CHECK: }
define void @test12(i8* %x, i64 %n) {
entry:
@@ -942,6 +943,8 @@ entry:
; CHECK-NEXT: @objc_retain(i8* %x)
; CHECK-NEXT: @use_pointer
; CHECK-NEXT: @use_pointer
+; CHECK-NEXT: @use_pointer
+; CHECK-NEXT: @objc_release
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @test13b(i8* %x, i64 %n) {
@@ -951,6 +954,8 @@ entry:
call void @use_pointer(i8* %x)
call void @use_pointer(i8* %x)
call void @objc_release(i8* %x) nounwind
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x) nounwind
ret void
}
@@ -984,6 +989,8 @@ entry:
; CHECK-NEXT: @objc_autoreleasePoolPush
; CHECK-NEXT: @use_pointer
; CHECK-NEXT: @use_pointer
+; CHECK-NEXT: @use_pointer
+; CHECK-NEXT: @objc_release
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @test13d(i8* %x, i64 %n) {
@@ -994,17 +1001,22 @@ entry:
call void @use_pointer(i8* %x)
call void @use_pointer(i8* %x)
call void @objc_release(i8* %x) nounwind
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x) nounwind
ret void
}
-; Trivial retain,release pair with intervening call, but it's post-dominated
-; by another release - delete!
+; Trivial retain,release pair with intervening call, and it's post-dominated by
+; another release. But it is not known safe in the top down direction. We can
+; not eliminate it.
; CHECK-LABEL: define void @test14(
; CHECK-NEXT: entry:
+; CHECK-NEXT: @objc_retain
; CHECK-NEXT: @use_pointer
; CHECK-NEXT: @use_pointer
; CHECK-NEXT: @objc_release
+; CHECK-NEXT: @objc_release
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @test14(i8* %x, i64 %n) {
@@ -1073,6 +1085,9 @@ entry:
; CHECK-LABEL: define void @test16a(
; CHECK: @objc_retain(i8* %x)
; CHECK-NOT: @objc
+; CHECK: purple:
+; CHECK: @use_pointer
+; CHECK: @objc_release
; CHECK: }
define void @test16a(i1 %a, i1 %b, i8* %x) {
entry:
@@ -1101,12 +1116,18 @@ blue:
br label %purple
purple:
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x) nounwind
ret void
}
; CHECK-LABEL: define void @test16b(
; CHECK: @objc_retain(i8* %x)
; CHECK-NOT: @objc
+; CHECK: purple:
+; CHECK-NEXT: @use_pointer
+; CHECK-NEXT: @use_pointer
+; CHECK-NEXT: @objc_release
; CHECK: }
define void @test16b(i1 %a, i1 %b, i8* %x) {
entry:
@@ -1135,12 +1156,18 @@ blue:
br label %purple
purple:
+ call void @use_pointer(i8* %x)
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x) nounwind
ret void
}
; CHECK-LABEL: define void @test16c(
; CHECK: @objc_retain(i8* %x)
; CHECK-NOT: @objc
+; CHECK: purple:
+; CHECK: @use_pointer
+; CHECK: @objc_release
; CHECK: }
define void @test16c(i1 %a, i1 %b, i8* %x) {
entry:
@@ -1169,12 +1196,14 @@ blue:
br label %purple
purple:
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
ret void
}
; CHECK-LABEL: define void @test16d(
; CHECK: @objc_retain(i8* %x)
-; CHECK-NOT: @objc
+; CHECK: @objc
; CHECK: }
define void @test16d(i1 %a, i1 %b, i8* %x) {
entry:
@@ -1206,44 +1235,6 @@ purple:
ret void
}
-
-; Retain+release pairs in diamonds, all post-dominated by a release.
-
-; CHECK-LABEL: define void @test17(
-; CHECK-NOT: @objc_
-; CHECK: purple:
-; CHECK: @objc_release
-; CHECK: }
-define void @test17(i1 %a, i1 %b, i8* %x) {
-entry:
- br i1 %a, label %red, label %orange
-
-red:
- call i8* @objc_retain(i8* %x) nounwind
- br label %yellow
-
-orange:
- call i8* @objc_retain(i8* %x) nounwind
- br label %yellow
-
-yellow:
- call void @use_pointer(i8* %x)
- call void @use_pointer(i8* %x)
- br i1 %b, label %green, label %blue
-
-green:
- call void @objc_release(i8* %x) nounwind
- br label %purple
-
-blue:
- call void @objc_release(i8* %x) nounwind
- br label %purple
-
-purple:
- call void @objc_release(i8* %x) nounwind
- ret void
-}
-
; Delete no-ops.
; CHECK-LABEL: define void @test18(
@@ -1936,6 +1927,9 @@ exit: ; preds = %loop
; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
; CHECK-NEXT: call void @use_pointer(i8* %p)
; CHECK-NEXT: call void @use_pointer(i8* %p)
+; CHECK-NEXT: call void @use_pointer(i8* %p)
+; CHECK-NEXT: call void @use_pointer(i8* %p)
+; CHECK-NEXT: call void @objc_release(i8* %p)
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @test42(i8* %p) {
@@ -1946,6 +1940,9 @@ entry:
call void @use_pointer(i8* %p)
call void @use_pointer(i8* %p)
call void @objc_release(i8* %p)
+ call void @use_pointer(i8* %p)
+ call void @use_pointer(i8* %p)
+ call void @objc_release(i8* %p)
ret void
}
@@ -1985,6 +1982,8 @@ entry:
; CHECK-NEXT: call void @use_pointer(i8* %p)
; CHECK-NEXT: call void @use_pointer(i8* %p)
; CHECK-NEXT: call i8* @objc_autoreleasePoolPush()
+; CHECK-NEXT: call void @use_pointer(i8* %p)
+; CHECK-NEXT: call void @objc_release
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @test43b(i8* %p) {
@@ -1996,6 +1995,8 @@ entry:
call void @use_pointer(i8* %p)
call i8* @objc_autoreleasePoolPush()
call void @objc_release(i8* %p)
+ call void @use_pointer(i8* %p)
+ call void @objc_release(i8* %p)
ret void
}
@@ -2260,15 +2261,16 @@ if.end: ; preds = %entry, %if.then
ret void
}
-; When there are adjacent retain+release pairs, the first one is
-; known unnecessary because the presence of the second one means that
-; the first one won't be deleting the object.
+; When there are adjacent retain+release pairs, the first one is known
+; unnecessary because the presence of the second one means that the first one
+; won't be deleting the object.
; CHECK-LABEL: define void @test57(
; CHECK-NEXT: entry:
+; CHECK-NEXT: tail call i8* @objc_retain(i8* %x) [[NUW]]
; CHECK-NEXT: call void @use_pointer(i8* %x)
; CHECK-NEXT: call void @use_pointer(i8* %x)
-; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) [[NUW]]
+; CHECK-NEXT: tail call i8* @objc_retain(i8* %x) [[NUW]]
; CHECK-NEXT: call void @use_pointer(i8* %x)
; CHECK-NEXT: call void @use_pointer(i8* %x)
; CHECK-NEXT: call void @objc_release(i8* %x) [[NUW]]
@@ -2277,6 +2279,7 @@ if.end: ; preds = %entry, %if.then
define void @test57(i8* %x) nounwind {
entry:
call i8* @objc_retain(i8* %x) nounwind
+ call i8* @objc_retain(i8* %x) nounwind
call void @use_pointer(i8* %x)
call void @use_pointer(i8* %x)
call void @objc_release(i8* %x) nounwind
@@ -2292,6 +2295,7 @@ entry:
; CHECK-LABEL: define void @test58(
; CHECK-NEXT: entry:
+; CHECK-NEXT: @objc_retain
; CHECK-NEXT: call void @use_pointer(i8* %x)
; CHECK-NEXT: call void @use_pointer(i8* %x)
; CHECK-NEXT: ret void
@@ -2299,6 +2303,7 @@ entry:
define void @test58(i8* %x) nounwind {
entry:
call i8* @objc_retain(i8* %x) nounwind
+ call i8* @objc_retain(i8* %x) nounwind
call void @use_pointer(i8* %x)
call void @use_pointer(i8* %x)
call void @objc_release(i8* %x) nounwind
@@ -2353,16 +2358,16 @@ define void @test60a() {
; CHECK-LABEL: define void @test60b(
; CHECK: call i8* @objc_retain
; CHECK-NOT: call i8* @objc_retain
-; CHECK-NOT: call i8* @objc_rrelease
+; CHECK-NOT: call i8* @objc_release
; CHECK: }
define void @test60b() {
%t = load i8*, i8** @constptr
%s = load i8*, i8** @something
- call i8* @objc_retain(i8* %s)
- call i8* @objc_retain(i8* %s)
+ call i8* @objc_retain(i8* %t)
+ call i8* @objc_retain(i8* %t)
call void @callee()
- call void @use_pointer(i8* %t)
- call void @objc_release(i8* %s)
+ call void @use_pointer(i8* %s)
+ call void @objc_release(i8* %t)
ret void
}
@@ -2372,10 +2377,10 @@ define void @test60b() {
define void @test60c() {
%t = load i8*, i8** @constptr
%s = load i8*, i8** @something
- call i8* @objc_retain(i8* %s)
+ call i8* @objc_retain(i8* %t)
call void @callee()
- call void @use_pointer(i8* %t)
- call void @objc_release(i8* %s), !clang.imprecise_release !0
+ call void @use_pointer(i8* %s)
+ call void @objc_release(i8* %t), !clang.imprecise_release !0
ret void
}
diff --git a/llvm/test/Transforms/ObjCARC/nested.ll b/llvm/test/Transforms/ObjCARC/nested.ll
index 5ef7d626af7..464426abfb0 100644
--- a/llvm/test/Transforms/ObjCARC/nested.ll
+++ b/llvm/test/Transforms/ObjCARC/nested.ll
@@ -229,7 +229,6 @@ entry:
%items.ptr = alloca [16 x i8*], align 8
%call = call i8* @returner()
%0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
- call void @callee()
%tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
%1 = call i8* @objc_retain(i8* %0) nounwind
@@ -283,13 +282,12 @@ forcoll.empty:
ret void
}
-; TODO: Delete a nested retain+release pair.
-; The optimizer currently can't do this, because isn't isn't sophisticated enough in
-; reasnoning about nesting.
-
+; We handle this now due to the fact that a release just needs a post dominating
+; use.
+;
; CHECK-LABEL: define void @test6(
; CHECK: call i8* @objc_retain
-; CHECK: @objc_retain
+; CHECK-NOT: @objc_retain
; CHECK: }
define void @test6() nounwind {
entry:
OpenPOWER on IntegriCloud