Skip to content

Commit 708c460

Browse files
committed
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 llvm-svn: 368945
1 parent 1c705d9 commit 708c460

File tree

4 files changed

+61
-3
lines changed

4 files changed

+61
-3
lines changed

llvm/include/llvm-c/Core.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,13 @@ enum {
452452

453453
typedef unsigned LLVMAttributeIndex;
454454

455+
typedef enum {
456+
LLVMTailCallKindNone,
457+
LLVMTailCallKindTail,
458+
LLVMTailCallKindMustTail,
459+
LLVMTailCallKindNoTail
460+
} LLVMTailCallKind;
461+
455462
/**
456463
* @}
457464
*/
@@ -3263,6 +3270,24 @@ LLVMBool LLVMIsTailCall(LLVMValueRef CallInst);
32633270
*/
32643271
void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall);
32653272

3273+
/**
3274+
* Obtains the kind of tail call for a call instruction.
3275+
*
3276+
* This only works on llvm::CallInst instructions.
3277+
*
3278+
* @see llvm::CallInst::getTailCallKind()
3279+
*/
3280+
LLVMTailCallKind LLVMGetTailCallKind(LLVMValueRef CallInst);
3281+
3282+
/**
3283+
* Set the kind of tail call for a call instruction.
3284+
*
3285+
* This only works on llvm::CallInst instructions.
3286+
*
3287+
* @see llvm::CallInst::setTailCallKind()
3288+
*/
3289+
void LLVMSetTailCallKind(LLVMValueRef CallInst, LLVMTailCallKind TCK);
3290+
32663291
/**
32673292
* Return the normal destination basic block.
32683293
*

llvm/lib/IR/Core.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2844,6 +2844,39 @@ void LLVMSetTailCall(LLVMValueRef Call, LLVMBool isTailCall) {
28442844
unwrap<CallInst>(Call)->setTailCall(isTailCall);
28452845
}
28462846

2847+
LLVMTailCallKind LLVMGetTailCallKind(LLVMValueRef Call) {
2848+
switch (unwrap<CallInst>(Call)->getTailCallKind()) {
2849+
case CallInst::TailCallKind::TCK_None:
2850+
return LLVMTailCallKindNone;
2851+
case CallInst::TailCallKind::TCK_Tail:
2852+
return LLVMTailCallKindTail;
2853+
case CallInst::TailCallKind::TCK_MustTail:
2854+
return LLVMTailCallKindMustTail;
2855+
case CallInst::TailCallKind::TCK_NoTail:
2856+
return LLVMTailCallKindNoTail;
2857+
}
2858+
}
2859+
2860+
void LLVMSetTailCallKind(LLVMValueRef Call, LLVMTailCallKind TCK) {
2861+
CallInst::TailCallKind kind;
2862+
switch (TCK) {
2863+
case LLVMTailCallKindNone:
2864+
kind = CallInst::TailCallKind::TCK_None;
2865+
break;
2866+
case LLVMTailCallKindTail:
2867+
kind = CallInst::TailCallKind::TCK_Tail;
2868+
break;
2869+
case LLVMTailCallKindMustTail:
2870+
kind = CallInst::TailCallKind::TCK_MustTail;
2871+
break;
2872+
case LLVMTailCallKindNoTail:
2873+
kind = CallInst::TailCallKind::TCK_NoTail;
2874+
break;
2875+
}
2876+
2877+
unwrap<CallInst>(Call)->setTailCallKind(kind);
2878+
}
2879+
28472880
/*--.. Operations on invoke instructions (only) ............................--*/
28482881

28492882
LLVMBasicBlockRef LLVMGetNormalDest(LLVMValueRef Invoke) {

llvm/test/Bindings/llvm-c/invoke.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ catch: ; preds = %unwind5, %unwind3,
5555
ret i32 %merge
5656

5757
unwind3: ; preds = %landingPad
58-
%8 = tail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Exception__ClassInfo to i8*))
58+
%8 = musttail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Exception__ClassInfo to i8*))
5959
%9 = icmp eq i32 %8, %5
6060
br i1 %9, label %catch, label %unwind5
6161

6262
unwind5: ; preds = %unwind3
63-
%10 = tail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Throwable__ClassInfo to i8*))
63+
%10 = notail call i32 @llvm.eh.typeid.for(i8* nonnull bitcast (%C6object9ClassInfo* @C6object9Throwable__ClassInfo to i8*))
6464
%11 = icmp eq i32 %10, %5
6565
br i1 %11, label %catch, label %unwind7
6666

llvm/tools/llvm-c-test/echo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ struct FunCloner {
643643
Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
644644
LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
645645
Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
646-
LLVMSetTailCall(Dst, LLVMIsTailCall(Src));
646+
LLVMSetTailCallKind(Dst, LLVMGetTailCallKind(Src));
647647
CloneAttrs(Src, Dst);
648648
break;
649649
}

0 commit comments

Comments
 (0)