diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp')
-rw-r--r-- | llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp | 29 |
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(); |