summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindings/ocaml/llvm/llvm.ml4
-rw-r--r--bindings/ocaml/llvm/llvm.mli11
-rw-r--r--bindings/ocaml/llvm/llvm_ocaml.c14
-rw-r--r--include/llvm-c/Core.h4
-rw-r--r--lib/VMCore/Core.cpp10
-rw-r--r--test/Bindings/Ocaml/vmcore.ml4
6 files changed, 47 insertions, 0 deletions
diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml
index ded6380549..18e1417393 100644
--- a/bindings/ocaml/llvm/llvm.ml
+++ b/bindings/ocaml/llvm/llvm.ml
@@ -586,6 +586,10 @@ external instruction_call_conv: llvalue -> int
external set_instruction_call_conv: int -> llvalue -> unit
= "llvm_set_instruction_call_conv"
+(*--... Operations on call instructions (only) .............................--*)
+external is_tail_call : llvalue -> bool = "llvm_is_tail_call"
+external set_tail_call : bool -> llvalue -> unit = "llvm_set_tail_call"
+
(*--... Operations on phi nodes ............................................--*)
external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit
= "llvm_add_incoming"
diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli
index fc2919e328..d9fb11e5fe 100644
--- a/bindings/ocaml/llvm/llvm.mli
+++ b/bindings/ocaml/llvm/llvm.mli
@@ -1126,6 +1126,17 @@ external instruction_call_conv: llvalue -> int
external set_instruction_call_conv: int -> llvalue -> unit
= "llvm_set_instruction_call_conv"
+(** {Operations on call instructions (only)} *)
+
+(** [is_tail_call ci] is [true] if the call instruction [ci] is flagged as
+ eligible for tail call optimization, [false] otherwise.
+ See the method [llvm::CallInst::isTailCall]. *)
+external is_tail_call : llvalue -> bool = "llvm_is_tail_call"
+
+(** [set_tail_call tc ci] flags the call instruction [ci] as eligible for tail
+ call optimization if [tc] is [true], clears otherwise.
+ See the method [llvm::CallInst::setTailCall]. *)
+external set_tail_call : bool -> llvalue -> unit = "llvm_set_tail_call"
(** {7 Operations on phi nodes} *)
diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c
index f09d6cd91c..35cd7d2360 100644
--- a/bindings/ocaml/llvm/llvm_ocaml.c
+++ b/bindings/ocaml/llvm/llvm_ocaml.c
@@ -733,6 +733,20 @@ CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) {
return Val_unit;
}
+/*--... Operations on call instructions (only) .............................--*/
+
+/* llvalue -> bool */
+CAMLprim value llvm_is_tail_call(LLVMValueRef CallInst) {
+ return Val_bool(LLVMIsTailCall(CallInst));
+}
+
+/* bool -> llvalue -> unit */
+CAMLprim value llvm_set_tail_call(value IsTailCall,
+ LLVMValueRef CallInst) {
+ LLVMSetTailCall(CallInst, Bool_val(IsTailCall));
+ return Val_unit;
+}
+
/*--... Operations on phi nodes ............................................--*/
/* (llvalue * llbasicblock) -> llvalue -> unit */
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 9ff125199f..3094431af2 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -460,6 +460,10 @@ void LLVMRemoveInstrParamAttr(LLVMValueRef Instr, unsigned index,
void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
unsigned align);
+/* Operations on call instructions (only) */
+int LLVMIsTailCall(LLVMValueRef CallInst);
+void LLVMSetTailCall(LLVMValueRef CallInst, int IsTailCall);
+
/* Operations on phi nodes */
void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
LLVMBasicBlockRef *IncomingBlocks, unsigned Count);
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index 8517a41d7c..2fedc1e3f1 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -963,6 +963,16 @@ void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
ParamAttr::constructAlignmentFromInt(align)));
}
+/*--.. Operations on call instructions (only) ..............................--*/
+
+int LLVMIsTailCall(LLVMValueRef Call) {
+ return unwrap<CallInst>(Call)->isTailCall();
+}
+
+void LLVMSetTailCall(LLVMValueRef Call, int isTailCall) {
+ unwrap<CallInst>(Call)->setTailCall(isTailCall);
+}
+
/*--.. Operations on phi nodes .............................................--*/
void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
diff --git a/test/Bindings/Ocaml/vmcore.ml b/test/Bindings/Ocaml/vmcore.ml
index 4dc196579b..694590885d 100644
--- a/test/Bindings/Ocaml/vmcore.ml
+++ b/test/Bindings/Ocaml/vmcore.ml
@@ -979,11 +979,15 @@ let test_builder () =
* RUN: grep {Inst49.*extractelement.*Vec1.*P2} < %t.ll
* RUN: grep {Inst50.*insertelement.*Vec1.*P1.*P2} < %t.ll
* RUN: grep {Inst51.*shufflevector.*Vec1.*Vec2.*1.*1.*0.*0} < %t.ll
+ * RUN: grep {CallInst.*tail call} < %t.ll
*)
let ci = build_call fn [| p2; p1 |] "CallInst" atentry in
insist (CallConv.c = instruction_call_conv ci);
set_instruction_call_conv 63 ci;
insist (63 = instruction_call_conv ci);
+ insist (not (is_tail_call ci));
+ set_tail_call true ci;
+ insist (is_tail_call ci);
let inst46 = build_icmp Icmp.Eq p1 p2 "Inst46" atentry in
ignore (build_select inst46 p1 p2 "Inst47" atentry);