[PATCH] D56235: Teach ObjCARC optimizer about equivalent PHIs when eliminating autoreleaseRV/retainRV pairs
Pete Cooper via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 2 16:54:58 PST 2019
pete created this revision.
pete added a reviewer: ahatanak.
Herald added a subscriber: llvm-commits.
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 patch teaches ObjCARCOpt::OptimizeRetainRVCall to also understand PHI equivalence.
Repository:
rL LLVM
https://reviews.llvm.org/D56235
Files:
lib/Transforms/ObjCARC/ObjCARCOpts.cpp
test/Transforms/ObjCARC/rv.ll
Index: test/Transforms/ObjCARC/rv.ll
===================================================================
--- test/Transforms/ObjCARC/rv.ll
+++ test/Transforms/ObjCARC/rv.ll
@@ -239,6 +239,24 @@
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) {
Index: lib/Transforms/ObjCARC/ObjCARCOpts.cpp
===================================================================
--- lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -600,6 +600,19 @@
}
}
+ // 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);
+
+ for (const Value *ArgUser : ArgUsers)
+ EquivalentArgs.insert(ArgUser);
+ }
+
// 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(),
@@ -608,17 +621,19 @@
do
--I;
while (I != Begin && IsNoopInstruction(&*I));
- if (GetBasicARCInstKind(&*I) == ARCInstKind::AutoreleaseRV &&
- GetArgRCIdentityRoot(&*I) == Arg) {
- Changed = true;
- ++NumPeeps;
+ if (GetBasicARCInstKind(&*I) == ARCInstKind::AutoreleaseRV) {
+ if (EquivalentArgs.count(GetArgRCIdentityRoot(&*I))) {
+ Changed = true;
+ ++NumPeeps;
- LLVM_DEBUG(dbgs() << "Erasing autoreleaseRV,retainRV pair: " << *I << "\n"
- << "Erasing " << *RetainRV << "\n");
+ LLVM_DEBUG(dbgs() << "Erasing autoreleaseRV,retainRV pair: "
+ << *I << "\n"
+ << "Erasing " << *RetainRV << "\n");
- EraseInstruction(&*I);
- EraseInstruction(RetainRV);
- return true;
+ EraseInstruction(&*I);
+ EraseInstruction(RetainRV);
+ return true;
+ }
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D56235.179971.patch
Type: text/x-patch
Size: 2583 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190103/bf794005/attachment.bin>
More information about the llvm-commits
mailing list