Skip to content

Commit cafa666

Browse files
committed
Be more aggressive with ObjCARCContract.cpp
If Inst is a retain, we can be more aggressive by checking it
1 parent 21ff15f commit cafa666

File tree

2 files changed

+47
-8
lines changed

2 files changed

+47
-8
lines changed

llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,21 @@ static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
243243

244244
// Ok, now we know we have not seen a store yet.
245245

246-
// If Inst is a retain, we don't care about it as it doesn't prevent moving
247-
// the load to the store.
248-
//
249-
// TODO: This is one area where the optimization could be made more
250-
// aggressive.
251-
if (IsRetain(Class))
252-
continue;
246+
// If Inst is a retain, we can be more aggressive by checking if:
247+
// 1. The retain is on an unrelated object (different RC identity root)
248+
// 2. The retain's argument doesn't alias with our load location
249+
// In these cases, we can safely move past the retain.
250+
if (IsRetain(Class)) {
251+
Value *RetainArg = GetArgRCIdentityRoot(Inst);
252+
Value *LoadRoot = GetRCIdentityRoot(Load);
253+
if (RetainArg != LoadRoot && !AA->alias(MemoryLocation::get(Load),
254+
MemoryLocation::getBeforeOrAfter(RetainArg))) {
255+
continue;
256+
}
257+
// If the retain is on the same object or we can't prove no aliasing,
258+
// be conservative and bail out
259+
return nullptr;
260+
}
253261

254262
// See if Inst can write to our load location, if it can not, just ignore
255263
// the instruction.

llvm/test/Transforms/ObjCARC/contract.ll

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ entry:
3232
ret void
3333
}
3434

35-
; Merge objc_retain and objc_autorelease into objc_retainAutorelease.
35+
; Merge objc_retain and objc_autorelease into objc_retainAutoreleasedReturnValue.
3636

3737
; CHECK-LABEL: define void @test2(
3838
; CHECK: tail call ptr @llvm.objc.retainAutorelease(ptr %x) [[NUW:#[0-9]+]]
@@ -238,3 +238,34 @@ declare void @llvm.objc.clang.arc.use(...) nounwind
238238
declare void @llvm.objc.clang.arc.noop.use(...) nounwind
239239

240240
; CHECK: attributes [[NUW]] = { nounwind }
241+
242+
; CHECK-LABEL: define void @test_aggressive_retain_opt(
243+
; CHECK: tail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %p)
244+
; CHECK: }
245+
define void @test_aggressive_retain_opt() {
246+
%p = call ptr @returner()
247+
%unrelated = call ptr @returner()
248+
tail call ptr @llvm.objc.retain(ptr %unrelated) nounwind
249+
tail call ptr @llvm.objc.retain(ptr %p) nounwind
250+
ret void
251+
}
252+
253+
; CHECK-LABEL: define void @test_aggressive_retain_opt_alias(
254+
; CHECK: tail call ptr @llvm.objc.retain(ptr %p)
255+
; CHECK: }
256+
define void @test_aggressive_retain_opt_alias(ptr %p, ptr %q) {
257+
store ptr %p, ptr %q
258+
tail call ptr @llvm.objc.retain(ptr %p) nounwind
259+
ret void
260+
}
261+
262+
; CHECK-LABEL: define void @test_aggressive_retain_opt_no_alias(
263+
; CHECK: tail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %p)
264+
; CHECK: }
265+
define void @test_aggressive_retain_opt_no_alias() {
266+
%p = call ptr @returner()
267+
%q = alloca ptr
268+
store ptr null, ptr %q
269+
tail call ptr @llvm.objc.retain(ptr %p) nounwind
270+
ret void
271+
}

0 commit comments

Comments
 (0)