From 2970677f21ef006e6c8477e0c3f58fdd28b2ac03 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 12 Aug 2014 00:05:15 +0000 Subject: [PATCH] Move helper for getting a terminating musttail call to BasicBlock No functional change. To be used in future commits that need to look for such instructions. Reviewed By: rafael Differential Revision: http://reviews.llvm.org/D4504 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215413 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/BasicBlock.h | 9 +++++++ lib/IR/BasicBlock.cpp | 31 ++++++++++++++++++++++ lib/Transforms/Utils/InlineFunction.cpp | 35 ++++--------------------- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index 026c39f0551..7c7dd2ca564 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -23,6 +23,7 @@ namespace llvm { +class CallInst; class LandingPadInst; class TerminatorInst; class LLVMContext; @@ -125,6 +126,14 @@ public: TerminatorInst *getTerminator(); const TerminatorInst *getTerminator() const; + /// \brief Returns the call instruction marked 'musttail' prior to the + /// terminating return instruction of this basic block, if such a call is + /// present. Otherwise, returns null. + CallInst *getTerminatingMustTailCall(); + const CallInst *getTerminatingMustTailCall() const { + return const_cast(this)->getTerminatingMustTailCall(); + } + /// \brief Returns a pointer to the first instruction in this block that is /// not a PHINode instruction. /// diff --git a/lib/IR/BasicBlock.cpp b/lib/IR/BasicBlock.cpp index 1ec977811ce..5ed9bed1baf 100644 --- a/lib/IR/BasicBlock.cpp +++ b/lib/IR/BasicBlock.cpp @@ -138,6 +138,37 @@ const TerminatorInst *BasicBlock::getTerminator() const { return dyn_cast(&InstList.back()); } +CallInst *BasicBlock::getTerminatingMustTailCall() { + if (InstList.empty()) + return nullptr; + ReturnInst *RI = dyn_cast(&InstList.back()); + if (!RI || RI == &InstList.front()) + return nullptr; + + Instruction *Prev = RI->getPrevNode(); + if (!Prev) + return nullptr; + + if (Value *RV = RI->getReturnValue()) { + if (RV != Prev) + return nullptr; + + // Look through the optional bitcast. + if (auto *BI = dyn_cast(Prev)) { + RV = BI->getOperand(0); + Prev = BI->getPrevNode(); + if (!Prev || RV != Prev) + return nullptr; + } + } + + if (auto *CI = dyn_cast(Prev)) { + if (CI->isMustTailCall()) + return CI; + } + return nullptr; +} + Instruction* BasicBlock::getFirstNonPHI() { BasicBlock::iterator i = begin(); // All valid basic blocks should have a terminator, diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index abf7f5ead07..4fa27673ca7 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -755,33 +755,6 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI, } } -/// Returns a musttail call instruction if one immediately precedes the given -/// return instruction with an optional bitcast instruction between them. -static CallInst *getPrecedingMustTailCall(ReturnInst *RI) { - Instruction *Prev = RI->getPrevNode(); - if (!Prev) - return nullptr; - - if (Value *RV = RI->getReturnValue()) { - if (RV != Prev) - return nullptr; - - // Look through the optional bitcast. - if (auto *BI = dyn_cast(Prev)) { - RV = BI->getOperand(0); - Prev = BI->getPrevNode(); - if (!Prev || RV != Prev) - return nullptr; - } - } - - if (auto *CI = dyn_cast(Prev)) { - if (CI->isMustTailCall()) - return CI; - } - return nullptr; -} - /// InlineFunction - This function inlines the called function into the basic /// block of the caller. This returns false if it is not possible to inline /// this call. The program is still in a well defined state if this occurs @@ -1040,7 +1013,8 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, for (ReturnInst *RI : Returns) { // Don't insert llvm.lifetime.end calls between a musttail call and a // return. The return kills all local allocas. - if (InlinedMustTailCalls && getPrecedingMustTailCall(RI)) + if (InlinedMustTailCalls && + RI->getParent()->getTerminatingMustTailCall()) continue; IRBuilder<>(RI).CreateLifetimeEnd(AI, AllocaSize); } @@ -1064,7 +1038,7 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, for (ReturnInst *RI : Returns) { // Don't insert llvm.stackrestore calls between a musttail call and a // return. The return will restore the stack pointer. - if (InlinedMustTailCalls && getPrecedingMustTailCall(RI)) + if (InlinedMustTailCalls && RI->getParent()->getTerminatingMustTailCall()) continue; IRBuilder<>(RI).CreateCall(StackRestore, SavedPtr); } @@ -1087,7 +1061,8 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // Handle the returns preceded by musttail calls separately. SmallVector NormalReturns; for (ReturnInst *RI : Returns) { - CallInst *ReturnedMustTail = getPrecedingMustTailCall(RI); + CallInst *ReturnedMustTail = + RI->getParent()->getTerminatingMustTailCall(); if (!ReturnedMustTail) { NormalReturns.push_back(RI); continue; -- 2.34.1