summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
commit706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch)
tree4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
parent7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff)
Notes
Diffstat (limited to 'llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp')
-rw-r--r--llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
index 0d2f6f99ca96..1ff4e7cbd8fb 100644
--- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -12,14 +12,16 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
+#include "llvm/Analysis/ObjCARCInstKind.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
+#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
@@ -56,6 +58,17 @@ static bool lowerLoadRelative(Function &F) {
return Changed;
}
+// ObjCARC has knowledge about whether an obj-c runtime function needs to be
+// always tail-called or never tail-called.
+static CallInst::TailCallKind getOverridingTailCallKind(const Function &F) {
+ objcarc::ARCInstKind Kind = objcarc::GetFunctionClass(&F);
+ if (objcarc::IsAlwaysTail(Kind))
+ return CallInst::TCK_Tail;
+ else if (objcarc::IsNeverTail(Kind))
+ return CallInst::TCK_NoTail;
+ return CallInst::TCK_None;
+}
+
static bool lowerObjCCall(Function &F, const char *NewFn,
bool setNonLazyBind = false) {
if (F.use_empty())
@@ -75,6 +88,8 @@ static bool lowerObjCCall(Function &F, const char *NewFn,
}
}
+ CallInst::TailCallKind OverridingTCK = getOverridingTailCallKind(F);
+
for (auto I = F.use_begin(), E = F.use_end(); I != E;) {
auto *CI = cast<CallInst>(I->getUser());
assert(CI->getCalledFunction() && "Cannot lower an indirect call!");
@@ -84,7 +99,17 @@ static bool lowerObjCCall(Function &F, const char *NewFn,
SmallVector<Value *, 8> Args(CI->arg_begin(), CI->arg_end());
CallInst *NewCI = Builder.CreateCall(FCache, Args);
NewCI->setName(CI->getName());
- NewCI->setTailCallKind(CI->getTailCallKind());
+
+ // Try to set the most appropriate TailCallKind based on both the current
+ // attributes and the ones that we could get from ObjCARC's special
+ // knowledge of the runtime functions.
+ //
+ // std::max respects both requirements of notail and tail here:
+ // * notail on either the call or from ObjCARC becomes notail
+ // * tail on either side is stronger than none, but not notail
+ CallInst::TailCallKind TCK = CI->getTailCallKind();
+ NewCI->setTailCallKind(std::max(TCK, OverridingTCK));
+
if (!CI->use_empty())
CI->replaceAllUsesWith(NewCI);
CI->eraseFromParent();