ahatanak created this revision.
ahatanak added a reviewer: rjmccall.
ahatanak added a project: clang.
Herald added subscribers: ributzka, jkorous.
ahatanak requested review of this revision.
This enables a method sending an autorelease message to an object and returning 
the object in MRR to avoid adding the object to an autorelease pool if a call 
to `objc_retainAutoreleasedReturnValue` in the caller function accepts the hand 
off of the retain count.

This patch assumes that methods overriding autorelease do not touch anything on 
the stack. I think it's safe to make this assumption since ARC optimizer marks 
calls to `objc_autoreleaseReturnValue` as tail, which wouldn't be correct if an 
overriding method did access something on the stack.

https://github.com/llvm/llvm-project/blob/0ca90eb3350b9e8c606fdf1ca0496e0bf3e330ec/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp#L1035

rdar://problem/50678052


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D91111

Files:
  clang/lib/CodeGen/CGObjC.cpp
  clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m


Index: clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
===================================================================
--- clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
+++ clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
@@ -30,7 +30,7 @@
   // CALLS: {{call.*@objc_allocWithZone}}
   // CALLS: {{call.*@objc_retain}}
   // CALLS: {{call.*@objc_release}}
-  // CALLS: {{call.*@objc_autorelease}}
+  // CALLS: {{tail call.*@objc_autorelease}}
   [NSObject alloc];
   [NSObject allocWithZone:nil];
   [x retain];
@@ -121,7 +121,7 @@
 // call will return i8* which we have to cast to A*
 // CHECK-LABEL: define {{.*}}void @test_autorelease_class_ptr
 A* test_autorelease_class_ptr(B *b) {
-  // CALLS: {{call.*@objc_autorelease}}
+  // CALLS: {{tail call.*@objc_autorelease}}
   // CALLS-NEXT: bitcast i8*
   // CALLS-NEXT: ret
   return [b autorelease];
Index: clang/lib/CodeGen/CGObjC.cpp
===================================================================
--- clang/lib/CodeGen/CGObjC.cpp
+++ clang/lib/CodeGen/CGObjC.cpp
@@ -2221,6 +2221,12 @@
   // Call the function.
   llvm::CallBase *Inst = CGF.EmitCallOrInvoke(fn, value);
 
+  // Mark calls to objc_autorelease as tail on the assumption that methods
+  // overriding autorelease do not touch anything on the stack.
+  if (fnName == "objc_autorelease")
+    if (auto *Call = dyn_cast<llvm::CallInst>(Inst))
+      Call->setTailCall();
+
   // Cast the result back to the original type.
   return CGF.Builder.CreateBitCast(Inst, origType);
 }


Index: clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
===================================================================
--- clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
+++ clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
@@ -30,7 +30,7 @@
   // CALLS: {{call.*@objc_allocWithZone}}
   // CALLS: {{call.*@objc_retain}}
   // CALLS: {{call.*@objc_release}}
-  // CALLS: {{call.*@objc_autorelease}}
+  // CALLS: {{tail call.*@objc_autorelease}}
   [NSObject alloc];
   [NSObject allocWithZone:nil];
   [x retain];
@@ -121,7 +121,7 @@
 // call will return i8* which we have to cast to A*
 // CHECK-LABEL: define {{.*}}void @test_autorelease_class_ptr
 A* test_autorelease_class_ptr(B *b) {
-  // CALLS: {{call.*@objc_autorelease}}
+  // CALLS: {{tail call.*@objc_autorelease}}
   // CALLS-NEXT: bitcast i8*
   // CALLS-NEXT: ret
   return [b autorelease];
Index: clang/lib/CodeGen/CGObjC.cpp
===================================================================
--- clang/lib/CodeGen/CGObjC.cpp
+++ clang/lib/CodeGen/CGObjC.cpp
@@ -2221,6 +2221,12 @@
   // Call the function.
   llvm::CallBase *Inst = CGF.EmitCallOrInvoke(fn, value);
 
+  // Mark calls to objc_autorelease as tail on the assumption that methods
+  // overriding autorelease do not touch anything on the stack.
+  if (fnName == "objc_autorelease")
+    if (auto *Call = dyn_cast<llvm::CallInst>(Inst))
+      Call->setTailCall();
+
   // Cast the result back to the original type.
   return CGF.Builder.CreateBitCast(Inst, origType);
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to