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
This commit is contained in:
Reid Kleckner 2014-08-12 00:05:15 +00:00
parent 524cd2eb7b
commit 2970677f21
3 changed files with 45 additions and 30 deletions

View File

@ -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<BasicBlock *>(this)->getTerminatingMustTailCall();
}
/// \brief Returns a pointer to the first instruction in this block that is
/// not a PHINode instruction.
///

View File

@ -138,6 +138,37 @@ const TerminatorInst *BasicBlock::getTerminator() const {
return dyn_cast<TerminatorInst>(&InstList.back());
}
CallInst *BasicBlock::getTerminatingMustTailCall() {
if (InstList.empty())
return nullptr;
ReturnInst *RI = dyn_cast<ReturnInst>(&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<BitCastInst>(Prev)) {
RV = BI->getOperand(0);
Prev = BI->getPrevNode();
if (!Prev || RV != Prev)
return nullptr;
}
}
if (auto *CI = dyn_cast<CallInst>(Prev)) {
if (CI->isMustTailCall())
return CI;
}
return nullptr;
}
Instruction* BasicBlock::getFirstNonPHI() {
BasicBlock::iterator i = begin();
// All valid basic blocks should have a terminator,

View File

@ -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<BitCastInst>(Prev)) {
RV = BI->getOperand(0);
Prev = BI->getPrevNode();
if (!Prev || RV != Prev)
return nullptr;
}
}
if (auto *CI = dyn_cast<CallInst>(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<ReturnInst *, 8> NormalReturns;
for (ReturnInst *RI : Returns) {
CallInst *ReturnedMustTail = getPrecedingMustTailCall(RI);
CallInst *ReturnedMustTail =
RI->getParent()->getTerminatingMustTailCall();
if (!ReturnedMustTail) {
NormalReturns.push_back(RI);
continue;