[PATCH] D155944: expose get/set tail call kind in the C api

Folkert de Vries via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 21 05:16:21 PDT 2023


folkertdev created this revision.
Herald added a reviewer: deadalnix.
Herald added a subscriber: hiraditya.
Herald added a project: All.
folkertdev requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

adds `LLVMGetTailCallKind` and `LLVMSetTailCallKind` to the public C API

The C api does not currently allow us to force tail calls to be preserved. Guaranteed tail calls are essential for performance in our case. We have found that LLVM optimizations will move calls out of tail position in certain cases.

An alternative api would be to add `LLVMSetMustTail` and `LLVMGetMustTail` (and the same for `notail`, I guess). That would keep the `TailCallKind` enum members private, but is inconsistent with the internal API.

background: I am one of the main contributors to the roc programming language. We use LLVM via the `inkwell` crate, which in turn uses the LLVM C api to construct LLVM modules.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155944

Files:
  llvm/bindings/ocaml/llvm/llvm_ocaml.c
  llvm/include/llvm-c/Core.h
  llvm/lib/IR/Core.cpp
  llvm/tools/llvm-c-test/echo.cpp


Index: llvm/tools/llvm-c-test/echo.cpp
===================================================================
--- llvm/tools/llvm-c-test/echo.cpp
+++ llvm/tools/llvm-c-test/echo.cpp
@@ -737,6 +737,7 @@
         LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));
         Dst = LLVMBuildCall2(Builder, FnTy, Fn, Args.data(), ArgCount, Name);
         LLVMSetTailCall(Dst, LLVMIsTailCall(Src));
+        LLVMSetTailCallKind(Dst, LLVMGetTailCallKind(Src));
         CloneAttrs(Src, Dst);
         break;
       }
Index: llvm/lib/IR/Core.cpp
===================================================================
--- llvm/lib/IR/Core.cpp
+++ llvm/lib/IR/Core.cpp
@@ -2892,10 +2892,18 @@
   return unwrap<CallInst>(Call)->isTailCall();
 }
 
+unsigned LLVMGetTailCallKind(LLVMValueRef Call) {
+  return unwrap<CallInst>(Call)->getTailCallKind();
+}
+
 void LLVMSetTailCall(LLVMValueRef Call, LLVMBool isTailCall) {
   unwrap<CallInst>(Call)->setTailCall(isTailCall);
 }
 
+void LLVMSetTailCallKind(LLVMValueRef Call, unsigned tailCallKind) {
+  unwrap<CallInst>(Call)->setTailCallKind((CallInst::TailCallKind)tailCallKind);
+}
+
 /*--.. Operations on invoke instructions (only) ............................--*/
 
 LLVMBasicBlockRef LLVMGetNormalDest(LLVMValueRef Invoke) {
Index: llvm/include/llvm-c/Core.h
===================================================================
--- llvm/include/llvm-c/Core.h
+++ llvm/include/llvm-c/Core.h
@@ -3420,6 +3420,15 @@
  */
 LLVMBool LLVMIsTailCall(LLVMValueRef CallInst);
 
+/**
+ * Obtain the tail call kind of a call instruction.
+ *
+ * This only works on llvm::CallInst instructions.
+ *
+ * @see llvm::CallInst::getTailCallKind()
+ */
+unsigned LLVMGetTailCallKind(LLVMValueRef CallInst);
+
 /**
  * Set whether a call instruction is a tail call.
  *
@@ -3429,6 +3438,15 @@
  */
 void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall);
 
+/**
+ * Set the tail call kind of a call instruction.
+ *
+ * This only works on llvm::CallInst instructions.
+ *
+ * @see llvm::CallInst::setTailCallKind()
+ */
+void LLVMSetTailCallKind(LLVMValueRef CallInst, unsigned TailCallKind);
+
 /**
  * Return the normal destination basic block.
  *
Index: llvm/bindings/ocaml/llvm/llvm_ocaml.c
===================================================================
--- llvm/bindings/ocaml/llvm/llvm_ocaml.c
+++ llvm/bindings/ocaml/llvm/llvm_ocaml.c
@@ -1975,12 +1975,23 @@
   return Val_bool(LLVMIsTailCall(Value_val(CallInst)));
 }
 
+/* llvalue -> int */
+value llvm_get_tail_call_kind(value CallInst) {
+  return Val_int(LLVMGetTailCallKind(Value_val(CallInst)));
+}
+
 /* bool -> llvalue -> unit */
 value llvm_set_tail_call(value IsTailCall, value CallInst) {
   LLVMSetTailCall(Value_val(CallInst), Bool_val(IsTailCall));
   return Val_unit;
 }
 
+/* int -> llvalue -> unit */
+value llvm_set_tail_call_kind(value tailCallKind, value CallInst) {
+  LLVMSetTailCallKind(Value_val(CallInst), Int_val(tailCallKind));
+  return Val_unit;
+}
+
 /* llvalue -> llbasicblock */
 value llvm_get_normal_dest(value Val) {
   LLVMBasicBlockRef BB = LLVMGetNormalDest(Value_val(Val));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D155944.542867.patch
Type: text/x-patch
Size: 3107 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230721/101a0199/attachment.bin>


More information about the llvm-commits mailing list