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