1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

Teach ObjCARC optimizer about equivalent PHIs when eliminating autoreleaseRV/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
This commit is contained in:
Pete Cooper 2019-01-03 01:38:08 +00:00
parent 7bf06060fd
commit a170bfa57d
2 changed files with 30 additions and 1 deletions

View File

@ -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(),
@ -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;

View File

@ -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) {