Summary: This exposes `CallInst`'s tail call kind via new `LLVMGetTailCallKind` and `LLVMSetTailCallKind` functions. The motivation for this is to be able to see `musttail` for languages that require mandatory tail calls for correctness. Today only the weaker `LLVMSetTail` is exposed and there is no way to set `GuaranteedTailCallOpt` via the C API.
Reviewers: CodaFi, jyknight, deadalnix, rnk
Reviewed By: CodaFi
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66061
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368945
91177308-0d34-0410-b5e6-
96231b3b80d8
typedef unsigned LLVMAttributeIndex;
+typedef enum {
+ LLVMTailCallKindNone,
+ LLVMTailCallKindTail,
+ LLVMTailCallKindMustTail,
+ LLVMTailCallKindNoTail
+} LLVMTailCallKind;
+
/**
* @}
*/
*/
void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall);
+/**
+ * Obtains the kind of tail call for a call instruction.
+ *
+ * This only works on llvm::CallInst instructions.
+ *
+ * @see llvm::CallInst::getTailCallKind()
+ */
+LLVMTailCallKind LLVMGetTailCallKind(LLVMValueRef CallInst);
+
+/**
+ * Set the kind of tail call for a call instruction.
+ *
+ * This only works on llvm::CallInst instructions.
+ *
+ * @see llvm::CallInst::setTailCallKind()
+ */
+void LLVMSetTailCallKind(LLVMValueRef CallInst, LLVMTailCallKind TCK);
+
/**
* Return the normal destination basic block.
*
unwrap<CallInst>(Call)->setTailCall(isTailCall);
}
+LLVMTailCallKind LLVMGetTailCallKind(LLVMValueRef Call) {
+ switch (unwrap<CallInst>(Call)->getTailCallKind()) {
+ case CallInst::TailCallKind::TCK_None:
+ return LLVMTailCallKindNone;
+ case CallInst::TailCallKind::TCK_Tail:
+ return LLVMTailCallKindTail;
+ case CallInst::TailCallKind::TCK_MustTail:
+ return LLVMTailCallKindMustTail;
+ case CallInst::TailCallKind::TCK_NoTail:
+ return LLVMTailCallKindNoTail;
+ }
+}
+
+void LLVMSetTailCallKind(LLVMValueRef Call, LLVMTailCallKind TCK) {
+ CallInst::TailCallKind kind;
+ switch (TCK) {
+ case LLVMTailCallKindNone:
+ kind = CallInst::TailCallKind::TCK_None;
+ break;
+ case LLVMTailCallKindTail:
+ kind = CallInst::TailCallKind::TCK_Tail;
+ break;
+ case LLVMTailCallKindMustTail:
+ kind = CallInst::TailCallKind::TCK_MustTail;
+ break;
+ case LLVMTailCallKindNoTail:
+ kind = CallInst::TailCallKind::TCK_NoTail;
+ break;
+ }
+
+ unwrap<CallInst>(Call)->setTailCallKind(kind);
+}
+
/*--.. Operations on invoke instructions (only) ............................--*/
LLVMBasicBlockRef LLVMGetNormalDest(LLVMValueRef Invoke) {
ret i32 %merge
unwind3: ; preds = %landingPad
- %8 = tail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Exception__ClassInfo to i8*))
+ %8 = musttail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Exception__ClassInfo to i8*))
%9 = icmp eq i32 %8, %5
br i1 %9, label %catch, label %unwind5
unwind5: ; preds = %unwind3
- %10 = tail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Throwable__ClassInfo to i8*))
+ %10 = notail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Throwable__ClassInfo to i8*))
%11 = icmp eq i32 %10, %5
br i1 %11, label %catch, label %unwind7
Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
- LLVMSetTailCall(Dst, LLVMIsTailCall(Src));
+ LLVMSetTailCallKind(Dst, LLVMGetTailCallKind(Src));
CloneAttrs(Src, Dst);
break;
}