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:
parent
7bf06060fd
commit
a170bfa57d
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user