PR2731: C and Ocaml bindings for setTailCall and isTailCall.
authorGordon Henriksen <gordonhenriksen@mac.com>
Sat, 30 Aug 2008 16:34:54 +0000 (16:34 +0000)
committerGordon Henriksen <gordonhenriksen@mac.com>
Sat, 30 Aug 2008 16:34:54 +0000 (16:34 +0000)
Based on patch by Giorgos Korfiatis.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55570 91177308-0d34-0410-b5e6-96231b3b80d8

bindings/ocaml/llvm/llvm.ml
bindings/ocaml/llvm/llvm.mli
bindings/ocaml/llvm/llvm_ocaml.c
include/llvm-c/Core.h
lib/VMCore/Core.cpp
test/Bindings/Ocaml/vmcore.ml

index ded6380..18e1417 100644 (file)
@@ -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"
index fc2919e..d9fb11e 100644 (file)
@@ -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} *)
 
index f09d6cd..35cd7d2 100644 (file)
@@ -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 */
index 9ff1251..3094431 100644 (file)
@@ -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);
index 8517a41..2fedc1e 100644 (file)
@@ -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,
index 4dc1965..6945908 100644 (file)
@@ -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);