summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2019-03-21 19:59:49 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2019-03-21 19:59:49 +0000
commit65bb3f92bd5f6d1d32dee43904c56f4f73276e62 (patch)
tree5c039ce629b8e7ee218f1a0682b797be53ed10c5 /clang/lib/CodeGen
parent86559dcb8d519863c16f7b210ca583a34194acef (diff)
downloadbcm5719-llvm-65bb3f92bd5f6d1d32dee43904c56f4f73276e62.tar.gz
bcm5719-llvm-65bb3f92bd5f6d1d32dee43904c56f4f73276e62.zip
[CodeGen][ObjC] Annotate calls to objc_retainAutoreleasedReturnValue
with notail on x86-64. On x86-64, the epilogue code inserted before the tail jump blocks the autoreleased return optimization. rdar://problem/38675807 Differential Revision: https://reviews.llvm.org/D59656 llvm-svn: 356705
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp27
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp6
-rw-r--r--clang/lib/CodeGen/TargetInfo.h6
3 files changed, 28 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 561f21afdb1..69ced587957 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1958,10 +1958,10 @@ static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM,
/// Perform an operation having the signature
/// i8* (i8*)
/// where a null input causes a no-op and returns null.
-static llvm::Value *
-emitARCValueOperation(CodeGenFunction &CGF, llvm::Value *value,
- llvm::Type *returnType, llvm::Function *&fn,
- llvm::Intrinsic::ID IntID, bool isTailCall = false) {
+static llvm::Value *emitARCValueOperation(
+ CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType,
+ llvm::Function *&fn, llvm::Intrinsic::ID IntID,
+ llvm::CallInst::TailCallKind tailKind = llvm::CallInst::TCK_None) {
if (isa<llvm::ConstantPointerNull>(value))
return value;
@@ -1976,8 +1976,7 @@ emitARCValueOperation(CodeGenFunction &CGF, llvm::Value *value,
// Call the function.
llvm::CallInst *call = CGF.EmitNounwindRuntimeCall(fn, value);
- if (isTailCall)
- call->setTailCall();
+ call->setTailCallKind(tailKind);
// Cast the result back to the original type.
return CGF.Builder.CreateBitCast(call, origType);
@@ -2187,9 +2186,15 @@ static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF) {
llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
emitAutoreleasedReturnValueMarker(*this);
- return emitARCValueOperation(*this, value, nullptr,
- CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue,
- llvm::Intrinsic::objc_retainAutoreleasedReturnValue);
+ llvm::CallInst::TailCallKind tailKind =
+ CGM.getTargetCodeGenInfo()
+ .shouldSuppressTailCallsOfRetainAutoreleasedReturnValue()
+ ? llvm::CallInst::TCK_NoTail
+ : llvm::CallInst::TCK_None;
+ return emitARCValueOperation(
+ *this, value, nullptr,
+ CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue,
+ llvm::Intrinsic::objc_retainAutoreleasedReturnValue, tailKind);
}
/// Claim a possibly-autoreleased return value at +0. This is only
@@ -2326,7 +2331,7 @@ CodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {
return emitARCValueOperation(*this, value, nullptr,
CGM.getObjCEntrypoints().objc_autoreleaseReturnValue,
llvm::Intrinsic::objc_autoreleaseReturnValue,
- /*isTailCall*/ true);
+ llvm::CallInst::TCK_Tail);
}
/// Do a fused retain/autorelease of the given object.
@@ -2336,7 +2341,7 @@ CodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {
return emitARCValueOperation(*this, value, nullptr,
CGM.getObjCEntrypoints().objc_retainAutoreleaseReturnValue,
llvm::Intrinsic::objc_retainAutoreleaseReturnValue,
- /*isTailCall*/ true);
+ llvm::CallInst::TCK_Tail);
}
/// Do a fused retain/autorelease of the given object.
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 63e991c9370..f48f19966e5 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -2268,6 +2268,12 @@ public:
return static_cast<const X86_64ABIInfo&>(TargetCodeGenInfo::getABIInfo());
}
+ /// Disable tail call on x86-64. The epilogue code before the tail jump blocks
+ /// the autoreleaseRV/retainRV optimization.
+ bool shouldSuppressTailCallsOfRetainAutoreleasedReturnValue() const override {
+ return true;
+ }
+
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
return 7;
}
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index b5d5c1fb300..8a4154030ce 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -156,6 +156,12 @@ public:
return "";
}
+ /// Determine whether a call to objc_retainAutoreleasedReturnValue should be
+ /// marked as 'notail'.
+ virtual bool shouldSuppressTailCallsOfRetainAutoreleasedReturnValue() const {
+ return false;
+ }
+
/// Return a constant used by UBSan as a signature to identify functions
/// possessing type information, or 0 if the platform is unsupported.
virtual llvm::Constant *
OpenPOWER on IntegriCloud