[PATCH] D61808: [ObjC] Replace uses of the argument of a call to objc_autorelease with the result in MRR
Akira Hatanaka via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri May 10 15:30:04 PDT 2019
ahatanak created this revision.
ahatanak added reviewers: pete, rjmccall, erik.pilkington.
ahatanak added a project: LLVM.
Herald added subscribers: dexonsmith, jkorous.
This is needed to enable performing tail-call optimization on calls to `objc_autorelease` in MRR, which enables `objc_autorelease` to perform the retainRV/ autoreleaseRV handshake that keeps the returned object out of the autorelease pool.
With this patch, the backend can tail-call the call to `objc_autorelease` in function `bar` in the code below.
// We currently tail call the call to `objc_autorelease` in `foo`
NSObject *foo(void) {
NSObject *t = [NSObject new];
return [t autorelease];
}
// We currently don't tail-call the call to `objc_autorelease` in `bar` because its result isn't used by the return instruction.
//
// %call = tail call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %0, i8* %1)
// %2 = bitcast i8* %call to %0*
// %3 = tail call i8* @objc_autorelease(i8* %call) #2
// ret %0* %2
NSObject *bar(void) {
NSObject *t = [NSObject new];
[t autorelease];
return t;
}
rdar://problem/50353574
Repository:
rL LLVM
https://reviews.llvm.org/D61808
Files:
lib/Transforms/ObjCARC/ObjCARCContract.cpp
test/Transforms/ObjCARC/contract-replace-arg-use.ll
Index: test/Transforms/ObjCARC/contract-replace-arg-use.ll
===================================================================
--- test/Transforms/ObjCARC/contract-replace-arg-use.ll
+++ test/Transforms/ObjCARC/contract-replace-arg-use.ll
@@ -1,5 +1,6 @@
; RUN: opt -objc-arc-contract -S < %s | FileCheck %s
+%0 = type opaque
declare i8* @llvm.objc.autoreleaseReturnValue(i8*)
declare i8* @foo1()
@@ -44,3 +45,17 @@
%v4 = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* %phival)
ret i32* %retval
}
+
+; CHECK-LABEL: define %0* @testAutoreleaseTailCallMRR(
+; CHECK: %[[V1:.*]] = tail call i8* @objc_autorelease(i8* %
+; CHECK: %[[V2:.*]] = bitcast i8* %[[V1]] to %0*
+; CHECK: ret %0* %[[V2]]
+
+define %0* @testAutoreleaseTailCallMRR() {
+ %call = tail call i8* @foo1()
+ %v0 = bitcast i8* %call to %0*
+ %v1 = tail call i8* @objc_autorelease(i8* %call)
+ ret %0* %v0
+}
+
+declare i8* @objc_autorelease(i8*)
Index: lib/Transforms/ObjCARC/ObjCARCContract.cpp
===================================================================
--- lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -13,6 +13,10 @@
/// This specific file mainly deals with ``contracting'' multiple lower level
/// operations into singular higher level operations through pattern matching.
///
+/// This file also replaces uses of the argument of a call to objc_autorelease
+/// in MRR with the result to enable performing tall-call optimization on the
+/// call when the call result is returned by the calling function.
+///
/// WARNING: This file knows about certain library functions. It recognizes them
/// by name, and hardwires knowledge of their semantics.
///
@@ -535,6 +539,11 @@
Inst->eraseFromParent();
return true;
default:
+ // Replace uses of the argument of a call to objc_autorelease in MRR with
+ // the result to enable performing tail-call optimization on it.
+ if (auto *CI = dyn_cast<CallInst>(Inst))
+ if (Function *Callee = CI->getCalledFunction())
+ return !Callee->getName().equals("objc_autorelease");
return true;
}
}
@@ -767,8 +776,9 @@
Pass *llvm::createObjCARCContractPass() { return new ObjCARCContract(); }
bool ObjCARCContract::doInitialization(Module &M) {
- // If nothing in the Module uses ARC, don't do anything.
- Run = ModuleHasARC(M);
+ // If nothing in the Module uses ARC or calls objc_autorelease in MRR, don't
+ // do anything.
+ Run = ModuleHasARC(M) || M.getNamedValue("objc_autorelease");
if (!Run)
return false;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D61808.199094.patch
Type: text/x-patch
Size: 2558 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190510/8dde4d55/attachment-0001.bin>
More information about the llvm-commits
mailing list