[CodeGen] Mark calls to objc_autorelease as tail

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.

rdar://problem/50678052

Differential Revision: https://reviews.llvm.org/D91111
This commit is contained in:
Akira Hatanaka 2020-11-10 13:46:53 -08:00
parent 53a0d45db6
commit 874b0a0b9d
2 changed files with 8 additions and 2 deletions

View File

@ -2221,6 +2221,12 @@ static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
// 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);
}

View File

@ -30,7 +30,7 @@ void test1(id x) {
// 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 @@ A* test_retain_class_ptr(B *b) {
// 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];