From 46abf91f7378fb7bb118d66fe6d69b5d3af1e9d5 Mon Sep 17 00:00:00 2001 From: Gordon Henriksen Date: Wed, 26 Sep 2007 20:56:12 +0000 Subject: [PATCH] Added C and Ocaml bindings for functions, basic blocks, and instruction creation. No support yet for instruction introspection. Also eliminated allocas from the Ocaml bindings for portability, and avoided unnecessary casts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42367 91177308-0d34-0410-b5e6-96231b3b80d8 --- Xcode/LLVM.xcodeproj/project.pbxproj | 53 ++ bindings/ocaml/Makefile.ocaml | 2 + bindings/ocaml/bitwriter/Makefile | 1 + bindings/ocaml/llvm/llvm.ml | 202 ++++++- bindings/ocaml/llvm/llvm.mli | 199 ++++++- bindings/ocaml/llvm/llvm_ocaml.c | 817 +++++++++++++++++++++------ include/llvm-c/Core.h | 222 +++++++- include/llvm/CHelpers.h | 10 + lib/VMCore/Core.cpp | 462 ++++++++++++++- test/Bindings/Ocaml/bitwriter.ml | 2 +- test/Bindings/Ocaml/vmcore.ml | 350 +++++++++++- 11 files changed, 2087 insertions(+), 233 deletions(-) diff --git a/Xcode/LLVM.xcodeproj/project.pbxproj b/Xcode/LLVM.xcodeproj/project.pbxproj index 1ae711ab4bd..0763ae32564 100644 --- a/Xcode/LLVM.xcodeproj/project.pbxproj +++ b/Xcode/LLVM.xcodeproj/project.pbxproj @@ -153,6 +153,16 @@ 9FA638EA0C77B252007F12AE /* InlinerPass.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InlinerPass.h; sourceTree = ""; }; 9FA638EB0C77B26B007F12AE /* BasicInliner.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BasicInliner.h; sourceTree = ""; }; 9FA638EC0C77B26B007F12AE /* InlineCost.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InlineCost.h; sourceTree = ""; }; + 9FD3E5710CA0116100E54D15 /* bitwriter_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = bitwriter_ocaml.c; sourceTree = ""; }; + 9FD3E5720CA0116100E54D15 /* llvm_bitwriter.ml */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm_bitwriter.ml; sourceTree = ""; }; + 9FD3E5730CA0116100E54D15 /* llvm_bitwriter.mli */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm_bitwriter.mli; sourceTree = ""; }; + 9FD3E57B0CA0116100E54D15 /* llvm.ml */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm.ml; sourceTree = ""; }; + 9FD3E57C0CA0116100E54D15 /* llvm.mli */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm.mli; sourceTree = ""; }; + 9FD3E57D0CA0116100E54D15 /* llvm_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = llvm_ocaml.c; sourceTree = ""; }; + 9FD3E58D0CA0125F00E54D15 /* BitWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BitWriter.h; sourceTree = ""; }; + 9FD3E58E0CA0125F00E54D15 /* Core.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Core.h; sourceTree = ""; }; + 9FD3E5900CA0129D00E54D15 /* Core.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Core.cpp; path = ../lib/VMCore/Core.cpp; sourceTree = SOURCE_ROOT; }; + 9FD3E5920CA012B300E54D15 /* BitWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BitWriter.cpp; sourceTree = ""; }; 9FE4508B0C77A77000C4FEA4 /* ARMCodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ARMCodeEmitter.cpp; sourceTree = ""; }; 9FE4508C0C77A77000C4FEA4 /* ARMGenAsmWriter.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenAsmWriter.inc; sourceTree = ""; }; 9FE4508D0C77A77000C4FEA4 /* ARMGenDAGISel.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenDAGISel.inc; sourceTree = ""; }; @@ -1049,6 +1059,7 @@ DE66F2BD08ABF14400323D32 /* tools */, DE816FAC08CFB44C0093BDEF /* utils */, DE66F38D08ABF35C00323D32 /* docs */, + 9FD3E56D0CA0116100E54D15 /* bindings */, DE66F3FD08ABF37000323D32 /* examples */, DE66F38C08ABF35300323D32 /* CREDITS.TXT */, CFD99AA80AFE827B0068D19C /* LICENSE.TXT */, @@ -1079,6 +1090,7 @@ 9F68EB110C77AD2C004AA152 /* Writer */ = { isa = PBXGroup; children = ( + 9FD3E5920CA012B300E54D15 /* BitWriter.cpp */, 9F68EB120C77AD2C004AA152 /* BitcodeWriter.cpp */, 9F68EB130C77AD2C004AA152 /* BitcodeWriterPass.cpp */, 9F68EB250C77AD2C004AA152 /* ValueEnumerator.cpp */, @@ -1145,6 +1157,44 @@ path = IPO; sourceTree = ""; }; + 9FD3E56D0CA0116100E54D15 /* bindings */ = { + isa = PBXGroup; + children = ( + 9FD3E56F0CA0116100E54D15 /* ocaml */, + ); + name = bindings; + path = ../bindings; + sourceTree = SOURCE_ROOT; + }; + 9FD3E56F0CA0116100E54D15 /* ocaml */ = { + isa = PBXGroup; + children = ( + 9FD3E5700CA0116100E54D15 /* bitwriter */, + 9FD3E57A0CA0116100E54D15 /* llvm */, + ); + path = ocaml; + sourceTree = ""; + }; + 9FD3E5700CA0116100E54D15 /* bitwriter */ = { + isa = PBXGroup; + children = ( + 9FD3E5710CA0116100E54D15 /* bitwriter_ocaml.c */, + 9FD3E5720CA0116100E54D15 /* llvm_bitwriter.ml */, + 9FD3E5730CA0116100E54D15 /* llvm_bitwriter.mli */, + ); + path = bitwriter; + sourceTree = ""; + }; + 9FD3E57A0CA0116100E54D15 /* llvm */ = { + isa = PBXGroup; + children = ( + 9FD3E57B0CA0116100E54D15 /* llvm.ml */, + 9FD3E57C0CA0116100E54D15 /* llvm.mli */, + 9FD3E57D0CA0116100E54D15 /* llvm_ocaml.c */, + ); + path = llvm; + sourceTree = ""; + }; 9FE450DE0C77ABE400C4FEA4 /* lib/Archive */ = { isa = PBXGroup; children = ( @@ -1160,6 +1210,8 @@ CF8F1B480B64F7AB00BB4199 /* llvm-c */ = { isa = PBXGroup; children = ( + 9FD3E58D0CA0125F00E54D15 /* BitWriter.h */, + 9FD3E58E0CA0125F00E54D15 /* Core.h */, CF8F1B490B64F7AB00BB4199 /* LinkTimeOptimizer.h */, ); name = "llvm-c"; @@ -1283,6 +1335,7 @@ 9F77937C0C73C4F400551F9C /* ConstantFold.cpp */, 9F77937D0C73C4F400551F9C /* ConstantFold.h */, DE66EC6008ABE86A00323D32 /* Constants.cpp */, + 9FD3E5900CA0129D00E54D15 /* Core.cpp */, DE66EC6108ABE86A00323D32 /* Dominators.cpp */, DE66EC6208ABE86A00323D32 /* Function.cpp */, DE66EC6308ABE86A00323D32 /* Globals.cpp */, diff --git a/bindings/ocaml/Makefile.ocaml b/bindings/ocaml/Makefile.ocaml index 4c65ca8ffc6..8ad085ecad3 100644 --- a/bindings/ocaml/Makefile.ocaml +++ b/bindings/ocaml/Makefile.ocaml @@ -92,6 +92,8 @@ $(ObjDir)/$(LIBRARYNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \ $(OcamlDir)/.dir $(ObjDir)/.dir $(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeader) > $@ +$(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi) + -include $(ObjDir)/$(LIBRARYNAME).ocamldep diff --git a/bindings/ocaml/bitwriter/Makefile b/bindings/ocaml/bitwriter/Makefile index aef41f50092..953ab4c082b 100644 --- a/bindings/ocaml/bitwriter/Makefile +++ b/bindings/ocaml/bitwriter/Makefile @@ -19,5 +19,6 @@ LEVEL := ../../.. LIBRARYNAME := llvm_bitwriter DONT_BUILD_RELINKED := 1 UsedComponents := bitwriter +UsedOcamlInterfaces := llvm include ../Makefile.ocaml diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml index b8a62dcb681..63079f21072 100644 --- a/bindings/ocaml/llvm/llvm.ml +++ b/bindings/ocaml/llvm/llvm.ml @@ -17,6 +17,9 @@ type llmodule type lltype type llvalue +type llbasicblock (* These are actually values, but + benefit from type checking. *) +type llbuilder type type_kind = Void_type @@ -50,6 +53,42 @@ type visibility = | Hidden_visibility | Protected_visibility +let ccc = 0 +let fastcc = 8 +let coldcc = 9 +let x86_stdcallcc = 64 +let x86_fastcallcc = 65 + +type int_predicate = + Icmp_eq +| Icmp_ne +| Icmp_ugt +| Icmp_uge +| Icmp_ult +| Icmp_ule +| Icmp_sgt +| Icmp_sge +| Icmp_slt +| Icmp_sle + +type real_predicate = + Fcmp_false +| Fcmp_oeq +| Fcmp_ogt +| Fcmp_oge +| Fcmp_olt +| Fcmp_ole +| Fcmp_one +| Fcmp_ord +| Fcmp_uno +| Fcmp_ueq +| Fcmp_ugt +| Fcmp_uge +| Fcmp_ult +| Fcmp_ule +| Fcmp_une +| Fcmp_true + (*===-- Modules -----------------------------------------------------------===*) @@ -63,8 +102,11 @@ external dispose_module : llmodule -> unit = "llvm_dispose_module" (* Adds a named type to the module's symbol table. Returns true if successful. If such a name already exists, then no entry is added and returns false. *) -external add_type_name : string -> lltype -> llmodule -> bool - = "llvm_add_type_name" +external define_type_name : string -> lltype -> llmodule -> bool + = "llvm_add_type_name" + +external delete_type_name : string -> llmodule -> unit + = "llvm_delete_type_name" (*===-- Types -------------------------------------------------------------===*) @@ -142,9 +184,9 @@ external set_value_name : string -> llvalue -> unit = "llvm_set_value_name" (*--... Operations on constants of (mostly) any type .......................--*) external is_constant : llvalue -> bool = "llvm_is_constant" -external make_null : lltype -> llvalue = "llvm_make_null" -external make_all_ones : (*int|vec*)lltype -> llvalue = "llvm_make_all_ones" -external make_undef : lltype -> llvalue = "llvm_make_undef" +external make_null : lltype -> llvalue = "LLVMGetNull" +external make_all_ones : (*int|vec*)lltype -> llvalue = "LLVMGetAllOnes" +external make_undef : lltype -> llvalue = "LLVMGetUndef" external is_null : llvalue -> bool = "llvm_is_null" external is_undef : llvalue -> bool = "llvm_is_undef" @@ -183,12 +225,160 @@ external declare_global : lltype -> string -> llmodule -> llvalue external define_global : string -> llvalue -> llmodule -> llvalue = "llvm_define_global" external delete_global : llvalue -> unit = "llvm_delete_global" -external global_initializer : llvalue -> llvalue = "llvm_global_initializer" +external global_initializer : llvalue -> llvalue = "LLVMGetInitializer" external set_initializer : llvalue -> llvalue -> unit = "llvm_set_initializer" external remove_initializer : llvalue -> unit = "llvm_remove_initializer" external is_thread_local : llvalue -> bool = "llvm_is_thread_local" external set_thread_local : bool -> llvalue -> unit = "llvm_set_thread_local" +(*--... Operations on functions ............................................--*) +external declare_function : string -> lltype -> llmodule -> llvalue + = "llvm_declare_function" +external define_function : string -> lltype -> llmodule -> llvalue + = "llvm_define_function" +external delete_function : llvalue -> unit = "llvm_delete_function" +external params : llvalue -> llvalue array = "llvm_params" +external param : llvalue -> int -> llvalue = "llvm_param" +external is_intrinsic : llvalue -> bool = "llvm_is_intrinsic" +external function_call_conv : llvalue -> int = "llvm_function_call_conv" +external set_function_call_conv : int -> llvalue -> unit + = "llvm_set_function_call_conv" + +(* TODO: param attrs *) + +(*--... Operations on basic blocks .........................................--*) +external basic_blocks : llvalue -> llbasicblock array = "llvm_basic_blocks" +external entry_block : llvalue -> llbasicblock = "LLVMGetEntryBasicBlock" +external delete_block : llbasicblock -> unit = "llvm_delete_block" +external append_block : string -> llvalue -> llbasicblock = "llvm_append_block" +external insert_block : string -> llbasicblock -> llbasicblock + = "llvm_insert_block" +external value_of_block : llbasicblock -> llvalue = "LLVMBasicBlockAsValue" +external value_is_block : llvalue -> bool = "llvm_value_is_block" +external block_of_value : llvalue -> llbasicblock = "LLVMValueAsBasicBlock" + + +(*===-- Instruction builders ----------------------------------------------===*) +external builder_before : llvalue -> llbuilder = "llvm_builder_before" +external builder_at_end : llbasicblock -> llbuilder = "llvm_builder_at_end" +external position_before : llvalue -> llbuilder -> unit = "llvm_position_before" +external position_at_end : llbasicblock -> llbuilder -> unit + = "llvm_position_at_end" + +(*--... Terminators ........................................................--*) +external build_ret_void : llbuilder -> llvalue = "llvm_build_ret_void" +external build_ret : llvalue -> llbuilder -> llvalue = "llvm_build_ret" +external build_br : llbasicblock -> llbuilder -> llvalue = "llvm_build_br" +external build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder -> + llvalue = "llvm_build_cond_br" +external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue + = "llvm_build_switch" +external build_invoke : llvalue -> llvalue array -> llbasicblock -> + llbasicblock -> string -> llbuilder -> llvalue + = "llvm_build_invoke_bc" "llvm_build_invoke_nat" +external build_unwind : llbuilder -> llvalue = "llvm_build_unwind" +external build_unreachable : llbuilder -> llvalue = "llvm_build_unreachable" + +(*--... Arithmetic .........................................................--*) +external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_add" +external build_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_sub" +external build_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_mul" +external build_udiv : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_udiv" +external build_sdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_sdiv" +external build_fdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_fdiv" +external build_urem : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_urem" +external build_srem : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_srem" +external build_frem : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_frem" +external build_shl : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_shl" +external build_lshr : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_lshr" +external build_ashr : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_ashr" +external build_and : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_and" +external build_or : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_or" +external build_xor : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_xor" +external build_neg : llvalue -> string -> llbuilder -> llvalue + = "llvm_build_neg" +external build_not : llvalue -> string -> llbuilder -> llvalue + = "llvm_build_not" + +(*--... Memory .............................................................--*) +external build_malloc : lltype -> string -> llbuilder -> llvalue + = "llvm_build_malloc" +external build_array_malloc : lltype -> llvalue -> string -> llbuilder -> + llvalue = "llvm_build_array_malloc" +external build_alloca : lltype -> string -> llbuilder -> llvalue + = "llvm_build_alloca" +external build_array_alloca : lltype -> llvalue -> string -> llbuilder -> + llvalue = "llvm_build_array_alloca" +external build_free : llvalue -> llbuilder -> llvalue = "llvm_build_free" +external build_load : llvalue -> string -> llbuilder -> llvalue + = "llvm_build_load" +external build_store : llvalue -> llvalue -> llbuilder -> llvalue + = "llvm_build_store" +external build_gep : llvalue -> llvalue array -> string -> llbuilder -> llvalue + = "llvm_build_gep" + +(*--... Casts ..............................................................--*) +external build_trunc : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_trunc" +external build_zext : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_zext" +external build_sext : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_sext" +external build_fptoui : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_fptoui" +external build_fptosi : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_fptosi" +external build_uitofp : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_uitofp" +external build_sitofp : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_sitofp" +external build_fptrunc : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_fptrunc" +external build_fpext : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_fpext" +external build_ptrtoint : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_prttoint" +external build_inttoptr : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_inttoptr" +external build_bitcast : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_bitcast" + +(*--... Comparisons ........................................................--*) +external build_icmp : int_predicate -> llvalue -> llvalue -> string -> + llbuilder -> llvalue = "llvm_build_icmp" +external build_fcmp : real_predicate -> llvalue -> llvalue -> string -> + llbuilder -> llvalue = "llvm_build_fcmp" + +(*--... Miscellaneous instructions .........................................--*) +external build_phi : lltype -> string -> llbuilder -> llvalue = "llvm_build_phi" +external build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue + = "llvm_build_call" +external build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder -> + llvalue = "llvm_build_select" +external build_va_arg : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_va_arg" +external build_extractelement : llvalue -> llvalue -> string -> llbuilder -> + llvalue = "llvm_build_extractelement" +external build_insertelement : llvalue -> llvalue -> llvalue -> string -> + llbuilder -> llvalue = "llvm_build_insertelement" +external build_shufflevector : llvalue -> llvalue -> llvalue -> string -> + llbuilder -> llvalue = "llvm_build_shufflevector" + (*===-- Non-Externs -------------------------------------------------------===*) (* These functions are built using the externals, so must be declared late. *) diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli index 0e38ca0ef2f..627594170b2 100644 --- a/bindings/ocaml/llvm/llvm.mli +++ b/bindings/ocaml/llvm/llvm.mli @@ -17,6 +17,9 @@ type llmodule type lltype type llvalue +type llbasicblock (* These are actually values, but + benefit from type checking. *) +type llbuilder type type_kind = Void_type @@ -50,6 +53,42 @@ type visibility = | Hidden_visibility | Protected_visibility +val ccc : int +val fastcc : int +val coldcc : int +val x86_stdcallcc : int +val x86_fastcallcc : int + +type int_predicate = + Icmp_eq +| Icmp_ne +| Icmp_ugt +| Icmp_uge +| Icmp_ult +| Icmp_ule +| Icmp_sgt +| Icmp_sge +| Icmp_slt +| Icmp_sle + +type real_predicate = + Fcmp_false +| Fcmp_oeq +| Fcmp_ogt +| Fcmp_oge +| Fcmp_olt +| Fcmp_ole +| Fcmp_one +| Fcmp_ord +| Fcmp_uno +| Fcmp_ueq +| Fcmp_ugt +| Fcmp_uge +| Fcmp_ult +| Fcmp_ule +| Fcmp_une +| Fcmp_true + (*===-- Modules -----------------------------------------------------------===*) @@ -63,8 +102,11 @@ external dispose_module : llmodule -> unit = "llvm_dispose_module" (* Adds a named type to the module's symbol table. Returns true if successful. If such a name already exists, then no entry is added and returns false. *) -external add_type_name : string -> lltype -> llmodule -> bool - = "llvm_add_type_name" +external define_type_name : string -> lltype -> llmodule -> bool + = "llvm_add_type_name" + +external delete_type_name : string -> llmodule -> unit + = "llvm_delete_type_name" (*===-- Types -------------------------------------------------------------===*) @@ -125,9 +167,9 @@ external set_value_name : string -> llvalue -> unit = "llvm_set_value_name" (*--... Operations on constants of (mostly) any type .......................--*) external is_constant : llvalue -> bool = "llvm_is_constant" -external make_null : lltype -> llvalue = "llvm_make_null" -external make_all_ones : (*int|vec*)lltype -> llvalue = "llvm_make_all_ones" -external make_undef : lltype -> llvalue = "llvm_make_undef" +external make_null : lltype -> llvalue = "LLVMGetNull" +external make_all_ones : (*int|vec*)lltype -> llvalue = "LLVMGetAllOnes" +external make_undef : lltype -> llvalue = "LLVMGetUndef" external is_null : llvalue -> bool = "llvm_is_null" external is_undef : llvalue -> bool = "llvm_is_undef" @@ -166,9 +208,154 @@ external declare_global : lltype -> string -> llmodule -> llvalue external define_global : string -> llvalue -> llmodule -> llvalue = "llvm_define_global" external delete_global : llvalue -> unit = "llvm_delete_global" -external global_initializer : llvalue -> llvalue = "llvm_global_initializer" +external global_initializer : llvalue -> llvalue = "LLVMGetInitializer" external set_initializer : llvalue -> llvalue -> unit = "llvm_set_initializer" external remove_initializer : llvalue -> unit = "llvm_remove_initializer" external is_thread_local : llvalue -> bool = "llvm_is_thread_local" external set_thread_local : bool -> llvalue -> unit = "llvm_set_thread_local" +(*--... Operations on functions ............................................--*) +external declare_function : string -> lltype -> llmodule -> llvalue + = "llvm_declare_function" +external define_function : string -> lltype -> llmodule -> llvalue + = "llvm_define_function" +external delete_function : llvalue -> unit = "llvm_delete_function" +external params : llvalue -> llvalue array = "llvm_params" +external param : llvalue -> int -> llvalue = "llvm_param" +external is_intrinsic : llvalue -> bool = "llvm_is_intrinsic" +external function_call_conv : llvalue -> int = "llvm_function_call_conv" +external set_function_call_conv : int -> llvalue -> unit + = "llvm_set_function_call_conv" + +(*--... Operations on basic blocks .........................................--*) +external basic_blocks : llvalue -> llbasicblock array = "llvm_basic_blocks" +external entry_block : llvalue -> llbasicblock = "LLVMGetEntryBasicBlock" +external delete_block : llbasicblock -> unit = "llvm_delete_block" +external append_block : string -> llvalue -> llbasicblock = "llvm_append_block" +external insert_block : string -> llbasicblock -> llbasicblock + = "llvm_insert_block" +external value_of_block : llbasicblock -> llvalue = "LLVMBasicBlockAsValue" +external value_is_block : llvalue -> bool = "llvm_value_is_block" +external block_of_value : llvalue -> llbasicblock = "LLVMValueAsBasicBlock" + + +(*===-- Instruction builders ----------------------------------------------===*) +external builder_before : llvalue -> llbuilder = "llvm_builder_before" +external builder_at_end : llbasicblock -> llbuilder = "llvm_builder_at_end" +external position_before : llvalue -> llbuilder -> unit = "llvm_position_before" +external position_at_end : llbasicblock -> llbuilder -> unit + = "llvm_position_at_end" + +(*--... Terminators ........................................................--*) +external build_ret_void : llbuilder -> llvalue = "llvm_build_ret_void" +external build_ret : llvalue -> llbuilder -> llvalue = "llvm_build_ret" +external build_br : llbasicblock -> llbuilder -> llvalue = "llvm_build_br" +external build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder -> + llvalue = "llvm_build_cond_br" +external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue + = "llvm_build_switch" +external build_invoke : llvalue -> llvalue array -> llbasicblock -> + llbasicblock -> string -> llbuilder -> llvalue + = "llvm_build_invoke_bc" "llvm_build_invoke_nat" +external build_unwind : llbuilder -> llvalue = "llvm_build_unwind" +external build_unreachable : llbuilder -> llvalue = "llvm_build_unreachable" + +(*--... Arithmetic .........................................................--*) +external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_add" +external build_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_sub" +external build_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_mul" +external build_udiv : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_udiv" +external build_sdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_sdiv" +external build_fdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_fdiv" +external build_urem : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_urem" +external build_srem : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_srem" +external build_frem : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_frem" +external build_shl : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_shl" +external build_lshr : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_lshr" +external build_ashr : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_ashr" +external build_and : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_and" +external build_or : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_or" +external build_xor : llvalue -> llvalue -> string -> llbuilder -> llvalue + = "llvm_build_xor" +external build_neg : llvalue -> string -> llbuilder -> llvalue + = "llvm_build_neg" +external build_not : llvalue -> string -> llbuilder -> llvalue + = "llvm_build_not" + +(*--... Memory .............................................................--*) +external build_malloc : lltype -> string -> llbuilder -> llvalue + = "llvm_build_malloc" +external build_array_malloc : lltype -> llvalue -> string -> llbuilder -> + llvalue = "llvm_build_array_malloc" +external build_alloca : lltype -> string -> llbuilder -> llvalue + = "llvm_build_alloca" +external build_array_alloca : lltype -> llvalue -> string -> llbuilder -> + llvalue = "llvm_build_array_alloca" +external build_free : llvalue -> llbuilder -> llvalue = "llvm_build_free" +external build_load : llvalue -> string -> llbuilder -> llvalue + = "llvm_build_load" +external build_store : llvalue -> llvalue -> llbuilder -> llvalue + = "llvm_build_store" +external build_gep : llvalue -> llvalue array -> string -> llbuilder -> llvalue + = "llvm_build_gep" + +(*--... Casts ..............................................................--*) +external build_trunc : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_trunc" +external build_zext : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_zext" +external build_sext : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_sext" +external build_fptoui : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_fptoui" +external build_fptosi : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_fptosi" +external build_uitofp : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_uitofp" +external build_sitofp : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_sitofp" +external build_fptrunc : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_fptrunc" +external build_fpext : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_fpext" +external build_ptrtoint : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_prttoint" +external build_inttoptr : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_inttoptr" +external build_bitcast : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_bitcast" + +(*--... Comparisons ........................................................--*) +external build_icmp : int_predicate -> llvalue -> llvalue -> string -> + llbuilder -> llvalue = "llvm_build_icmp" +external build_fcmp : real_predicate -> llvalue -> llvalue -> string -> + llbuilder -> llvalue = "llvm_build_fcmp" + +(*--... Miscellaneous instructions .........................................--*) +external build_phi : lltype -> string -> llbuilder -> llvalue = "llvm_build_phi" +external build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue + = "llvm_build_call" +external build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder -> + llvalue = "llvm_build_select" +external build_va_arg : llvalue -> lltype -> string -> llbuilder -> llvalue + = "llvm_build_va_arg" +external build_extractelement : llvalue -> llvalue -> string -> llbuilder -> + llvalue = "llvm_build_extractelement" +external build_insertelement : llvalue -> llvalue -> llvalue -> string -> + llbuilder -> llvalue = "llvm_build_insertelement" +external build_shufflevector : llvalue -> llvalue -> llvalue -> string -> + llbuilder -> llvalue = "llvm_build_shufflevector" diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c index f7356668a26..ffa872da6be 100644 --- a/bindings/ocaml/llvm/llvm_ocaml.c +++ b/bindings/ocaml/llvm/llvm_ocaml.c @@ -17,130 +17,125 @@ #include "llvm-c/Core.h" #include "caml/alloc.h" +#include "caml/custom.h" #include "caml/mlvalues.h" #include "caml/memory.h" #include "llvm/Config/config.h" #include -#ifdef HAVE_ALLOCA_H -#include -#endif +#include /*===-- Modules -----------------------------------------------------------===*/ /* string -> llmodule */ -CAMLprim value llvm_create_module(value ModuleID) { - return (value) LLVMModuleCreateWithName(String_val(ModuleID)); +CAMLprim LLVMModuleRef llvm_create_module(value ModuleID) { + return LLVMModuleCreateWithName(String_val(ModuleID)); } /* llmodule -> unit */ -CAMLprim value llvm_dispose_module(value M) { - LLVMDisposeModule((LLVMModuleRef) M); +CAMLprim value llvm_dispose_module(LLVMModuleRef M) { + LLVMDisposeModule(M); return Val_unit; } /* string -> lltype -> llmodule -> bool */ -CAMLprim value llvm_add_type_name(value Name, value Ty, value M) { - int res = LLVMAddTypeName((LLVMModuleRef) M, - String_val(Name), (LLVMTypeRef) Ty); +CAMLprim value llvm_add_type_name(value Name, LLVMTypeRef Ty, LLVMModuleRef M) { + int res = LLVMAddTypeName(M, String_val(Name), Ty); return Val_bool(res == 0); } +/* string -> llmodule -> unit */ +CAMLprim value llvm_delete_type_name(value Name, LLVMModuleRef M) { + LLVMDeleteTypeName(M, String_val(Name)); + return Val_unit; +} + /*===-- Types -------------------------------------------------------------===*/ /* lltype -> type_kind */ -CAMLprim value llvm_classify_type(value Ty) { - return Val_int(LLVMGetTypeKind((LLVMTypeRef) Ty)); +CAMLprim value llvm_classify_type(LLVMTypeRef Ty) { + return Val_int(LLVMGetTypeKind(Ty)); } /* lltype -> lltype -> unit */ -CAMLprim value llvm_refine_abstract_type(value ConcreteTy, value AbstractTy) { - LLVMRefineAbstractType((LLVMTypeRef) AbstractTy, (LLVMTypeRef) ConcreteTy); - return (value) Val_unit; +CAMLprim value llvm_refine_abstract_type(LLVMTypeRef ConcreteTy, + LLVMTypeRef AbstractTy) { + LLVMRefineAbstractType(AbstractTy, ConcreteTy); + return Val_unit; } /*--... Operations on integer types ........................................--*/ /* unit -> lltype */ -CAMLprim value llvm_i1_type (value Unit) { return (value) LLVMInt1Type(); } -CAMLprim value llvm_i8_type (value Unit) { return (value) LLVMInt8Type(); } -CAMLprim value llvm_i16_type(value Unit) { return (value) LLVMInt16Type(); } -CAMLprim value llvm_i32_type(value Unit) { return (value) LLVMInt32Type(); } -CAMLprim value llvm_i64_type(value Unit) { return (value) LLVMInt64Type(); } +CAMLprim LLVMTypeRef llvm_i1_type (value Unit) { return LLVMInt1Type(); } +CAMLprim LLVMTypeRef llvm_i8_type (value Unit) { return LLVMInt8Type(); } +CAMLprim LLVMTypeRef llvm_i16_type(value Unit) { return LLVMInt16Type(); } +CAMLprim LLVMTypeRef llvm_i32_type(value Unit) { return LLVMInt32Type(); } +CAMLprim LLVMTypeRef llvm_i64_type(value Unit) { return LLVMInt64Type(); } /* int -> lltype */ -CAMLprim value llvm_make_integer_type(value Width) { - return (value) LLVMCreateIntegerType(Int_val(Width)); +CAMLprim LLVMTypeRef llvm_make_integer_type(value Width) { + return LLVMCreateIntType(Int_val(Width)); } /* lltype -> int */ -CAMLprim value llvm_integer_bitwidth(value IntegerTy) { - return Val_int(LLVMGetIntegerTypeWidth((LLVMTypeRef) IntegerTy)); +CAMLprim value llvm_integer_bitwidth(LLVMTypeRef IntegerTy) { + return Val_int(LLVMGetIntTypeWidth(IntegerTy)); } /*--... Operations on real types ...........................................--*/ /* unit -> lltype */ -CAMLprim value llvm_float_type(value Unit) { - return (value) LLVMFloatType(); +CAMLprim LLVMTypeRef llvm_float_type(value Unit) { + return LLVMFloatType(); } /* unit -> lltype */ -CAMLprim value llvm_double_type(value Unit) { - return (value) LLVMDoubleType(); +CAMLprim LLVMTypeRef llvm_double_type(value Unit) { + return LLVMDoubleType(); } /* unit -> lltype */ -CAMLprim value llvm_x86fp80_type(value Unit) { - return (value) LLVMX86FP80Type(); +CAMLprim LLVMTypeRef llvm_x86fp80_type(value Unit) { + return LLVMX86FP80Type(); } /* unit -> lltype */ -CAMLprim value llvm_fp128_type(value Unit) { - return (value) LLVMFP128Type(); +CAMLprim LLVMTypeRef llvm_fp128_type(value Unit) { + return LLVMFP128Type(); } /* unit -> lltype */ -CAMLprim value llvm_ppc_fp128_type(value Unit) { - return (value) LLVMPPCFP128Type(); +CAMLprim LLVMTypeRef llvm_ppc_fp128_type(value Unit) { + return LLVMPPCFP128Type(); } /*--... Operations on function types .......................................--*/ /* lltype -> lltype array -> bool -> lltype */ -CAMLprim value llvm_make_function_type(value RetTy, value ParamTys, - value IsVarArg) { - return (value) LLVMCreateFunctionType((LLVMTypeRef) RetTy, - (LLVMTypeRef *) ParamTys, - Wosize_val(ParamTys), - Bool_val(IsVarArg)); +CAMLprim LLVMTypeRef llvm_make_function_type(LLVMTypeRef RetTy, value ParamTys, + value IsVarArg) { + return LLVMCreateFunctionType(RetTy, (LLVMTypeRef *) ParamTys, + Wosize_val(ParamTys), + Bool_val(IsVarArg)); } /* lltype -> bool */ -CAMLprim value llvm_is_var_arg(value FunTy) { - return Val_bool(LLVMIsFunctionVarArg((LLVMTypeRef) FunTy)); +CAMLprim value llvm_is_var_arg(LLVMTypeRef FunTy) { + return Val_bool(LLVMIsFunctionVarArg(FunTy)); } /* lltype -> lltype */ -CAMLprim value llvm_return_type(value FunTy) { - return (value) LLVMGetFunctionReturnType((LLVMTypeRef) FunTy); +CAMLprim LLVMTypeRef llvm_return_type(LLVMTypeRef FunTy) { + return LLVMGetReturnType(FunTy); } /* lltype -> lltype array */ -CAMLprim value llvm_param_types(value FunTy) { - unsigned Count = LLVMGetFunctionParamCount((LLVMTypeRef) FunTy); - LLVMTypeRef *FunTys = alloca(Count * sizeof(LLVMTypeRef)); - - /* copy into an ocaml array */ - unsigned i; - value ParamTys = alloc(Count, 0); - - LLVMGetFunctionParamTypes((LLVMTypeRef) FunTy, FunTys); - for (i = 0; i != Count; ++i) - Store_field(ParamTys, i, (value) FunTys[i]); - - return ParamTys; +CAMLprim value llvm_param_types(LLVMTypeRef FunTy) { + value Tys = alloc(LLVMCountParamTypes(FunTy), 0); + LLVMGetParamTypes(FunTy, (LLVMTypeRef *) Tys); + return Tys; } /*--... Operations on struct types .........................................--*/ @@ -153,123 +148,101 @@ CAMLprim value llvm_make_struct_type(value ElementTypes, value Packed) { } /* lltype -> lltype array */ -CAMLprim value llvm_element_types(value StructTy) { - unsigned Count = LLVMGetStructElementCount((LLVMTypeRef) StructTy); - LLVMTypeRef *Tys = alloca(Count * sizeof(LLVMTypeRef)); - - /* copy into an ocaml array */ - unsigned i; - value ElementTys = alloc(Count, 0); - - LLVMGetStructElementTypes((LLVMTypeRef) StructTy, Tys); - for (i = 0; i != Count; ++i) - Store_field(ElementTys, i, (value) Tys[i]); - - return ElementTys; +CAMLprim value llvm_element_types(LLVMTypeRef StructTy) { + value Tys = alloc(LLVMCountStructElementTypes(StructTy), 0); + LLVMGetStructElementTypes(StructTy, (LLVMTypeRef *) Tys); + return Tys; } -CAMLprim value llvm_is_packed(value StructTy) { - return Val_bool(LLVMIsPackedStruct((LLVMTypeRef) StructTy)); +/* lltype -> bool */ +CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) { + return Val_bool(LLVMIsPackedStruct(StructTy)); } /*--... Operations on array, pointer, and vector types .....................--*/ /* lltype -> int -> lltype */ -CAMLprim value llvm_make_array_type(value ElementTy, value Count) { - return (value) LLVMCreateArrayType((LLVMTypeRef) ElementTy, Int_val(Count)); +CAMLprim value llvm_make_array_type(LLVMTypeRef ElementTy, value Count) { + return (value) LLVMCreateArrayType(ElementTy, Int_val(Count)); } /* lltype -> lltype */ -CAMLprim value llvm_make_pointer_type(value ElementTy) { - return (value) LLVMCreatePointerType((LLVMTypeRef) ElementTy); +CAMLprim LLVMTypeRef llvm_make_pointer_type(LLVMTypeRef ElementTy) { + return LLVMCreatePointerType(ElementTy); } /* lltype -> int -> lltype */ -CAMLprim value llvm_make_vector_type(value ElementTy, value Count) { - return (value) LLVMCreateVectorType((LLVMTypeRef) ElementTy, Int_val(Count)); +CAMLprim LLVMTypeRef llvm_make_vector_type(LLVMTypeRef ElementTy, value Count) { + return LLVMCreateVectorType(ElementTy, Int_val(Count)); } /* lltype -> lltype */ -CAMLprim value llvm_element_type(value Ty) { - return (value) LLVMGetElementType((LLVMTypeRef) Ty); +CAMLprim LLVMTypeRef llvm_element_type(LLVMTypeRef Ty) { + return LLVMGetElementType(Ty); } /* lltype -> int */ -CAMLprim value llvm_array_length(value ArrayTy) { - return Val_int(LLVMGetArrayLength((LLVMTypeRef) ArrayTy)); +CAMLprim value llvm_array_length(LLVMTypeRef ArrayTy) { + return Val_int(LLVMGetArrayLength(ArrayTy)); } /* lltype -> int */ -CAMLprim value llvm_vector_size(value VectorTy) { - return Val_int(LLVMGetVectorSize((LLVMTypeRef) VectorTy)); +CAMLprim value llvm_vector_size(LLVMTypeRef VectorTy) { + return Val_int(LLVMGetVectorSize(VectorTy)); } /*--... Operations on other types ..........................................--*/ /* unit -> lltype */ -CAMLprim value llvm_void_type (value Unit) { return (value) LLVMVoidType(); } -CAMLprim value llvm_label_type(value Unit) { return (value) LLVMLabelType(); } +CAMLprim LLVMTypeRef llvm_void_type (value Unit) { return LLVMVoidType(); } +CAMLprim LLVMTypeRef llvm_label_type(value Unit) { return LLVMLabelType(); } /* unit -> lltype */ -CAMLprim value llvm_make_opaque_type(value Unit) { - return (value) LLVMCreateOpaqueType(); +CAMLprim LLVMTypeRef llvm_make_opaque_type(value Unit) { + return LLVMCreateOpaqueType(); } /*===-- VALUES ------------------------------------------------------------===*/ /* llvalue -> lltype */ -CAMLprim value llvm_type_of(value Val) { - return (value) LLVMGetTypeOfValue((LLVMValueRef) Val); +CAMLprim LLVMTypeRef llvm_type_of(LLVMValueRef Val) { + return LLVMTypeOf(Val); } /* llvalue -> string */ -CAMLprim value llvm_value_name(value Val) { - return copy_string(LLVMGetValueName((LLVMValueRef) Val)); +CAMLprim value llvm_value_name(LLVMValueRef Val) { + return copy_string(LLVMGetValueName(Val)); } /* string -> llvalue -> unit */ -CAMLprim value llvm_set_value_name(value Name, value Val) { - LLVMSetValueName((LLVMValueRef) Val, String_val(Name)); +CAMLprim value llvm_set_value_name(value Name, LLVMValueRef Val) { + LLVMSetValueName(Val, String_val(Name)); return Val_unit; } /*--... Operations on constants of (mostly) any type .......................--*/ -/* lltype -> llvalue */ -CAMLprim value llvm_make_null(value Ty) { - return (value) LLVMGetNull((LLVMTypeRef) Ty); -} - -/* lltype -> llvalue */ -CAMLprim value llvm_make_all_ones(value Ty) { - return (value) LLVMGetAllOnes((LLVMTypeRef) Ty); -} - -/* lltype -> llvalue */ -CAMLprim value llvm_make_undef(value Ty) { - return (value) LLVMGetUndef((LLVMTypeRef) Ty); -} - /* llvalue -> bool */ -CAMLprim value llvm_is_constant(value Ty) { - return Val_bool(LLVMIsConstant((LLVMValueRef) Ty)); +CAMLprim value llvm_is_constant(LLVMValueRef Val) { + return Val_bool(LLVMIsConstant(Val)); } /* llvalue -> bool */ -CAMLprim value llvm_is_null(value Val) { - return Val_bool(LLVMIsNull((LLVMValueRef) Val)); +CAMLprim value llvm_is_null(LLVMValueRef Val) { + return Val_bool(LLVMIsNull(Val)); } /* llvalue -> bool */ -CAMLprim value llvm_is_undef(value Ty) { - return Val_bool(LLVMIsUndef((LLVMValueRef) Ty)); +CAMLprim value llvm_is_undef(LLVMValueRef Val) { + return Val_bool(LLVMIsUndef(Val)); } /*--... Operations on scalar constants .....................................--*/ /* lltype -> int -> bool -> llvalue */ -CAMLprim value llvm_make_int_constant(value IntTy, value N, value SExt) { +CAMLprim LLVMValueRef llvm_make_int_constant(LLVMTypeRef IntTy, value N, + value SExt) { /* GCC warns if we use the ternary operator. */ unsigned long long N2; if (Bool_val(SExt)) @@ -277,41 +250,40 @@ CAMLprim value llvm_make_int_constant(value IntTy, value N, value SExt) { else N2 = (mlsize_t) Int_val(N); - return (value) LLVMGetIntConstant((LLVMTypeRef) IntTy, N2, Bool_val(SExt)); + return LLVMGetIntConstant(IntTy, N2, Bool_val(SExt)); } /* lltype -> Int64.t -> bool -> llvalue */ -CAMLprim value llvm_make_int64_constant(value IntTy, value N, value SExt) { - return (value) LLVMGetIntConstant((LLVMTypeRef) IntTy, Int64_val(N), - Bool_val(SExt)); +CAMLprim LLVMValueRef llvm_make_int64_constant(LLVMTypeRef IntTy, value N, + value SExt) { + return LLVMGetIntConstant(IntTy, Int64_val(N), Bool_val(SExt)); } /* lltype -> float -> llvalue */ -CAMLprim value llvm_make_real_constant(value RealTy, value N) { - return (value) LLVMGetRealConstant((LLVMTypeRef) RealTy, Double_val(N)); +CAMLprim LLVMValueRef llvm_make_real_constant(LLVMTypeRef RealTy, value N) { + return LLVMGetRealConstant(RealTy, Double_val(N)); } /*--... Operations on composite constants ..................................--*/ /* string -> bool -> llvalue */ -CAMLprim value llvm_make_string_constant(value Str, value NullTerminate) { - return (value) LLVMGetStringConstant(String_val(Str), - string_length(Str), - Bool_val(NullTerminate) == 0); +CAMLprim LLVMValueRef llvm_make_string_constant(value Str, value NullTerminate) { + return LLVMGetStringConstant(String_val(Str), string_length(Str), + Bool_val(NullTerminate) == 0); } /* lltype -> llvalue array -> llvalue */ -CAMLprim value llvm_make_array_constant(value ElementTy, value ElementVals) { - return (value) LLVMGetArrayConstant((LLVMTypeRef) ElementTy, - (LLVMValueRef*) Op_val(ElementVals), - Wosize_val(ElementVals)); +CAMLprim LLVMValueRef llvm_make_array_constant(LLVMTypeRef ElementTy, + value ElementVals) { + return LLVMGetArrayConstant(ElementTy, (LLVMValueRef*) Op_val(ElementVals), + Wosize_val(ElementVals)); } /* llvalue array -> bool -> llvalue */ -CAMLprim value llvm_make_struct_constant(value ElementVals, value Packed) { - return (value) LLVMGetStructConstant((LLVMValueRef*) Op_val(ElementVals), - Wosize_val(ElementVals), - Bool_val(Packed)); +CAMLprim LLVMValueRef llvm_make_struct_constant(value ElementVals, + value Packed) { + return LLVMGetStructConstant((LLVMValueRef *) Op_val(ElementVals), + Wosize_val(ElementVals), Bool_val(Packed)); } /* llvalue array -> llvalue */ @@ -323,108 +295,591 @@ CAMLprim value llvm_make_vector_constant(value ElementVals) { /*--... Operations on global variables, functions, and aliases (globals) ...--*/ /* llvalue -> bool */ -CAMLprim value llvm_is_declaration(value Global) { - return Val_bool(LLVMIsDeclaration((LLVMValueRef) Global)); +CAMLprim value llvm_is_declaration(LLVMValueRef Global) { + return Val_bool(LLVMIsDeclaration(Global)); } /* llvalue -> linkage */ -CAMLprim value llvm_linkage(value Global) { - return Val_int(LLVMGetLinkage((LLVMValueRef) Global)); +CAMLprim value llvm_linkage(LLVMValueRef Global) { + return Val_int(LLVMGetLinkage(Global)); } /* linkage -> llvalue -> unit */ -CAMLprim value llvm_set_linkage(value Linkage, value Global) { - LLVMSetLinkage((LLVMValueRef) Global, Int_val(Linkage)); +CAMLprim value llvm_set_linkage(value Linkage, LLVMValueRef Global) { + LLVMSetLinkage(Global, Int_val(Linkage)); return Val_unit; } /* llvalue -> string */ -CAMLprim value llvm_section(value Global) { - return copy_string(LLVMGetSection((LLVMValueRef) Global)); +CAMLprim value llvm_section(LLVMValueRef Global) { + return copy_string(LLVMGetSection(Global)); } /* string -> llvalue -> unit */ -CAMLprim value llvm_set_section(value Section, value Global) { - LLVMSetSection((LLVMValueRef) Global, String_val(Section)); +CAMLprim value llvm_set_section(value Section, LLVMValueRef Global) { + LLVMSetSection(Global, String_val(Section)); return Val_unit; } /* llvalue -> visibility */ -CAMLprim value llvm_visibility(value Global) { - return Val_int(LLVMGetVisibility((LLVMValueRef) Global)); +CAMLprim value llvm_visibility(LLVMValueRef Global) { + return Val_int(LLVMGetVisibility(Global)); } /* visibility -> llvalue -> unit */ -CAMLprim value llvm_set_visibility(value Viz, value Global) { - LLVMSetVisibility((LLVMValueRef) Global, Int_val(Viz)); +CAMLprim value llvm_set_visibility(value Viz, LLVMValueRef Global) { + LLVMSetVisibility(Global, Int_val(Viz)); return Val_unit; } /* llvalue -> int */ -CAMLprim value llvm_alignment(value Global) { - return Val_int(LLVMGetAlignment((LLVMValueRef) Global)); +CAMLprim value llvm_alignment(LLVMValueRef Global) { + return Val_int(LLVMGetAlignment(Global)); } /* int -> llvalue -> unit */ -CAMLprim value llvm_set_alignment(value Bytes, value Global) { - LLVMSetAlignment((LLVMValueRef) Global, Int_val(Bytes)); +CAMLprim value llvm_set_alignment(value Bytes, LLVMValueRef Global) { + LLVMSetAlignment(Global, Int_val(Bytes)); return Val_unit; } /*--... Operations on global variables .....................................--*/ /* lltype -> string -> llmodule -> llvalue */ -CAMLprim value llvm_add_global(value Ty, value Name, value M) { - return (value) LLVMAddGlobal((LLVMModuleRef) M, - (LLVMTypeRef) Ty, String_val(Name)); -} - -/* lltype -> string -> llmodule -> llvalue */ -CAMLprim value llvm_declare_global(value Ty, value Name, value M) { - return (value) LLVMAddGlobal((LLVMModuleRef) M, - (LLVMTypeRef) Ty, String_val(Name)); +CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name, + LLVMModuleRef M) { + return LLVMAddGlobal(M, Ty, String_val(Name)); } /* string -> llvalue -> llmodule -> llvalue */ -CAMLprim value llvm_define_global(value Name, value ConstantVal, value M) { - LLVMValueRef Initializer = (LLVMValueRef) ConstantVal; - LLVMValueRef GlobalVar = LLVMAddGlobal((LLVMModuleRef) M, - LLVMGetTypeOfValue(Initializer), +CAMLprim LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer, + LLVMModuleRef M) { + LLVMValueRef GlobalVar = LLVMAddGlobal(M, LLVMTypeOf(Initializer), String_val(Name)); LLVMSetInitializer(GlobalVar, Initializer); - return (value) GlobalVar; + return GlobalVar; } /* llvalue -> unit */ -CAMLprim value llvm_delete_global(value GlobalVar) { - LLVMDeleteGlobal((LLVMValueRef) GlobalVar); +CAMLprim value llvm_delete_global(LLVMValueRef GlobalVar) { + LLVMDeleteGlobal(GlobalVar); return Val_unit; } -/* llvalue -> llvalue */ -CAMLprim value llvm_global_initializer(value GlobalVar) { - return (value) LLVMGetInitializer((LLVMValueRef) GlobalVar); -} - /* llvalue -> llvalue -> unit */ -CAMLprim value llvm_set_initializer(value ConstantVal, value GlobalVar) { - LLVMSetInitializer((LLVMValueRef) GlobalVar, (LLVMValueRef) ConstantVal); +CAMLprim value llvm_set_initializer(LLVMValueRef ConstantVal, + LLVMValueRef GlobalVar) { + LLVMSetInitializer(GlobalVar, ConstantVal); return Val_unit; } /* llvalue -> unit */ -CAMLprim value llvm_remove_initializer(value GlobalVar) { - LLVMSetInitializer((LLVMValueRef) GlobalVar, NULL); +CAMLprim value llvm_remove_initializer(LLVMValueRef GlobalVar) { + LLVMSetInitializer(GlobalVar, NULL); return Val_unit; } /* llvalue -> bool */ -CAMLprim value llvm_is_thread_local(value GlobalVar) { - return Val_bool(LLVMIsThreadLocal((LLVMValueRef) GlobalVar)); +CAMLprim value llvm_is_thread_local(LLVMValueRef GlobalVar) { + return Val_bool(LLVMIsThreadLocal(GlobalVar)); } /* bool -> llvalue -> unit */ -CAMLprim value llvm_set_thread_local(value IsThreadLocal, value GlobalVar) { - LLVMSetThreadLocal((LLVMValueRef) GlobalVar, Bool_val(IsThreadLocal)); +CAMLprim value llvm_set_thread_local(value IsThreadLocal, + LLVMValueRef GlobalVar) { + LLVMSetThreadLocal(GlobalVar, Bool_val(IsThreadLocal)); + return Val_unit; +} + +/*--... Operations on functions ............................................--*/ + +/* string -> lltype -> llmodule -> llvalue */ +CAMLprim LLVMValueRef llvm_declare_function(value Name, LLVMTypeRef Ty, + LLVMModuleRef M) { + return LLVMAddFunction(M, String_val(Name), Ty); +} + +/* string -> lltype -> llmodule -> llvalue */ +CAMLprim LLVMValueRef llvm_define_function(value Name, LLVMTypeRef Ty, + LLVMModuleRef M) { + LLVMValueRef Fn = LLVMAddFunction(M, String_val(Name), Ty); + LLVMAppendBasicBlock(Fn, "entry"); + return Fn; +} + +/* llvalue -> unit */ +CAMLprim value llvm_delete_function(LLVMValueRef Fn) { + LLVMDeleteFunction(Fn); + return Val_unit; +} + +/* llvalue -> int -> llvalue */ +CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) { + return LLVMGetParam(Fn, Int_val(Index)); +} + +/* llvalue -> int -> llvalue */ +CAMLprim value llvm_params(LLVMValueRef Fn, value Index) { + value Params = alloc(LLVMCountParams(Fn), 0); + LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params)); + return Params; +} + +/* llvalue -> bool */ +CAMLprim value llvm_is_intrinsic(LLVMValueRef Fn) { + return Val_bool(LLVMGetIntrinsicID(Fn)); +} + +/* llvalue -> int */ +CAMLprim value llvm_function_call_conv(LLVMValueRef Fn) { + return Val_int(LLVMGetFunctionCallConv(Fn)); +} + +/* int -> llvalue -> unit */ +CAMLprim value llvm_set_function_call_conv(value Id, LLVMValueRef Fn) { + LLVMSetFunctionCallConv(Fn, Int_val(Id)); + return Val_unit; +} + +/*--... Operations on basic blocks .........................................--*/ + +/* llvalue -> llbasicblock array */ +CAMLprim value llvm_basic_blocks(LLVMValueRef Fn) { + value MLArray = alloc(LLVMCountBasicBlocks(Fn), 0); + LLVMGetBasicBlocks(Fn, (LLVMBasicBlockRef *) Op_val(MLArray)); + return MLArray; +} + +/* llbasicblock -> unit */ +CAMLprim value llvm_delete_block(LLVMBasicBlockRef BB) { + LLVMDeleteBasicBlock(BB); + return Val_unit; +} + +/* string -> llvalue -> llbasicblock */ +CAMLprim LLVMBasicBlockRef llvm_append_block(value Name, LLVMValueRef Fn) { + return LLVMAppendBasicBlock(Fn, String_val(Name)); +} + +/* string -> llbasicblock -> llbasicblock */ +CAMLprim LLVMBasicBlockRef llvm_insert_block(value Name, LLVMBasicBlockRef BB) { + return LLVMInsertBasicBlock(BB, String_val(Name)); +} + +/* llvalue -> bool */ +CAMLprim value llvm_value_is_block(LLVMValueRef Val) { + return Val_bool(LLVMValueIsBasicBlock(Val)); +} + + +/*===-- Instruction builders ----------------------------------------------===*/ + +#define Builder_val(v) (*(LLVMBuilderRef *)(Data_custom_val(v))) + +void llvm_finalize_builder(value B) { + fprintf(stderr, "disposing builder = 0x%08x\n", (int) Builder_val(B)); + LLVMDisposeBuilder(Builder_val(B)); +} + +static struct custom_operations builder_ops = { + (char *) "LLVMBuilder", + llvm_finalize_builder, + custom_compare_default, + custom_hash_default, + custom_serialize_default, + custom_deserialize_default +}; + +/* llvalue -> llbuilder */ +CAMLprim value llvm_builder_before(LLVMValueRef Inst) { + value V; + LLVMBuilderRef B = LLVMCreateBuilder(); + LLVMPositionBuilderBefore(B, Inst); + V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1); + Builder_val(V) = B; + return V; +} + +/* llbasicblock -> llbuilder */ +CAMLprim value llvm_builder_at_end(LLVMBasicBlockRef BB) { + value V; + LLVMBuilderRef B = LLVMCreateBuilder(); + LLVMPositionBuilderAtEnd(B, BB); + fprintf(stderr, "returning builder = 0x%08x\n", (int) B); + V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1); + Builder_val(V) = B; + return V; +} + +/* llvalue -> llbuilder -> unit */ +CAMLprim value llvm_position_before(LLVMValueRef Inst, value B) { + LLVMPositionBuilderBefore(Builder_val(B), Inst); + return Val_unit; +} + +/* llbasicblock -> llbuilder -> unit */ +CAMLprim value llvm_position_at_end(LLVMBasicBlockRef BB, value B) { + LLVMPositionBuilderAtEnd(Builder_val(B), BB); return Val_unit; } + +/*--... Terminators ........................................................--*/ + +/* llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_ret_void(value B) { + return LLVMBuildRetVoid(Builder_val(B)); +} + +/* llvalue -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_ret(LLVMValueRef Val, value B) { + return LLVMBuildRet(Builder_val(B), Val); +} + +/* llbasicblock -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_br(LLVMBasicBlockRef BB, value B) { + return LLVMBuildBr(Builder_val(B), BB); +} + +/* llvalue -> llbasicblock -> llbasicblock -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_cond_br(LLVMValueRef If, + LLVMBasicBlockRef Then, + LLVMBasicBlockRef Else, + value B) { + return LLVMBuildCondBr(Builder_val(B), If, Then, Else); +} + +/* llvalue -> llbasicblock -> int -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of, + LLVMBasicBlockRef Else, + value EstimatedCount, + value B) { + return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount)); +} + +/* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string -> + llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args, + LLVMBasicBlockRef Then, + LLVMBasicBlockRef Catch, + value Name, value B) { + return LLVMBuildInvoke(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Args), + Wosize_val(Args), Then, Catch, String_val(Name)); +} + +/* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string -> + llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) { + return llvm_build_invoke_nat((LLVMValueRef) Args[0], Args[1], + (LLVMBasicBlockRef) Args[2], + (LLVMBasicBlockRef) Args[3], + Args[4], Args[5]); +} + +/* llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_unwind(value B) { + return LLVMBuildUnwind(Builder_val(B)); +} + +/* llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_unreachable(value B) { + return LLVMBuildUnreachable(Builder_val(B)); +} + +/*--... Arithmetic .........................................................--*/ + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_add(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildAdd(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildSub(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildMul(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_udiv(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildUDiv(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_sdiv(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildSDiv(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fdiv(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildFDiv(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_urem(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildURem(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_srem(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildSRem(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_frem(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildFRem(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_shl(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildShl(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_lshr(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildLShr(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_ashr(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildAShr(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_and(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildAnd(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_or(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildOr(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_xor(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildXor(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_neg(LLVMValueRef X, + value Name, value B) { + return LLVMBuildNeg(Builder_val(B), X, String_val(Name)); +} + +/* llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X, + value Name, value B) { + return LLVMBuildNot(Builder_val(B), X, String_val(Name)); +} + +/*--... Memory .............................................................--*/ + +/* lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name)); +} + +/* lltype -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_array_malloc(LLVMTypeRef Ty, LLVMValueRef Size, + value Name, value B) { + return LLVMBuildArrayMalloc(Builder_val(B), Ty, Size, String_val(Name)); +} + +/* lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_alloca(LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildAlloca(Builder_val(B), Ty, String_val(Name)); +} + +/* lltype -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size, + value Name, value B) { + return LLVMBuildArrayAlloca(Builder_val(B), Ty, Size, String_val(Name)); +} + +/* llvalue -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef Pointer, value B) { + return LLVMBuildFree(Builder_val(B), Pointer); +} + +/* llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_load(LLVMValueRef Pointer, + value Name, value B) { + return LLVMBuildLoad(Builder_val(B), Pointer, String_val(Name)); +} + +/* llvalue -> llvalue -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_store(LLVMValueRef Value, LLVMValueRef Pointer, + value B) { + return LLVMBuildStore(Builder_val(B), Value, Pointer); +} + +/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices, + value Name, value B) { + return LLVMBuildGEP(Builder_val(B), Pointer, + (LLVMValueRef *) Op_val(Indices), Wosize_val(Indices), + String_val(Name)); +} + +/*--... Casts ..............................................................--*/ + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_trunc(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildTrunc(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_zext(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildZExt(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_sext(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildSExt(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fptoui(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildFPToUI(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fptosi(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildFPToSI(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_uitofp(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildUIToFP(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_sitofp(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildSIToFP(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fptrunc(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildFPTrunc(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fpext(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildFPExt(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_prttoint(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildPtrToInt(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_inttoptr(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildIntToPtr(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_bitcast(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildBitCast(Builder_val(B), X, Ty, String_val(Name)); +} + +/*--... Comparisons ........................................................--*/ + +/* int_predicate -> llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_icmp(value Pred, + LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildICmp(Builder_val(B), Int_val(Pred) + LLVMIntEQ, LHS, RHS, + String_val(Name)); +} + +/* real_predicate -> llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fcmp(value Pred, + LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildFCmp(Builder_val(B), Int_val(Pred), LHS, RHS, + String_val(Name)); +} + +/*--... Miscellaneous instructions .........................................--*/ + +/* lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_phi(LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildPhi(Builder_val(B), Ty, String_val(Name)); +} + +/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_call(LLVMValueRef Fn, value Params, + value Name, value B) { + return LLVMBuildCall(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Params), + Wosize_val(Params), String_val(Name)); +} + +/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_select(LLVMValueRef If, + LLVMValueRef Then, LLVMValueRef Else, + value Name, value B) { + return LLVMBuildSelect(Builder_val(B), If, Then, Else, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_va_arg(LLVMValueRef List, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildVAArg(Builder_val(B), List, Ty, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_extractelement(LLVMValueRef Vec, + LLVMValueRef Idx, + value Name, value B) { + return LLVMBuildExtractElement(Builder_val(B), Vec, Idx, String_val(Name)); +} + +/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_insertelement(LLVMValueRef Vec, + LLVMValueRef Element, + LLVMValueRef Idx, + value Name, value B) { + return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx, + String_val(Name)); +} + +/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_shufflevector(LLVMValueRef V1, LLVMValueRef V2, + LLVMValueRef Mask, + value Name, value B) { + return LLVMBuildShuffleVector(Builder_val(B), V1, V2, Mask, String_val(Name)); +} + diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 9aa5f07761c..47b89aa513e 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -37,9 +37,11 @@ extern "C" { typedef struct LLVMOpaqueModule *LLVMModuleRef; typedef struct LLVMOpaqueType *LLVMTypeRef; typedef struct LLVMOpaqueValue *LLVMValueRef; +typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef; +typedef struct LLVMOpaqueBuilder *LLVMBuilderRef; typedef enum { - LLVMVoidTypeKind = 0, /* type with no size */ + LLVMVoidTypeKind, /* type with no size */ LLVMFloatTypeKind, /* 32 bit floating point type */ LLVMDoubleTypeKind, /* 64 bit floating point type */ LLVMX86_FP80TypeKind, /* 80 bit floating point type (X87) */ @@ -56,7 +58,7 @@ typedef enum { } LLVMTypeKind; typedef enum { - LLVMExternalLinkage = 0,/* Externally visible function */ + LLVMExternalLinkage, /* Externally visible function */ LLVMLinkOnceLinkage, /* Keep one copy of function when linking (inline) */ LLVMWeakLinkage, /* Keep one copy of function when linking (weak) */ LLVMAppendingLinkage, /* Special purpose, only applies to global arrays */ @@ -68,11 +70,51 @@ typedef enum { } LLVMLinkage; typedef enum { - LLVMDefaultVisibility = 0, /* The GV is visible */ - LLVMHiddenVisibility, /* The GV is hidden */ - LLVMProtectedVisibility /* The GV is protected */ + LLVMDefaultVisibility, /* The GV is visible */ + LLVMHiddenVisibility, /* The GV is hidden */ + LLVMProtectedVisibility /* The GV is protected */ } LLVMVisibility; +typedef enum { + LLVMCCallConv = 0, + LLVMFastCallConv = 8, + LLVMColdCallConv = 9, + LLVMX86StdcallCallConv = 64, + LLVMX86FastcallCallConv = 65 +} LLVMCallConv; + +typedef enum { + LLVMIntEQ = 32, /* equal */ + LLVMIntNE, /* not equal */ + LLVMIntUGT, /* unsigned greater than */ + LLVMIntUGE, /* unsigned greater or equal */ + LLVMIntULT, /* unsigned less than */ + LLVMIntULE, /* unsigned less or equal */ + LLVMIntSGT, /* signed greater than */ + LLVMIntSGE, /* signed greater or equal */ + LLVMIntSLT, /* signed less than */ + LLVMIntSLE /* signed less or equal */ +} LLVMIntPredicate; + +typedef enum { + LLVMRealPredicateFalse, /* Always false (always folded) */ + LLVMRealOEQ, /* True if ordered and equal */ + LLVMRealOGT, /* True if ordered and greater than */ + LLVMRealOGE, /* True if ordered and greater than or equal */ + LLVMRealOLT, /* True if ordered and less than */ + LLVMRealOLE, /* True if ordered and less than or equal */ + LLVMRealONE, /* True if ordered and operands are unequal */ + LLVMRealORD, /* True if ordered (no nans) */ + LLVMRealUNO, /* True if unordered: isnan(X) | isnan(Y) */ + LLVMRealUEQ, /* True if unordered or equal */ + LLVMRealUGT, /* True if unordered or greater than */ + LLVMRealUGE, /* True if unordered, greater than, or equal */ + LLVMRealULT, /* True if unordered or less than */ + LLVMRealULE, /* True if unordered, less than, or equal */ + LLVMRealUNE, /* True if unordered or not equal */ + LLVMRealPredicateTrue /* Always true (always folded) */ +} LLVMRealPredicate; + /*===-- Modules -----------------------------------------------------------===*/ @@ -82,10 +124,10 @@ void LLVMDisposeModule(LLVMModuleRef M); /* Same as Module::addTypeName. */ int LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty); -int LLVMDeleteTypeName(LLVMModuleRef M, const char *Name); +void LLVMDeleteTypeName(LLVMModuleRef M, const char *Name); -/*===-- Types --------------------------------------------------------------===*/ +/*===-- Types -------------------------------------------------------------===*/ /* LLVM types conform to the following hierarchy: * @@ -111,8 +153,8 @@ LLVMTypeRef LLVMInt8Type(); LLVMTypeRef LLVMInt16Type(); LLVMTypeRef LLVMInt32Type(); LLVMTypeRef LLVMInt64Type(); -LLVMTypeRef LLVMCreateIntegerType(unsigned NumBits); -unsigned LLVMGetIntegerTypeWidth(LLVMTypeRef IntegerTy); +LLVMTypeRef LLVMCreateIntType(unsigned NumBits); +unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy); /* Operations on real types */ LLVMTypeRef LLVMFloatType(); @@ -126,14 +168,14 @@ LLVMTypeRef LLVMCreateFunctionType(LLVMTypeRef ReturnType, LLVMTypeRef *ParamTypes, unsigned ParamCount, int IsVarArg); int LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy); -LLVMTypeRef LLVMGetFunctionReturnType(LLVMTypeRef FunctionTy); -unsigned LLVMGetFunctionParamCount(LLVMTypeRef FunctionTy); -void LLVMGetFunctionParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest); +LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy); +unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy); +void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest); /* Operations on struct types */ LLVMTypeRef LLVMCreateStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount, int Packed); -unsigned LLVMGetStructElementCount(LLVMTypeRef StructTy); +unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy); void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest); int LLVMIsPackedStruct(LLVMTypeRef StructTy); @@ -165,10 +207,11 @@ LLVMTypeRef LLVMCreateOpaqueType(); * global variable * function * alias + * basic blocks */ /* Operations on all values */ -LLVMTypeRef LLVMGetTypeOfValue(LLVMValueRef Val); +LLVMTypeRef LLVMTypeOf(LLVMValueRef Val); const char *LLVMGetValueName(LLVMValueRef Val); void LLVMSetValueName(LLVMValueRef Val, const char *Name); @@ -215,6 +258,157 @@ void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal); int LLVMIsThreadLocal(LLVMValueRef GlobalVar); void LLVMSetThreadLocal(LLVMValueRef GlobalVar, int IsThreadLocal); +/* Operations on functions */ +LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name, + LLVMTypeRef FunctionTy); +void LLVMDeleteFunction(LLVMValueRef Fn); +unsigned LLVMCountParams(LLVMValueRef Fn); +void LLVMGetParams(LLVMValueRef Fn, LLVMValueRef *Params); +LLVMValueRef LLVMGetParam(LLVMValueRef Fn, unsigned Index); +unsigned LLVMGetIntrinsicID(LLVMValueRef Fn); +unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn); +void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC); + +/* Operations on basic blocks */ +LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef Bb); +int LLVMValueIsBasicBlock(LLVMValueRef Val); +LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val); +unsigned LLVMCountBasicBlocks(LLVMValueRef Fn); +void LLVMGetBasicBlocks(LLVMValueRef Fn, LLVMBasicBlockRef *BasicBlocks); +LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn); +LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, const char *Name); +LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB, + const char *Name); +void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB); + + +/*===-- Instruction builders ----------------------------------------------===*/ + +/* An instruction builder represents a point within a basic block, and is the + * exclusive means of building instructions using the C interface. + */ + +LLVMBuilderRef LLVMCreateBuilder(); +void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr); +void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block); +void LLVMDisposeBuilder(LLVMBuilderRef Builder); + +/* Terminators */ +LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef); +LLVMValueRef LLVMBuildRet(LLVMBuilderRef, LLVMValueRef V); +LLVMValueRef LLVMBuildBr(LLVMBuilderRef, LLVMBasicBlockRef Dest); +LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef, LLVMValueRef If, + LLVMBasicBlockRef Then, LLVMBasicBlockRef Else); +LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef, LLVMValueRef V, + LLVMBasicBlockRef Else, unsigned NumCases); +LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, + const char *Name); +LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef); +LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef); + +/* Arithmetic */ +LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildURem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildSRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildFRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildShl(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildLShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildAShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildAnd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildOr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildXor(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name); +LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name); + +/* Memory */ +LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name); +LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef, LLVMTypeRef Ty, + LLVMValueRef Val, const char *Name); +LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name); +LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef, LLVMTypeRef Ty, + LLVMValueRef Val, const char *Name); +LLVMValueRef LLVMBuildFree(LLVMBuilderRef, LLVMValueRef PointerVal); +LLVMValueRef LLVMBuildLoad(LLVMBuilderRef, LLVMValueRef PointerVal, + const char *Name); +LLVMValueRef LLVMBuildStore(LLVMBuilderRef, LLVMValueRef Val, LLVMValueRef Ptr); +LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer, + LLVMValueRef *Indices, unsigned NumIndices, + const char *Name); + +/* Casts */ +LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildZExt(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildSExt(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); + +/* Comparisons */ +LLVMValueRef LLVMBuildICmp(LLVMBuilderRef, LLVMIntPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef, LLVMRealPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); + +/* Miscellaneous instructions */ +LLVMValueRef LLVMBuildPhi(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name); +LLVMValueRef LLVMBuildCall(LLVMBuilderRef, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + const char *Name); +LLVMValueRef LLVMBuildSelect(LLVMBuilderRef, LLVMValueRef If, + LLVMValueRef Then, LLVMValueRef Else, + const char *Name); +LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef, LLVMValueRef List, LLVMTypeRef Ty, + const char *Name); +LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef, LLVMValueRef VecVal, + LLVMValueRef Index, const char *Name); +LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef, LLVMValueRef VecVal, + LLVMValueRef EltVal, LLVMValueRef Index, + const char *Name); +LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef V1, + LLVMValueRef V2, LLVMValueRef Mask, + const char *Name); #ifdef __cplusplus } diff --git a/include/llvm/CHelpers.h b/include/llvm/CHelpers.h index d00aba383f9..0ae7503ab07 100644 --- a/include/llvm/CHelpers.h +++ b/include/llvm/CHelpers.h @@ -89,6 +89,16 @@ namespace llvm { inline LLVMValueRef *wrap(const Value **Vals) { return reinterpret_cast(const_cast(Vals)); } + + /// Basic block conversions + /// + inline BasicBlock *unwrap(LLVMBasicBlockRef BBRef) { + return reinterpret_cast(BBRef); + } + + inline LLVMBasicBlockRef wrap(const BasicBlock *BB) { + return reinterpret_cast(const_cast(BB)); + } } #endif diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index b809db2ec72..9fc4d40746c 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -18,12 +18,24 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/GlobalVariable.h" -#include -#include +#include "llvm/Support/LLVMBuilder.h" +#include "llvm/TypeSymbolTable.h" #include using namespace llvm; +namespace { + /// Opaque builder conversions. + /// + inline LLVMBuilder *unwrap(LLVMBuilderRef B) { + return reinterpret_cast(B); + } + + inline LLVMBuilderRef wrap(LLVMBuilder *B) { + return reinterpret_cast(B); + } +} + /*===-- Operations on modules ---------------------------------------------===*/ @@ -39,6 +51,15 @@ int LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) { return unwrap(M)->addTypeName(Name, unwrap(Ty)); } +void LLVMDeleteTypeName(LLVMModuleRef M, const char *Name) { + std::string N(Name); + + TypeSymbolTable &TST = unwrap(M)->getTypeSymbolTable(); + for (TypeSymbolTable::iterator I = TST.begin(), E = TST.end(); I != E; ++I) + if (I->first == N) + TST.remove(I); +} + /*===-- Operations on types -----------------------------------------------===*/ @@ -61,11 +82,11 @@ LLVMTypeRef LLVMInt16Type() { return (LLVMTypeRef) Type::Int16Ty; } LLVMTypeRef LLVMInt32Type() { return (LLVMTypeRef) Type::Int32Ty; } LLVMTypeRef LLVMInt64Type() { return (LLVMTypeRef) Type::Int64Ty; } -LLVMTypeRef LLVMCreateIntegerType(unsigned NumBits) { +LLVMTypeRef LLVMCreateIntType(unsigned NumBits) { return wrap(IntegerType::get(NumBits)); } -unsigned LLVMGetIntegerTypeWidth(LLVMTypeRef IntegerTy) { +unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy) { return unwrap(IntegerTy)->getBitWidth(); } @@ -93,15 +114,15 @@ int LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy) { return unwrap(FunctionTy)->isVarArg(); } -LLVMTypeRef LLVMGetFunctionReturnType(LLVMTypeRef FunctionTy) { +LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy) { return wrap(unwrap(FunctionTy)->getReturnType()); } -unsigned LLVMGetFunctionParamCount(LLVMTypeRef FunctionTy) { +unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy) { return unwrap(FunctionTy)->getNumParams(); } -void LLVMGetFunctionParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest) { +void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest) { FunctionType *Ty = unwrap(FunctionTy); for (FunctionType::param_iterator I = Ty->param_begin(), E = Ty->param_end(); I != E; ++I) @@ -120,7 +141,7 @@ LLVMTypeRef LLVMCreateStructType(LLVMTypeRef *ElementTypes, return wrap(StructType::get(Tys, Packed != 0)); } -unsigned LLVMGetStructElementCount(LLVMTypeRef StructTy) { +unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy) { return unwrap(StructTy)->getNumElements(); } @@ -175,7 +196,7 @@ LLVMTypeRef LLVMCreateOpaqueType() { /*--.. Operations on all values ............................................--*/ -LLVMTypeRef LLVMGetTypeOfValue(LLVMValueRef Val) { +LLVMTypeRef LLVMTypeOf(LLVMValueRef Val) { return wrap(unwrap(Val)->getType()); } @@ -328,3 +349,426 @@ void LLVMSetThreadLocal(LLVMValueRef GlobalVar, int IsThreadLocal) { unwrap(GlobalVar)->setThreadLocal(IsThreadLocal != 0); } +/*--.. Operations on functions .............................................--*/ + +LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name, + LLVMTypeRef FunctionTy) { + return wrap(new Function(unwrap(FunctionTy), + GlobalValue::ExternalLinkage, Name, unwrap(M))); +} + +void LLVMDeleteFunction(LLVMValueRef Fn) { + unwrap(Fn)->eraseFromParent(); +} + +unsigned LLVMCountParams(LLVMValueRef FnRef) { + // This function is strictly redundant to + // LLVMCountParamTypes(LLVMGetElementType(LLVMTypeOf(FnRef))) + return unwrap(FnRef)->getArgumentList().size(); +} + +LLVMValueRef LLVMGetParam(LLVMValueRef FnRef, unsigned index) { + Function::arg_iterator AI = unwrap(FnRef)->arg_begin(); + while (index --> 0) + AI++; + return wrap(AI); +} + +void LLVMGetParams(LLVMValueRef FnRef, LLVMValueRef *ParamRefs) { + Function *Fn = unwrap(FnRef); + for (Function::arg_iterator I = Fn->arg_begin(), + E = Fn->arg_end(); I != E; I++) + *ParamRefs++ = wrap(I); +} + +unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) { + if (Function *F = dyn_cast(unwrap(Fn))) + return F->getIntrinsicID(); + return 0; +} + +unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn) { + return unwrap(Fn)->getCallingConv(); +} + +void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC) { + return unwrap(Fn)->setCallingConv(CC); +} + +/*--.. Operations on basic blocks ..........................................--*/ + +LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef Bb) { + return wrap(static_cast(unwrap(Bb))); +} + +int LLVMValueIsBasicBlock(LLVMValueRef Val) { + return isa(unwrap(Val)); +} + +LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val) { + return wrap(unwrap(Val)); +} + +unsigned LLVMCountBasicBlocks(LLVMValueRef FnRef) { + return unwrap(FnRef)->getBasicBlockList().size(); +} + +void LLVMGetBasicBlocks(LLVMValueRef FnRef, LLVMBasicBlockRef *BasicBlocksRefs){ + Function *Fn = unwrap(FnRef); + for (Function::iterator I = Fn->begin(), E = Fn->end(); I != E; I++) + *BasicBlocksRefs++ = wrap(I); +} + +LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn) { + return wrap(&unwrap(Fn)->getEntryBlock()); +} + +LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef FnRef, const char *Name) { + return wrap(new BasicBlock(Name, unwrap(FnRef))); +} + +LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBBRef, + const char *Name) { + BasicBlock *InsertBeforeBB = unwrap(InsertBeforeBBRef); + return wrap(new BasicBlock(Name, InsertBeforeBB->getParent(), + InsertBeforeBB)); +} + +void LLVMDeleteBasicBlock(LLVMBasicBlockRef BBRef) { + unwrap(BBRef)->eraseFromParent(); +} + +/*--.. Call and invoke instructions ........................................--*/ + +unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr) { + Value *V = unwrap(Instr); + if (CallInst *CI = dyn_cast(V)) + return CI->getCallingConv(); + else if (InvokeInst *II = dyn_cast(V)) + return II->getCallingConv(); + assert(0 && "LLVMGetInstructionCallConv applies only to call and invoke!"); + return 0; +} + +void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC) { + Value *V = unwrap(Instr); + if (CallInst *CI = dyn_cast(V)) + return CI->setCallingConv(CC); + else if (InvokeInst *II = dyn_cast(V)) + return II->setCallingConv(CC); + assert(0 && "LLVMSetInstructionCallConv applies only to call and invoke!"); +} + + +/*===-- Instruction builders ----------------------------------------------===*/ + +LLVMBuilderRef LLVMCreateBuilder() { + return wrap(new LLVMBuilder()); +} + +void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr) { + Instruction *I = unwrap(Instr); + unwrap(Builder)->SetInsertPoint(I->getParent(), I); +} + +void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block) { + BasicBlock *BB = unwrap(Block); + unwrap(Builder)->SetInsertPoint(BB); +} + +void LLVMDisposeBuilder(LLVMBuilderRef Builder) { + delete unwrap(Builder); +} + +/*--.. Instruction builders ................................................--*/ + +LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef B) { + return wrap(unwrap(B)->CreateRetVoid()); +} + +LLVMValueRef LLVMBuildRet(LLVMBuilderRef B, LLVMValueRef V) { + return wrap(unwrap(B)->CreateRet(unwrap(V))); +} + +LLVMValueRef LLVMBuildBr(LLVMBuilderRef B, LLVMBasicBlockRef Dest) { + return wrap(unwrap(B)->CreateBr(unwrap(Dest))); +} + +LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef B, LLVMValueRef If, + LLVMBasicBlockRef Then, LLVMBasicBlockRef Else) { + return wrap(unwrap(B)->CreateCondBr(unwrap(If), unwrap(Then), unwrap(Else))); +} + +LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef B, LLVMValueRef V, + LLVMBasicBlockRef Else, unsigned NumCases) { + return wrap(unwrap(B)->CreateSwitch(unwrap(V), unwrap(Else), NumCases)); +} + +LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, + const char *Name) { + return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch), + unwrap(Args), unwrap(Args) + NumArgs, + Name)); +} + +LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef B) { + return wrap(unwrap(B)->CreateUnwind()); +} + +LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) { + return wrap(unwrap(B)->CreateUnreachable()); +} + +/*--.. Arithmetic ..........................................................--*/ + +LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateAdd(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateSub(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateMul(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateUDiv(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateSDiv(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFDiv(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildURem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateURem(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildSRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateSRem(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFRem(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildShl(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateShl(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildLShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateLShr(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildAShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateAShr(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildAnd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateAnd(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildOr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateOr(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildXor(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateXor(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { + return wrap(unwrap(B)->CreateNeg(unwrap(V), Name)); +} + +LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { + return wrap(unwrap(B)->CreateNot(unwrap(V), Name)); +} + +/*--.. Memory ..............................................................--*/ + +LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, + const char *Name) { + return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), 0, Name)); +} + +LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef Val, const char *Name) { + return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), unwrap(Val), Name)); +} + +LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, + const char *Name) { + return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), 0, Name)); +} + +LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef Val, const char *Name) { + return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), unwrap(Val), Name)); +} + +LLVMValueRef LLVMBuildFree(LLVMBuilderRef B, LLVMValueRef PointerVal) { + return wrap(unwrap(B)->CreateFree(unwrap(PointerVal))); +} + + +LLVMValueRef LLVMBuildLoad(LLVMBuilderRef B, LLVMValueRef PointerVal, + const char *Name) { + return wrap(unwrap(B)->CreateLoad(unwrap(PointerVal), Name)); +} + +LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val, + LLVMValueRef PointerVal) { + return wrap(unwrap(B)->CreateStore(unwrap(Val), unwrap(PointerVal))); +} + +LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer, + LLVMValueRef *Indices, unsigned NumIndices, + const char *Name) { + return wrap(unwrap(B)->CreateGEP(unwrap(Pointer), unwrap(Indices), + unwrap(Indices) + NumIndices, Name)); +} + +/*--.. Casts ...............................................................--*/ + +LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateTrunc(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildZExt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateZExt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildSExt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateSExt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPToUI(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPToSI(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateUIToFP(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateSIToFP(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPTrunc(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPExt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreatePtrToInt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateIntToPtr(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateBitCast(unwrap(Val), unwrap(DestTy), Name)); +} + +/*--.. Comparisons .........................................................--*/ + +LLVMValueRef LLVMBuildICmp(LLVMBuilderRef B, LLVMIntPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateICmp(static_cast(Op), + unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef B, LLVMRealPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFCmp(static_cast(Op), + unwrap(LHS), unwrap(RHS), Name)); +} + +/*--.. Miscellaneous instructions ..........................................--*/ + +LLVMValueRef LLVMBuildPhi(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { + return wrap(unwrap(B)->CreatePHI(unwrap(Ty), Name)); +} + +LLVMValueRef LLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + const char *Name) { + return wrap(unwrap(B)->CreateCall(unwrap(Fn), unwrap(Args), + unwrap(Args) + NumArgs, Name)); +} + +LLVMValueRef LLVMBuildSelect(LLVMBuilderRef B, LLVMValueRef If, + LLVMValueRef Then, LLVMValueRef Else, + const char *Name) { + return wrap(unwrap(B)->CreateSelect(unwrap(If), unwrap(Then), unwrap(Else), + Name)); +} + +LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef B, LLVMValueRef List, + LLVMTypeRef Ty, const char *Name) { + return wrap(unwrap(B)->CreateVAArg(unwrap(List), unwrap(Ty), Name)); +} + +LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef B, LLVMValueRef VecVal, + LLVMValueRef Index, const char *Name) { + return wrap(unwrap(B)->CreateExtractElement(unwrap(VecVal), unwrap(Index), + Name)); +} + +LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef B, LLVMValueRef VecVal, + LLVMValueRef EltVal, LLVMValueRef Index, + const char *Name) { + return wrap(unwrap(B)->CreateInsertElement(unwrap(VecVal), unwrap(EltVal), + unwrap(Index), Name)); +} + +LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef B, LLVMValueRef V1, + LLVMValueRef V2, LLVMValueRef Mask, + const char *Name) { + return wrap(unwrap(B)->CreateShuffleVector(unwrap(V1), unwrap(V2), + unwrap(Mask), Name)); +} diff --git a/test/Bindings/Ocaml/bitwriter.ml b/test/Bindings/Ocaml/bitwriter.ml index 5421e09bcea..7bcdd4768f9 100644 --- a/test/Bindings/Ocaml/bitwriter.ml +++ b/test/Bindings/Ocaml/bitwriter.ml @@ -11,6 +11,6 @@ let test x = if not x then exit 1 else () let _ = let m = Llvm.create_module "ocaml_test_module" in - ignore (Llvm.add_type_name "caml_int_ty" Llvm.i32_type m); + ignore (Llvm.define_type_name "caml_int_ty" Llvm.i32_type m); test (Llvm_bitwriter.write_bitcode_file m Sys.argv.(1)) diff --git a/test/Bindings/Ocaml/vmcore.ml b/test/Bindings/Ocaml/vmcore.ml index 6d04638cb28..b1d2736f567 100644 --- a/test/Bindings/Ocaml/vmcore.ml +++ b/test/Bindings/Ocaml/vmcore.ml @@ -44,43 +44,43 @@ let test_types () = (* RUN: grep {Ty01.*void} < %t.ll *) group "void"; - insist (add_type_name "Ty01" void_type m); + insist (define_type_name "Ty01" void_type m); insist (Void_type == classify_type void_type); (* RUN: grep {Ty02.*i1} < %t.ll *) group "i1"; - insist (add_type_name "Ty02" i1_type m); + insist (define_type_name "Ty02" i1_type m); insist (Integer_type == classify_type i1_type); (* RUN: grep {Ty03.*i32} < %t.ll *) group "i32"; - insist (add_type_name "Ty03" i32_type m); + insist (define_type_name "Ty03" i32_type m); (* RUN: grep {Ty04.*i42} < %t.ll *) group "i42"; let ty = make_integer_type 42 in - insist (add_type_name "Ty04" ty m); + insist (define_type_name "Ty04" ty m); (* RUN: grep {Ty05.*float} < %t.ll *) group "float"; - insist (add_type_name "Ty05" float_type m); + insist (define_type_name "Ty05" float_type m); insist (Float_type == classify_type float_type); (* RUN: grep {Ty06.*double} < %t.ll *) group "double"; - insist (add_type_name "Ty06" double_type m); + insist (define_type_name "Ty06" double_type m); insist (Double_type == classify_type double_type); (* RUN: grep {Ty07.*i32.*i1, double} < %t.ll *) group "function"; let ty = make_function_type i32_type [| i1_type; double_type |] false in - insist (add_type_name "Ty07" ty m); + insist (define_type_name "Ty07" ty m); insist (Function_type = classify_type ty); insist (not (is_var_arg ty)); insist (i32_type == return_type ty); @@ -90,14 +90,14 @@ let test_types () = *) group "vararg"; let ty = make_function_type void_type [| i32_type |] true in - insist (add_type_name "Ty08" ty m); + insist (define_type_name "Ty08" ty m); insist (is_var_arg ty); (* RUN: grep {Ty09.*\\\[7 x i8\\\]} < %t.ll *) group "array"; let ty = make_array_type i8_type 7 in - insist (add_type_name "Ty09" ty m); + insist (define_type_name "Ty09" ty m); insist (7 = array_length ty); insist (i8_type == element_type ty); insist (Array_type == classify_type ty); @@ -106,7 +106,7 @@ let test_types () = *) group "pointer"; let ty = make_pointer_type float_type in - insist (add_type_name "Ty10" ty m); + insist (define_type_name "Ty10" ty m); insist (float_type == element_type ty); insist (Pointer_type == classify_type ty); @@ -114,7 +114,7 @@ let test_types () = *) group "vector"; let ty = make_vector_type i16_type 4 in - insist (add_type_name "Ty11" ty m); + insist (define_type_name "Ty11" ty m); insist (i16_type == element_type ty); insist (4 = vector_size ty); @@ -122,9 +122,16 @@ let test_types () = *) group "opaque"; let ty = make_opaque_type () in - insist (add_type_name "Ty12" ty m); + insist (define_type_name "Ty12" ty m); insist (ty == ty); - insist (ty <> make_opaque_type ()) + insist (ty <> make_opaque_type ()); + + (* RUN: grep -v {Ty13} < %t.ll + *) + group "delete"; + let ty = make_opaque_type () in + insist (define_type_name "Ty13" ty m); + delete_type_name "Ty13" m (*===-- Constants ---------------------------------------------------------===*) @@ -163,9 +170,6 @@ let test_constants () = *) group "string w/ null"; let c = make_string_constant "hi\000again" true in - prerr_string "====> "; - prerr_int (array_length (type_of c)); - prerr_endline " <===="; ignore (define_global "Const05" c m); insist ((make_array_type i8_type 9) = type_of c); @@ -306,6 +310,317 @@ let test_global_variables () = delete_global g +(*===-- Functions ---------------------------------------------------------===*) + +let test_functions () = + let ty = make_function_type i32_type [| i32_type; i64_type |] false in + let pty = make_pointer_type ty in + + (* RUN: grep {declare i32 @Fn1\(i32, i64\)} < %t.ll + *) + group "declare"; + let fn = declare_function "Fn1" ty m in + insist (pty = type_of fn); + insist (is_declaration fn); + insist (0 = Array.length (basic_blocks fn)); + + (* RUN: grep -v {Fn2} < %t.ll + *) + group "delete"; + let fn = declare_function "Fn2" ty m in + delete_function fn; + + (* RUN: grep {define.*Fn3} < %t.ll + *) + group "define"; + let fn = define_function "Fn3" ty m in + insist (not (is_declaration fn)); + insist (1 = Array.length (basic_blocks fn)); + (* this function is not valid because init bb lacks a terminator *) + + (* RUN: grep {define.*Fn4.*Param1.*Param2} < %t.ll + *) + group "params"; + let fn = define_function "Fn4" ty m in + let params = params fn in + insist (2 = Array.length params); + insist (params.(0) = param fn 0); + insist (params.(1) = param fn 1); + insist (i32_type = type_of params.(0)); + insist (i64_type = type_of params.(1)); + set_value_name "Param1" params.(0); + set_value_name "Param2" params.(1); + (* this function is not valid because init bb lacks a terminator *) + + (* RUN: grep {fastcc.*Fn5} < %t.ll + *) + group "callconv"; + let fn = define_function "Fn5" ty m in + insist (ccc = function_call_conv fn); + set_function_call_conv fastcc fn; + insist (fastcc = function_call_conv fn) + + +(*===-- Basic Blocks ------------------------------------------------------===*) + +let test_basic_blocks () = + let ty = make_function_type void_type [| |] false in + + (* RUN: grep {Bb1} < %t.ll + *) + group "entry"; + let fn = declare_function "X" ty m in + let bb = append_block "Bb1" fn in + insist (bb = entry_block fn); + + (* RUN: grep -v Bb2 < %t.ll + *) + group "delete"; + let fn = declare_function "X2" ty m in + let bb = append_block "Bb2" fn in + delete_block bb; + + group "insert"; + let fn = declare_function "X3" ty m in + let bbb = append_block "" fn in + let bba = insert_block "" bbb in + insist ([| bba; bbb |] = basic_blocks fn); + + (* RUN: grep Bb3 < %t.ll + *) + group "name/value"; + let fn = define_function "X4" ty m in + let bb = entry_block fn in + let bbv = value_of_block bb in + set_value_name "Bb3" bbv; + insist ("Bb3" = value_name bbv); + + group "casts"; + let fn = define_function "X5" ty m in + let bb = entry_block fn in + insist (bb = block_of_value (value_of_block bb)); + insist (value_is_block (value_of_block bb)); + insist (not (value_is_block (make_null i32_type))) + + +(*===-- Builder -----------------------------------------------------------===*) + +let test_builder () = + let (++) x f = f x; x in + + group "ret void"; + begin + (* RUN: grep {ret void} < %t.ll + *) + let fty = make_function_type void_type [| |] false in + let fn = declare_function "X6" fty m in + let b = builder_at_end (append_block "Bb01" fn) in + ignore (build_ret_void b) + end; + + (* The rest of the tests will use one big function. *) + let fty = make_function_type i32_type [| i32_type; i32_type |] false in + let fn = define_function "X7" fty m in + let atentry = builder_at_end (entry_block fn) in + let p1 = param fn 0 ++ set_value_name "P1" in + let p2 = param fn 1 ++ set_value_name "P2" in + let f1 = build_uitofp p1 float_type "F1" atentry in + let f2 = build_uitofp p2 float_type "F2" atentry in + + let bb00 = append_block "Bb00" fn in + ignore (build_unreachable (builder_at_end bb00)); + + group "ret"; begin + (* RUN: grep {ret.*P1} < %t.ll + *) + let ret = build_ret p1 atentry in + position_before ret atentry + end; + + group "br"; begin + (* RUN: grep {br.*Bb02} < %t.ll + *) + let bb02 = append_block "Bb02" fn in + let b = builder_at_end bb02 in + ignore (build_br bb02 b) + end; + + group "cond_br"; begin + (* RUN: grep {br.*Inst01.*Bb03.*Bb00} < %t.ll + *) + let bb03 = append_block "Bb03" fn in + let b = builder_at_end bb03 in + let cond = build_trunc p1 i1_type "Inst01" b in + ignore (build_cond_br cond bb03 bb00 b) + end; + + (* TODO: Switch *) + + group "invoke"; begin + (* RUN: grep {Inst02.*invoke.*P1.*P2} < %t.ll + * RUN: grep {to.*Bb04.*unwind.*Bb00} < %t.ll + *) + let bb04 = append_block "Bb04" fn in + let b = builder_at_end bb04 in + ignore (build_invoke fn [| p1; p2 |] bb04 bb00 "Inst02" b) + end; + + group "unwind"; begin + (* RUN: grep {unwind} < %t.ll + *) + let bb05 = append_block "Bb05" fn in + let b = builder_at_end bb05 in + ignore (build_unwind b) + end; + + group "unreachable"; begin + (* RUN: grep {unreachable} < %t.ll + *) + let bb06 = append_block "Bb06" fn in + let b = builder_at_end bb06 in + ignore (build_unreachable b) + end; + + group "arithmetic"; begin + let bb07 = append_block "Bb07" fn in + let b = builder_at_end bb07 in + + (* RUN: grep {Inst03.*add.*P1.*P2} < %t.ll + * RUN: grep {Inst04.*sub.*P1.*Inst03} < %t.ll + * RUN: grep {Inst05.*mul.*P1.*Inst04} < %t.ll + * RUN: grep {Inst06.*udiv.*P1.*Inst05} < %t.ll + * RUN: grep {Inst07.*sdiv.*P1.*Inst06} < %t.ll + * RUN: grep {Inst08.*fdiv.*F1.*F2} < %t.ll + * RUN: grep {Inst09.*urem.*P1.*Inst07} < %t.ll + * RUN: grep {Inst10.*srem.*P1.*Inst09} < %t.ll + * RUN: grep {Inst11.*frem.*F1.*Inst08} < %t.ll + * RUN: grep {Inst12.*shl.*P1.*Inst10} < %t.ll + * RUN: grep {Inst13.*lshr.*P1.*Inst12} < %t.ll + * RUN: grep {Inst14.*ashr.*P1.*Inst13} < %t.ll + * RUN: grep {Inst15.*and.*P1.*Inst14} < %t.ll + * RUN: grep {Inst16.*or.*P1.*Inst15} < %t.ll + * RUN: grep {Inst17.*xor.*P1.*Inst16} < %t.ll + * RUN: grep {Inst18.*sub.*0.*Inst17} < %t.ll + * RUN: grep {Inst19.*xor.*Inst18.*-1} < %t.ll + *) + let inst03 = build_add p1 p2 "Inst03" b in + let inst04 = build_sub p1 inst03 "Inst04" b in + let inst05 = build_mul p1 inst04 "Inst05" b in + let inst06 = build_udiv p1 inst05 "Inst06" b in + let inst07 = build_sdiv p1 inst06 "Inst07" b in + let inst08 = build_fdiv f1 f2 "Inst08" b in + let inst09 = build_urem p1 inst07 "Inst09" b in + let inst10 = build_srem p1 inst09 "Inst10" b in + ignore(build_frem f1 inst08 "Inst11" b); + let inst12 = build_shl p1 inst10 "Inst12" b in + let inst13 = build_lshr p1 inst12 "Inst13" b in + let inst14 = build_ashr p1 inst13 "Inst14" b in + let inst15 = build_and p1 inst14 "Inst15" b in + let inst16 = build_or p1 inst15 "Inst16" b in + let inst17 = build_xor p1 inst16 "Inst17" b in + let inst18 = build_neg inst17 "Inst18" b in + ignore (build_not inst18 "Inst19" b) + end; + + group "memory"; begin + let bb08 = append_block "Bb08" fn in + let b = builder_at_end bb08 in + + (* RUN: grep {Inst20.*malloc.*i8 } < %t.ll + * RUN: grep {Inst21.*malloc.*i8.*P1} < %t.ll + * RUN: grep {Inst22.*alloca.*i32 } < %t.ll + * RUN: grep {Inst23.*alloca.*i32.*P2} < %t.ll + * RUN: grep {free.*Inst20} < %t.ll + * RUN: grep {Inst25.*load.*Inst21} < %t.ll + * RUN: grep {store.*P2.*Inst22} < %t.ll + * RUN: grep {Inst27.*getelementptr.*Inst23.*P2} < %t.ll + *) + let inst20 = build_malloc i8_type "Inst20" b in + let inst21 = build_array_malloc i8_type p1 "Inst21" b in + let inst22 = build_alloca i32_type "Inst22" b in + let inst23 = build_array_alloca i32_type p2 "Inst23" b in + ignore(build_free inst20 b); + ignore(build_load inst21 "Inst25" b); + ignore(build_store p2 inst22 b); + ignore(build_gep inst23 [| p2 |] "Inst27" b) + end; + + group "casts"; begin + let void_ptr = make_pointer_type i8_type in + + (* RUN: grep {Inst28.*trunc.*P1.*i8} < %t.ll + * RUN: grep {Inst29.*zext.*Inst28.*i32} < %t.ll + * RUN: grep {Inst30.*sext.*Inst29.*i64} < %t.ll + * RUN: grep {Inst31.*uitofp.*Inst30.*float} < %t.ll + * RUN: grep {Inst32.*sitofp.*Inst29.*double} < %t.ll + * RUN: grep {Inst33.*fptoui.*Inst31.*i32} < %t.ll + * RUN: grep {Inst34.*fptosi.*Inst32.*i64} < %t.ll + * RUN: grep {Inst35.*fptrunc.*Inst32.*float} < %t.ll + * RUN: grep {Inst36.*fpext.*Inst35.*double} < %t.ll + * RUN: grep {Inst37.*inttoptr.*P1.*i8\*} < %t.ll + * RUN: grep {Inst38.*ptrtoint.*Inst37.*i64} < %t.ll + * RUN: grep {Inst39.*bitcast.*Inst38.*double} < %t.ll + *) + let inst28 = build_trunc p1 i8_type "Inst28" atentry in + let inst29 = build_zext inst28 i32_type "Inst29" atentry in + let inst30 = build_sext inst29 i64_type "Inst30" atentry in + let inst31 = build_uitofp inst30 float_type "Inst31" atentry in + let inst32 = build_sitofp inst29 double_type "Inst32" atentry in + ignore(build_fptoui inst31 i32_type "Inst33" atentry); + ignore(build_fptosi inst32 i64_type "Inst34" atentry); + let inst35 = build_fptrunc inst32 float_type "Inst35" atentry in + ignore(build_fpext inst35 double_type "Inst36" atentry); + let inst37 = build_inttoptr p1 void_ptr "Inst37" atentry in + let inst38 = build_ptrtoint inst37 i64_type "Inst38" atentry in + ignore(build_bitcast inst38 double_type "Inst39" atentry) + end; + + group "comparisons"; begin + (* RUN: grep {Inst40.*icmp.*ne.*P1.*P2} < %t.ll + * RUN: grep {Inst41.*icmp.*sle.*P2.*P1} < %t.ll + * RUN: grep {Inst42.*fcmp.*false.*F1.*F2} < %t.ll + * RUN: grep {Inst43.*fcmp.*true.*F2.*F1} < %t.ll + *) + ignore (build_icmp Icmp_ne p1 p2 "Inst40" atentry); + ignore (build_icmp Icmp_sle p2 p1 "Inst41" atentry); + ignore (build_fcmp Fcmp_false f1 f2 "Inst42" atentry); + ignore (build_fcmp Fcmp_true f2 f1 "Inst43" atentry) + end; + + group "miscellaneous"; begin + (* RUN: grep {Inst45.*call.*P2.*P1} < %t.ll + * RUN: grep {Inst47.*select.*Inst46.*P1.*P2} < %t.ll + * RUN: grep {Inst48.*va_arg.*null.*i32} < %t.ll + * RUN: grep {Inst49.*extractelement.*Vec1.*P2} < %t.ll + * RUN: grep {Inst50.*insertelement.*Vec1.*P1.*P2} < %t.ll + * RUN: grep {Inst51.*shufflevector.*Vec1.*Vec2.*Vec3} < %t.ll + *) + + (* TODO: %Inst44 = Phi *) + + ignore (build_call fn [| p2; p1 |] "Inst45" atentry); + let inst46 = build_icmp Icmp_eq p1 p2 "Inst46" atentry in + ignore (build_select inst46 p1 p2 "Inst47" atentry); + ignore (build_va_arg + (make_null (make_pointer_type (make_pointer_type i8_type))) + i32_type "Inst48" atentry); + + (* Set up some vector vregs. *) + let one = make_int_constant i32_type (-1) true in + let zero = make_int_constant i32_type 1 true in + let t1 = make_vector_constant [| one; zero; one; zero |] in + let t2 = make_vector_constant [| zero; one; zero; one |] in + let t3 = make_vector_constant [| one; one; zero; zero |] in + let vec1 = build_insertelement t1 p1 p2 "Vec1" atentry in + let vec2 = build_insertelement t2 p1 p2 "Vec2" atentry in + let vec3 = build_insertelement t3 p1 p2 "Vec3" atentry in + + ignore (build_extractelement vec1 p2 "Inst49" atentry); + ignore (build_insertelement vec1 p1 p2 "Inst50" atentry); + ignore (build_shufflevector vec1 vec2 vec3 "Inst51" atentry); + end + + (*===-- Writer ------------------------------------------------------------===*) let test_writer () = @@ -322,5 +637,8 @@ let _ = suite "constants" test_constants; suite "global values" test_global_values; suite "global variables" test_global_variables; + suite "functions" test_functions; + suite "basic blocks" test_basic_blocks; + suite "builder" test_builder; suite "writer" test_writer; exit !exit_status -- 2.34.1