Skip to content

Commit

Permalink
Teach ObjCARC optimizer about equivalent PHIs when eliminating autore…
Browse files Browse the repository at this point in the history
…leaseRV/retainRV pairs

OptimizeAutoreleaseRVCall skips optimizing llvm.objc.autoreleaseReturnValue if it
sees a user which is llvm.objc.retainAutoreleasedReturnValue, and if they have
equivalent arguments (either identical or equivalent PHIs). It then assumes that
ObjCARCOpt::OptimizeRetainRVCall will optimize the pair instead.

Trouble is, ObjCARCOpt::OptimizeRetainRVCall doesn't know about equivalent PHIs
so optimizes in a different way and we are left with an unoptimized llvm.objc.autoreleaseReturnValue.

This teaches ObjCARCOpt::OptimizeRetainRVCall to also understand PHI equivalence.

rdar://problem/47005143

Reviewed By: ahatanak

Differential Revision: https://reviews.llvm.org/D56235

llvm-svn: 350284
  • Loading branch information
cooperp committed Jan 3, 2019
1 parent ddc6201 commit 697281d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
13 changes: 12 additions & 1 deletion llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
Expand Up @@ -600,6 +600,17 @@ ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
}
}

// Track PHIs which are equivalent to our Arg.
SmallDenseSet<const Value*, 2> EquivalentArgs;
EquivalentArgs.insert(Arg);

// Add PHIs that are equivalent to Arg to ArgUsers.
if (const PHINode *PN = dyn_cast<PHINode>(Arg)) {
SmallVector<const Value *, 2> ArgUsers;
getEquivalentPHIs(*PN, ArgUsers);
EquivalentArgs.insert(ArgUsers.begin(), ArgUsers.end());
}

// Check for being preceded by an objc_autoreleaseReturnValue on the same
// pointer. In this case, we can delete the pair.
BasicBlock::iterator I = RetainRV->getIterator(),
Expand All @@ -609,7 +620,7 @@ ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
--I;
while (I != Begin && IsNoopInstruction(&*I));
if (GetBasicARCInstKind(&*I) == ARCInstKind::AutoreleaseRV &&
GetArgRCIdentityRoot(&*I) == Arg) {
EquivalentArgs.count(GetArgRCIdentityRoot(&*I))) {
Changed = true;
++NumPeeps;

Expand Down
18 changes: 18 additions & 0 deletions llvm/test/Transforms/ObjCARC/rv.ll
Expand Up @@ -239,6 +239,24 @@ define i8* @test19(i8* %p) {
ret i8* %p
}

; Delete autoreleaseRV+retainRV pairs when they have equivalent PHIs as inputs

; CHECK: define i8* @test19phi(i8* %p) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label %test19bb
; CHECK: test19bb:
; CHECK-NEXT: ret i8* %p
define i8* @test19phi(i8* %p) {
entry:
br label %test19bb
test19bb:
%phi1 = phi i8* [ %p, %entry ]
%phi2 = phi i8* [ %p, %entry ]
call i8* @llvm.objc.autoreleaseReturnValue(i8* %phi1)
call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %phi2)
ret i8* %p
}

; Like test19 but with plain autorelease.

; CHECK: define i8* @test20(i8* %p) {
Expand Down

0 comments on commit 697281d

Please sign in to comment.