]> granicus.if.org Git - llvm/commitdiff
Expose TailCallKind via the LLVM C API
authorRobert Widmann <devteam.codafi@gmail.com>
Wed, 14 Aug 2019 23:54:35 +0000 (23:54 +0000)
committerRobert Widmann <devteam.codafi@gmail.com>
Wed, 14 Aug 2019 23:54:35 +0000 (23:54 +0000)
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
lib/IR/Core.cpp
test/Bindings/llvm-c/invoke.ll
tools/llvm-c-test/echo.cpp

index cac2f297056dcc60acbe6f5519e5134bd9992ba4..00d151c4541689b504cb43fdd0528d4b4bb68da5 100644 (file)
@@ -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.
  *
index b4dc91bc3f3412f88113e7a106ae7274c39fe7f2..4c38bb1a55314e437eadf6de95d53e59045cd77c 100644 (file)
@@ -2844,6 +2844,39 @@ void LLVMSetTailCall(LLVMValueRef Call, LLVMBool isTailCall) {
   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) {
index 613a18de1a80fa3687cbfe7c1ed697f8cbff9852..692282252518b74484f278d7914454d4e9356df6 100644 (file)
@@ -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
 
index 8341b11aa45fc68eff93534028f70c07b7ae08f4..7216aa7f594ccc20d0eb42790887aa5e8158807f 100644 (file)
@@ -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;
       }