[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