Marking the objc_autoreleaseReturnValue and objc_retainAutoreleaseReturnValue
call sites as tail calls unconditionally. While it's theoretically true that
this is just an optimization, it's an optimization that we very much want to
happen even at -O0, or else ARC applications become substantially harder to
debug. See r169796 for the llvm/fast-isel side of things.
rdar://12553082
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169996 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index c90e4ec..deac5f6 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -1725,7 +1725,8 @@
static llvm::Value *emitARCValueOperation(CodeGenFunction &CGF,
llvm::Value *value,
llvm::Constant *&fn,
- StringRef fnName) {
+ StringRef fnName,
+ bool isTailCall = false) {
if (isa<llvm::ConstantPointerNull>(value)) return value;
if (!fn) {
@@ -1742,6 +1743,8 @@
// Call the function.
llvm::CallInst *call = CGF.Builder.CreateCall(fn, value);
call->setDoesNotThrow();
+ if (isTailCall)
+ call->setTailCall();
// Cast the result back to the original type.
return CGF.Builder.CreateBitCast(call, origType);
@@ -2054,7 +2057,8 @@
CodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {
return emitARCValueOperation(*this, value,
CGM.getARCEntrypoints().objc_autoreleaseReturnValue,
- "objc_autoreleaseReturnValue");
+ "objc_autoreleaseReturnValue",
+ /*isTailCall*/ true);
}
/// Do a fused retain/autorelease of the given object.
@@ -2063,7 +2067,8 @@
CodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {
return emitARCValueOperation(*this, value,
CGM.getARCEntrypoints().objc_retainAutoreleaseReturnValue,
- "objc_retainAutoreleaseReturnValue");
+ "objc_retainAutoreleaseReturnValue",
+ /*isTailCall*/ true);
}
/// Do a fused retain/autorelease of the given object.