diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-04-24 20:14:34 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-04-24 20:14:34 +0000 |
commit | 710c1a449dd7bee747ecf9c344a6f6d5461a158d (patch) | |
tree | 112a9b219c12b5a90996ac964c861b3526f25266 /include/llvm | |
parent | 870200a833584ca4e05f5d1258265451d8b871eb (diff) | |
download | llvm-710c1a449dd7bee747ecf9c344a6f6d5461a158d.tar.gz llvm-710c1a449dd7bee747ecf9c344a6f6d5461a158d.tar.bz2 llvm-710c1a449dd7bee747ecf9c344a6f6d5461a158d.tar.xz |
Add 'musttail' marker to call instructions
This is similar to the 'tail' marker, except that it guarantees that
tail call optimization will occur. It also comes with convervative IR
verification rules that ensure that tail call optimization is possible.
Reviewers: nicholas
Differential Revision: http://llvm-reviews.chandlerc.com/D3240
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207143 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
-rw-r--r-- | include/llvm/IR/CallSite.h | 9 | ||||
-rw-r--r-- | include/llvm/IR/Instructions.h | 26 |
2 files changed, 29 insertions, 6 deletions
diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index bdac61a89b..39cb461f09 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -160,6 +160,15 @@ public: /// FunTy *getCaller() const { return (*this)->getParent()->getParent(); } + /// \brief Tests if this is a tail call. Only a CallInst can be a tail call. + bool isTailCall() const { return isCall() && cast<CallInst>->isTailCall(); } + + /// \brief Tests if this call site must be tail call optimized. Only a + /// CallInst can be tail call optimized. + bool isMustTailCall() const { + return isCall() && cast<CallInst>(getInstruction())->isMustTailCall(); + } + #define CALLSITE_DELEGATE_GETTER(METHOD) \ InstrTy *II = getInstruction(); \ return isCall() \ diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 19d451e3de..7d338a68f5 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1279,10 +1279,24 @@ public: ~CallInst(); - bool isTailCall() const { return getSubclassDataFromInstruction() & 1; } + // Note that 'musttail' implies 'tail'. + enum TailCallKind { TCK_None = 0, TCK_Tail = 1, TCK_MustTail = 2 }; + TailCallKind getTailCallKind() const { + return TailCallKind(getSubclassDataFromInstruction() & 3); + } + bool isTailCall() const { + return (getSubclassDataFromInstruction() & 3) != TCK_None; + } + bool isMustTailCall() const { + return (getSubclassDataFromInstruction() & 3) == TCK_MustTail; + } void setTailCall(bool isTC = true) { - setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | - unsigned(isTC)); + setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) | + unsigned(isTC ? TCK_Tail : TCK_None)); + } + void setTailCallKind(TailCallKind TCK) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) | + unsigned(TCK)); } /// Provide fast operand accessors @@ -1316,11 +1330,11 @@ public: /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. CallingConv::ID getCallingConv() const { - return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 1); + return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 2); } void setCallingConv(CallingConv::ID CC) { - setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | - (static_cast<unsigned>(CC) << 1)); + setInstructionSubclassData((getSubclassDataFromInstruction() & 3) | + (static_cast<unsigned>(CC) << 2)); } /// getAttributes - Return the parameter attributes for this call. |