forked from OSchip/llvm-project
[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:
parent
53a0d45db6
commit
874b0a0b9d
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue