From de7cabaee5b659eeaa6ba2f8bcd5595f7b7148e9 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Wed, 14 Aug 2019 23:54:35 +0000 Subject: [PATCH] Expose TailCallKind via the LLVM C API 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 --- include/llvm-c/Core.h | 25 +++++++++++++++++++++++++ lib/IR/Core.cpp | 33 +++++++++++++++++++++++++++++++++ test/Bindings/llvm-c/invoke.ll | 4 ++-- tools/llvm-c-test/echo.cpp | 2 +- 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index cac2f297056..00d151c4541 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -452,6 +452,13 @@ enum { typedef unsigned LLVMAttributeIndex; +typedef enum { + LLVMTailCallKindNone, + LLVMTailCallKindTail, + LLVMTailCallKindMustTail, + LLVMTailCallKindNoTail +} LLVMTailCallKind; + /** * @} */ @@ -3263,6 +3270,24 @@ LLVMBool LLVMIsTailCall(LLVMValueRef CallInst); */ 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. * diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index b4dc91bc3f3..4c38bb1a553 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -2844,6 +2844,39 @@ void LLVMSetTailCall(LLVMValueRef Call, LLVMBool isTailCall) { unwrap(Call)->setTailCall(isTailCall); } +LLVMTailCallKind LLVMGetTailCallKind(LLVMValueRef Call) { + switch (unwrap(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(Call)->setTailCallKind(kind); +} + /*--.. Operations on invoke instructions (only) ............................--*/ LLVMBasicBlockRef LLVMGetNormalDest(LLVMValueRef Invoke) { diff --git a/test/Bindings/llvm-c/invoke.ll b/test/Bindings/llvm-c/invoke.ll index 613a18de1a8..69228225251 100644 --- a/test/Bindings/llvm-c/invoke.ll +++ b/test/Bindings/llvm-c/invoke.ll @@ -55,12 +55,12 @@ catch: ; preds = %unwind5, %unwind3, 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 diff --git a/tools/llvm-c-test/echo.cpp b/tools/llvm-c-test/echo.cpp index 8341b11aa45..7216aa7f594 100644 --- a/tools/llvm-c-test/echo.cpp +++ b/tools/llvm-c-test/echo.cpp @@ -643,7 +643,7 @@ struct FunCloner { 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; } -- 2.50.1