X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=bindings%2Focaml%2Fllvm%2Fllvm_ocaml.c;h=f0143a01a9be03659fd2690bffb3d2aaaf0797fd;hp=d095550962297737f29e6fa720bd8d92f4f4d028;hb=601bf96887c0f7ec4fbd9a8d9a4e03f8e434ec0c;hpb=a353ffa7e556bfd2864474911174da691117f691 diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c index d0955509622..f0143a01a9b 100644 --- a/bindings/ocaml/llvm/llvm_ocaml.c +++ b/bindings/ocaml/llvm/llvm_ocaml.c @@ -1,13 +1,13 @@ -/*===-- llvm_ocaml.h - LLVM Ocaml Glue --------------------------*- C++ -*-===*\ +/*===-- llvm_ocaml.c - LLVM OCaml Glue --------------------------*- C++ -*-===*\ |* *| |* The LLVM Compiler Infrastructure *| |* *| -|* This file was developed by Gordon Henriksen and is distributed under the *| -|* University of Illinois Open Source License. See LICENSE.TXT for details. *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| |* *| |*===----------------------------------------------------------------------===*| |* *| -|* This file glues LLVM's ocaml interface to its C interface. These functions *| +|* This file glues LLVM's OCaml interface to its C interface. These functions *| |* are by and large transparent wrappers to the corresponding C functions. *| |* *| |* Note that these functions intentionally take liberties with the CAMLparamX *| @@ -21,9 +21,9 @@ #include "caml/memory.h" #include "caml/fail.h" #include "caml/callback.h" -#include "llvm/Config/config.h" #include #include +#include /* Can't use the recommended caml_named_value mechanism for backwards @@ -33,6 +33,7 @@ static value llvm_ioerror_exn; CAMLprim value llvm_register_core_exns(value IoError) { llvm_ioerror_exn = Field(IoError, 0); register_global_root(&llvm_ioerror_exn); + return Val_unit; } @@ -45,15 +46,107 @@ static void llvm_raise(value Prototype, char *Message) { raise_with_arg(Prototype, CamlMessage); abort(); /* NOTREACHED */ - CAMLnoreturn; +#ifdef CAMLnoreturn + CAMLnoreturn; /* Silences warnings, but is missing in some versions. */ +#endif +} + +static value llvm_fatal_error_handler; + +static void llvm_fatal_error_trampoline(const char *Reason) { + callback(llvm_fatal_error_handler, copy_string(Reason)); +} + +CAMLprim value llvm_install_fatal_error_handler(value Handler) { + LLVMInstallFatalErrorHandler(llvm_fatal_error_trampoline); + llvm_fatal_error_handler = Handler; + caml_register_global_root(&llvm_fatal_error_handler); + return Val_unit; +} + +CAMLprim value llvm_reset_fatal_error_handler(value Unit) { + caml_remove_global_root(&llvm_fatal_error_handler); + LLVMResetFatalErrorHandler(); + return Val_unit; } +CAMLprim value llvm_enable_pretty_stacktrace(value Unit) { + LLVMEnablePrettyStackTrace(); + return Val_unit; +} + +static value alloc_variant(int tag, void *Value) { + value Iter = alloc_small(1, tag); + Field(Iter, 0) = Val_op(Value); + return Iter; +} + +/* Macro to convert the C first/next/last/prev idiom to the Ocaml llpos/ + llrev_pos idiom. */ +#define DEFINE_ITERATORS(camlname, cname, pty, cty, pfun) \ + /* llmodule -> ('a, 'b) llpos */ \ + CAMLprim value llvm_##camlname##_begin(pty Mom) { \ + cty First = LLVMGetFirst##cname(Mom); \ + if (First) \ + return alloc_variant(1, First); \ + return alloc_variant(0, Mom); \ + } \ + \ + /* llvalue -> ('a, 'b) llpos */ \ + CAMLprim value llvm_##camlname##_succ(cty Kid) { \ + cty Next = LLVMGetNext##cname(Kid); \ + if (Next) \ + return alloc_variant(1, Next); \ + return alloc_variant(0, pfun(Kid)); \ + } \ + \ + /* llmodule -> ('a, 'b) llrev_pos */ \ + CAMLprim value llvm_##camlname##_end(pty Mom) { \ + cty Last = LLVMGetLast##cname(Mom); \ + if (Last) \ + return alloc_variant(1, Last); \ + return alloc_variant(0, Mom); \ + } \ + \ + /* llvalue -> ('a, 'b) llrev_pos */ \ + CAMLprim value llvm_##camlname##_pred(cty Kid) { \ + cty Prev = LLVMGetPrevious##cname(Kid); \ + if (Prev) \ + return alloc_variant(1, Prev); \ + return alloc_variant(0, pfun(Kid)); \ + } + + +/*===-- Contexts ----------------------------------------------------------===*/ + +/* unit -> llcontext */ +CAMLprim LLVMContextRef llvm_create_context(value Unit) { + return LLVMContextCreate(); +} + +/* llcontext -> unit */ +CAMLprim value llvm_dispose_context(LLVMContextRef C) { + LLVMContextDispose(C); + return Val_unit; +} + +/* unit -> llcontext */ +CAMLprim LLVMContextRef llvm_global_context(value Unit) { + return LLVMGetGlobalContext(); +} + +/* llcontext -> string -> int */ +CAMLprim value llvm_mdkind_id(LLVMContextRef C, value Name) { + unsigned MDKindID = LLVMGetMDKindIDInContext(C, String_val(Name), + caml_string_length(Name)); + return Val_int(MDKindID); +} /*===-- Modules -----------------------------------------------------------===*/ -/* string -> llmodule */ -CAMLprim LLVMModuleRef llvm_create_module(value ModuleID) { - return LLVMModuleCreateWithName(String_val(ModuleID)); +/* llcontext -> string -> llmodule */ +CAMLprim LLVMModuleRef llvm_create_module(LLVMContextRef C, value ModuleID) { + return LLVMModuleCreateWithNameInContext(String_val(ModuleID), C); } /* llmodule -> unit */ @@ -84,18 +177,38 @@ CAMLprim value llvm_set_data_layout(value Layout, LLVMModuleRef M) { return Val_unit; } -/* string -> lltype -> llmodule -> bool */ -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); +/* llmodule -> unit */ +CAMLprim value llvm_dump_module(LLVMModuleRef M) { + LLVMDumpModule(M); + return Val_unit; } /* string -> llmodule -> unit */ -CAMLprim value llvm_delete_type_name(value Name, LLVMModuleRef M) { - LLVMDeleteTypeName(M, String_val(Name)); +CAMLprim value llvm_print_module(value Filename, LLVMModuleRef M) { + char* Message; + if(LLVMPrintModuleToFile(M, String_val(Filename), &Message)) { + llvm_raise(llvm_ioerror_exn, Message); + } + return Val_unit; } +/* llmodule -> string */ +CAMLprim value llvm_string_of_llmodule(LLVMModuleRef M) { + char* ModuleCStr; + ModuleCStr = LLVMPrintModuleToString(M); + + value ModuleStr = caml_copy_string(ModuleCStr); + LLVMDisposeMessage(ModuleCStr); + + return ModuleStr; +} + +/* llmodule -> string -> unit */ +CAMLprim value llvm_set_module_inline_asm(LLVMModuleRef M, value Asm) { + LLVMSetModuleInlineAsm(M, String_val(Asm)); + return Val_unit; +} /*===-- Types -------------------------------------------------------------===*/ @@ -104,18 +217,62 @@ CAMLprim value llvm_classify_type(LLVMTypeRef Ty) { return Val_int(LLVMGetTypeKind(Ty)); } +CAMLprim value llvm_type_is_sized(LLVMTypeRef Ty) { + return Val_bool(LLVMTypeIsSized(Ty)); +} + +/* lltype -> llcontext */ +CAMLprim LLVMContextRef llvm_type_context(LLVMTypeRef Ty) { + return LLVMGetTypeContext(Ty); +} + +/* lltype -> unit */ +CAMLprim value llvm_dump_type(LLVMTypeRef Val) { + LLVMDumpType(Val); + return Val_unit; +} + +/* lltype -> string */ +CAMLprim value llvm_string_of_lltype(LLVMTypeRef M) { + char* TypeCStr; + TypeCStr = LLVMPrintTypeToString(M); + + value TypeStr = caml_copy_string(TypeCStr); + LLVMDisposeMessage(TypeCStr); + + return TypeStr; +} + /*--... Operations on integer types ........................................--*/ -/* unit -> lltype */ -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(); } +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_i1_type (LLVMContextRef Context) { + return LLVMInt1TypeInContext(Context); +} + +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_i8_type (LLVMContextRef Context) { + return LLVMInt8TypeInContext(Context); +} + +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_i16_type (LLVMContextRef Context) { + return LLVMInt16TypeInContext(Context); +} + +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_i32_type (LLVMContextRef Context) { + return LLVMInt32TypeInContext(Context); +} + +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_i64_type (LLVMContextRef Context) { + return LLVMInt64TypeInContext(Context); +} -/* int -> lltype */ -CAMLprim LLVMTypeRef llvm_integer_type(value Width) { - return LLVMIntType(Int_val(Width)); +/* llcontext -> int -> lltype */ +CAMLprim LLVMTypeRef llvm_integer_type(LLVMContextRef Context, value Width) { + return LLVMIntTypeInContext(Context, Int_val(Width)); } /* lltype -> int */ @@ -125,29 +282,29 @@ CAMLprim value llvm_integer_bitwidth(LLVMTypeRef IntegerTy) { /*--... Operations on real types ...........................................--*/ -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_float_type(value Unit) { - return LLVMFloatType(); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_float_type(LLVMContextRef Context) { + return LLVMFloatTypeInContext(Context); } -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_double_type(value Unit) { - return LLVMDoubleType(); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_double_type(LLVMContextRef Context) { + return LLVMDoubleTypeInContext(Context); } -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_x86fp80_type(value Unit) { - return LLVMX86FP80Type(); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_x86fp80_type(LLVMContextRef Context) { + return LLVMX86FP80TypeInContext(Context); } -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_fp128_type(value Unit) { - return LLVMFP128Type(); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_fp128_type(LLVMContextRef Context) { + return LLVMFP128TypeInContext(Context); } -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_ppc_fp128_type(value Unit) { - return LLVMPPCFP128Type(); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_ppc_fp128_type(LLVMContextRef Context) { + return LLVMPPCFP128TypeInContext(Context); } /*--... Operations on function types .......................................--*/ @@ -179,20 +336,49 @@ CAMLprim value llvm_param_types(LLVMTypeRef FunTy) { /*--... Operations on struct types .........................................--*/ -/* lltype array -> lltype */ -CAMLprim LLVMTypeRef llvm_struct_type(value ElementTypes) { - return LLVMStructType((LLVMTypeRef *) ElementTypes, - Wosize_val(ElementTypes), 0); +/* llcontext -> lltype array -> lltype */ +CAMLprim LLVMTypeRef llvm_struct_type(LLVMContextRef C, value ElementTypes) { + return LLVMStructTypeInContext(C, (LLVMTypeRef *) ElementTypes, + Wosize_val(ElementTypes), 0); +} + +/* llcontext -> lltype array -> lltype */ +CAMLprim LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C, + value ElementTypes) { + return LLVMStructTypeInContext(C, (LLVMTypeRef *) ElementTypes, + Wosize_val(ElementTypes), 1); } -/* lltype array -> lltype */ -CAMLprim LLVMTypeRef llvm_packed_struct_type(value ElementTypes) { - return LLVMStructType((LLVMTypeRef *) ElementTypes, - Wosize_val(ElementTypes), 1); +/* llcontext -> string -> lltype */ +CAMLprim LLVMTypeRef llvm_named_struct_type(LLVMContextRef C, + value Name) { + return LLVMStructCreateNamed(C, String_val(Name)); +} + +CAMLprim value llvm_struct_set_body(LLVMTypeRef Ty, + value ElementTypes, + value Packed) { + LLVMStructSetBody(Ty, (LLVMTypeRef *) ElementTypes, + Wosize_val(ElementTypes), Bool_val(Packed)); + return Val_unit; +} + +/* lltype -> string option */ +CAMLprim value llvm_struct_name(LLVMTypeRef Ty) +{ + CAMLparam0(); + const char *C = LLVMGetStructName(Ty); + if (C) { + CAMLlocal1(result); + result = caml_alloc_small(1, 0); + Store_field(result, 0, caml_copy_string(C)); + CAMLreturn(result); + } + CAMLreturn(Val_int(0)); } /* lltype -> lltype array */ -CAMLprim value llvm_element_types(LLVMTypeRef StructTy) { +CAMLprim value llvm_struct_element_types(LLVMTypeRef StructTy) { value Tys = alloc(LLVMCountStructElementTypes(StructTy), 0); LLVMGetStructElementTypes(StructTy, (LLVMTypeRef *) Tys); return Tys; @@ -203,6 +389,11 @@ CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) { return Val_bool(LLVMIsPackedStruct(StructTy)); } +/* lltype -> bool */ +CAMLprim value llvm_is_opaque(LLVMTypeRef StructTy) { + return Val_bool(LLVMIsOpaqueStruct(StructTy)); +} + /*--... Operations on array, pointer, and vector types .....................--*/ /* lltype -> int -> lltype */ @@ -243,48 +434,33 @@ CAMLprim value llvm_vector_size(LLVMTypeRef VectorTy) { /*--... Operations on other types ..........................................--*/ -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_void_type (value Unit) { return LLVMVoidType(); } -CAMLprim LLVMTypeRef llvm_label_type(value Unit) { return LLVMLabelType(); } - -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_opaque_type(value Unit) { - return LLVMOpaqueType(); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_void_type (LLVMContextRef Context) { + return LLVMVoidTypeInContext(Context); } -/*--... Operations on type handles .........................................--*/ - -#define Typehandle_val(v) (*(LLVMTypeHandleRef *)(Data_custom_val(v))) - -static void llvm_finalize_handle(value TH) { - LLVMDisposeTypeHandle(Typehandle_val(TH)); -} - -static struct custom_operations typehandle_ops = { - (char *) "LLVMTypeHandle", - llvm_finalize_handle, - custom_compare_default, - custom_hash_default, - custom_serialize_default, - custom_deserialize_default -}; - -CAMLprim value llvm_handle_to_type(LLVMTypeRef PATy) { - value TH = alloc_custom(&typehandle_ops, sizeof(LLVMBuilderRef), 0, 1); - Typehandle_val(TH) = LLVMCreateTypeHandle(PATy); - return TH; +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_label_type(LLVMContextRef Context) { + return LLVMLabelTypeInContext(Context); } -CAMLprim LLVMTypeRef llvm_type_of_handle(value TH) { - return LLVMResolveTypeHandle(Typehandle_val(TH)); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_x86_mmx_type(LLVMContextRef Context) { + return LLVMX86MMXTypeInContext(Context); } -CAMLprim value llvm_refine_type(LLVMTypeRef AbstractTy, LLVMTypeRef ConcreteTy){ - LLVMRefineAbstractType(AbstractTy, ConcreteTy); - return Val_unit; +CAMLprim value llvm_type_by_name(LLVMModuleRef M, value Name) +{ + CAMLparam1(Name); + LLVMTypeRef Ty = LLVMGetTypeByName(M, String_val(Name)); + if (Ty) { + value Option = alloc(1, 0); + Field(Option, 0) = (value) Ty; + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); } - /*===-- VALUES ------------------------------------------------------------===*/ /* llvalue -> lltype */ @@ -292,6 +468,73 @@ CAMLprim LLVMTypeRef llvm_type_of(LLVMValueRef Val) { return LLVMTypeOf(Val); } +/* keep in sync with ValueKind.t */ +enum ValueKind { + NullValue=0, + Argument, + BasicBlock, + InlineAsm, + MDNode, + MDString, + BlockAddress, + ConstantAggregateZero, + ConstantArray, + ConstantDataArray, + ConstantDataVector, + ConstantExpr, + ConstantFP, + ConstantInt, + ConstantPointerNull, + ConstantStruct, + ConstantVector, + Function, + GlobalAlias, + GlobalVariable, + UndefValue, + Instruction +}; + +/* llvalue -> ValueKind.t */ +#define DEFINE_CASE(Val, Kind) \ + do {if (LLVMIsA##Kind(Val)) CAMLreturn(Val_int(Kind));} while(0) + +CAMLprim value llvm_classify_value(LLVMValueRef Val) { + CAMLparam0(); + if (!Val) + CAMLreturn(Val_int(NullValue)); + if (LLVMIsAConstant(Val)) { + DEFINE_CASE(Val, BlockAddress); + DEFINE_CASE(Val, ConstantAggregateZero); + DEFINE_CASE(Val, ConstantArray); + DEFINE_CASE(Val, ConstantDataArray); + DEFINE_CASE(Val, ConstantDataVector); + DEFINE_CASE(Val, ConstantExpr); + DEFINE_CASE(Val, ConstantFP); + DEFINE_CASE(Val, ConstantInt); + DEFINE_CASE(Val, ConstantPointerNull); + DEFINE_CASE(Val, ConstantStruct); + DEFINE_CASE(Val, ConstantVector); + } + if (LLVMIsAInstruction(Val)) { + CAMLlocal1(result); + result = caml_alloc_small(1, 0); + Store_field(result, 0, Val_int(LLVMGetInstructionOpcode(Val))); + CAMLreturn(result); + } + if (LLVMIsAGlobalValue(Val)) { + DEFINE_CASE(Val, Function); + DEFINE_CASE(Val, GlobalAlias); + DEFINE_CASE(Val, GlobalVariable); + } + DEFINE_CASE(Val, Argument); + DEFINE_CASE(Val, BasicBlock); + DEFINE_CASE(Val, InlineAsm); + DEFINE_CASE(Val, MDNode); + DEFINE_CASE(Val, MDString); + DEFINE_CASE(Val, UndefValue); + failwith("Unknown Value class"); +} + /* llvalue -> string */ CAMLprim value llvm_value_name(LLVMValueRef Val) { return copy_string(LLVMGetValueName(Val)); @@ -309,6 +552,47 @@ CAMLprim value llvm_dump_value(LLVMValueRef Val) { return Val_unit; } +/* llvalue -> string */ +CAMLprim value llvm_string_of_llvalue(LLVMValueRef M) { + char* ValueCStr; + ValueCStr = LLVMPrintValueToString(M); + + value ValueStr = caml_copy_string(ValueCStr); + LLVMDisposeMessage(ValueCStr); + + return ValueStr; +} + +/* llvalue -> llvalue -> unit */ +CAMLprim value llvm_replace_all_uses_with(LLVMValueRef OldVal, + LLVMValueRef NewVal) { + LLVMReplaceAllUsesWith(OldVal, NewVal); + return Val_unit; +} + +/*--... Operations on users ................................................--*/ + +/* llvalue -> int -> llvalue */ +CAMLprim LLVMValueRef llvm_operand(LLVMValueRef V, value I) { + return LLVMGetOperand(V, Int_val(I)); +} + +/* llvalue -> int -> lluse */ +CAMLprim LLVMUseRef llvm_operand_use(LLVMValueRef V, value I) { + return LLVMGetOperandUse(V, Int_val(I)); +} + +/* llvalue -> int -> llvalue -> unit */ +CAMLprim value llvm_set_operand(LLVMValueRef U, value I, LLVMValueRef V) { + LLVMSetOperand(U, Int_val(I), V); + return Val_unit; +} + +/* llvalue -> int */ +CAMLprim value llvm_num_operands(LLVMValueRef V) { + return Val_int(LLVMGetNumOperands(V)); +} + /*--... Operations on constants of (mostly) any type .......................--*/ /* llvalue -> bool */ @@ -326,11 +610,97 @@ CAMLprim value llvm_is_undef(LLVMValueRef Val) { return Val_bool(LLVMIsUndef(Val)); } +/* llvalue -> Opcode.t */ +CAMLprim value llvm_constexpr_get_opcode(LLVMValueRef Val) { + return LLVMIsAConstantExpr(Val) ? + Val_int(LLVMGetConstOpcode(Val)) : Val_int(0); +} + +/*--... Operations on instructions .........................................--*/ + +/* llvalue -> bool */ +CAMLprim value llvm_has_metadata(LLVMValueRef Val) { + return Val_bool(LLVMHasMetadata(Val)); +} + +/* llvalue -> int -> llvalue option */ +CAMLprim value llvm_metadata(LLVMValueRef Val, value MDKindID) { + CAMLparam1(MDKindID); + LLVMValueRef MD; + if ((MD = LLVMGetMetadata(Val, Int_val(MDKindID)))) { + value Option = alloc(1, 0); + Field(Option, 0) = (value) MD; + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + +/* llvalue -> int -> llvalue -> unit */ +CAMLprim value llvm_set_metadata(LLVMValueRef Val, value MDKindID, + LLVMValueRef MD) { + LLVMSetMetadata(Val, Int_val(MDKindID), MD); + return Val_unit; +} + +/* llvalue -> int -> unit */ +CAMLprim value llvm_clear_metadata(LLVMValueRef Val, value MDKindID) { + LLVMSetMetadata(Val, Int_val(MDKindID), NULL); + return Val_unit; +} + + +/*--... Operations on metadata .............................................--*/ + +/* llcontext -> string -> llvalue */ +CAMLprim LLVMValueRef llvm_mdstring(LLVMContextRef C, value S) { + return LLVMMDStringInContext(C, String_val(S), caml_string_length(S)); +} + +/* llcontext -> llvalue array -> llvalue */ +CAMLprim LLVMValueRef llvm_mdnode(LLVMContextRef C, value ElementVals) { + return LLVMMDNodeInContext(C, (LLVMValueRef*) Op_val(ElementVals), + Wosize_val(ElementVals)); +} + +/* llvalue -> string option */ +CAMLprim value llvm_get_mdstring(LLVMValueRef V) { + CAMLparam0(); + const char *S; + unsigned Len; + + if ((S = LLVMGetMDString(V, &Len))) { + CAMLlocal2(Option, Str); + + Str = caml_alloc_string(Len); + memcpy(String_val(Str), S, Len); + Option = alloc(1,0); + Store_field(Option, 0, Str); + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + +/* llmodule -> string -> llvalue array */ +CAMLprim value llvm_get_namedmd(LLVMModuleRef M, value Name) +{ + CAMLparam1(Name); + CAMLlocal1(Nodes); + Nodes = alloc(LLVMGetNamedMetadataNumOperands(M, String_val(Name)), 0); + LLVMGetNamedMetadataOperands(M, String_val(Name), (LLVMValueRef *) Nodes); + CAMLreturn(Nodes); +} + +/* llmodule -> string -> llvalue -> unit */ +CAMLprim value llvm_append_namedmd(LLVMModuleRef M, value Name, LLVMValueRef Val) { + LLVMAddNamedMetadataOperand(M, String_val(Name), Val); + return Val_unit; +} + /*--... Operations on scalar constants .....................................--*/ /* lltype -> int -> llvalue */ CAMLprim LLVMValueRef llvm_const_int(LLVMTypeRef IntTy, value N) { - return LLVMConstInt(IntTy, (long long) Int_val(N), 1); + return LLVMConstInt(IntTy, (long long) Long_val(N), 1); } /* lltype -> Int64.t -> bool -> llvalue */ @@ -339,21 +709,51 @@ CAMLprim LLVMValueRef llvm_const_of_int64(LLVMTypeRef IntTy, value N, return LLVMConstInt(IntTy, Int64_val(N), Bool_val(SExt)); } +/* llvalue -> Int64.t */ +CAMLprim value llvm_int64_of_const(LLVMValueRef Const) +{ + CAMLparam0(); + if (LLVMIsAConstantInt(Const) && + LLVMGetIntTypeWidth(LLVMTypeOf(Const)) <= 64) { + value Option = alloc(1, 0); + Field(Option, 0) = caml_copy_int64(LLVMConstIntGetSExtValue(Const)); + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + +/* lltype -> string -> int -> llvalue */ +CAMLprim LLVMValueRef llvm_const_int_of_string(LLVMTypeRef IntTy, value S, + value Radix) { + return LLVMConstIntOfStringAndSize(IntTy, String_val(S), caml_string_length(S), + Int_val(Radix)); +} + /* lltype -> float -> llvalue */ CAMLprim LLVMValueRef llvm_const_float(LLVMTypeRef RealTy, value N) { return LLVMConstReal(RealTy, Double_val(N)); } +/* lltype -> string -> llvalue */ +CAMLprim LLVMValueRef llvm_const_float_of_string(LLVMTypeRef RealTy, value S) { + return LLVMConstRealOfStringAndSize(RealTy, String_val(S), + caml_string_length(S)); +} + /*--... Operations on composite constants ..................................--*/ -/* string -> llvalue */ -CAMLprim LLVMValueRef llvm_const_string(value Str, value NullTerminate) { - return LLVMConstString(String_val(Str), string_length(Str), 1); +/* llcontext -> string -> llvalue */ +CAMLprim LLVMValueRef llvm_const_string(LLVMContextRef Context, value Str, + value NullTerminate) { + return LLVMConstStringInContext(Context, String_val(Str), string_length(Str), + 1); } -/* string -> llvalue */ -CAMLprim LLVMValueRef llvm_const_stringz(value Str, value NullTerminate) { - return LLVMConstString(String_val(Str), string_length(Str), 0); +/* llcontext -> string -> llvalue */ +CAMLprim LLVMValueRef llvm_const_stringz(LLVMContextRef Context, value Str, + value NullTerminate) { + return LLVMConstStringInContext(Context, String_val(Str), string_length(Str), + 0); } /* lltype -> llvalue array -> llvalue */ @@ -363,16 +763,22 @@ CAMLprim LLVMValueRef llvm_const_array(LLVMTypeRef ElementTy, Wosize_val(ElementVals)); } -/* llvalue array -> llvalue */ -CAMLprim LLVMValueRef llvm_const_struct(value ElementVals) { - return LLVMConstStruct((LLVMValueRef *) Op_val(ElementVals), - Wosize_val(ElementVals), 0); +/* llcontext -> llvalue array -> llvalue */ +CAMLprim LLVMValueRef llvm_const_struct(LLVMContextRef C, value ElementVals) { + return LLVMConstStructInContext(C, (LLVMValueRef *) Op_val(ElementVals), + Wosize_val(ElementVals), 0); } -/* llvalue array -> llvalue */ -CAMLprim LLVMValueRef llvm_const_packed_struct(value ElementVals) { - return LLVMConstStruct((LLVMValueRef *) Op_val(ElementVals), - Wosize_val(ElementVals), 1); +/* lltype -> llvalue array -> llvalue */ +CAMLprim LLVMValueRef llvm_const_named_struct(LLVMTypeRef Ty, value ElementVals) { + return LLVMConstNamedStruct(Ty, (LLVMValueRef *) Op_val(ElementVals), Wosize_val(ElementVals)); +} + +/* llcontext -> llvalue array -> llvalue */ +CAMLprim LLVMValueRef llvm_const_packed_struct(LLVMContextRef C, + value ElementVals) { + return LLVMConstStructInContext(C, (LLVMValueRef *) Op_val(ElementVals), + Wosize_val(ElementVals), 1); } /* llvalue array -> llvalue */ @@ -381,6 +787,31 @@ CAMLprim LLVMValueRef llvm_const_vector(value ElementVals) { Wosize_val(ElementVals)); } +/* llvalue -> string option */ +CAMLprim value llvm_string_of_const(LLVMValueRef Const) { + const char *S; + size_t Len; + CAMLparam0(); + CAMLlocal2(Option, Str); + + if(LLVMIsAConstantDataSequential(Const) && LLVMIsConstantString(Const)) { + S = LLVMGetAsString(Const, &Len); + Str = caml_alloc_string(Len); + memcpy(String_val(Str), S, Len); + + Option = alloc(1, 0); + Field(Option, 0) = Str; + CAMLreturn(Option); + } else { + CAMLreturn(Val_int(0)); + } +} + +/* llvalue -> int -> llvalue */ +CAMLprim LLVMValueRef llvm_const_element(LLVMValueRef Const, value N) { + return LLVMGetElementAsConstant(Const, Int_val(N)); +} + /*--... Constant expressions ...............................................--*/ /* Icmp.t -> llvalue -> llvalue -> llvalue */ @@ -403,6 +834,63 @@ CAMLprim LLVMValueRef llvm_const_gep(LLVMValueRef ConstantVal, value Indices) { Wosize_val(Indices)); } +/* llvalue -> llvalue array -> llvalue */ +CAMLprim LLVMValueRef llvm_const_in_bounds_gep(LLVMValueRef ConstantVal, + value Indices) { + return LLVMConstInBoundsGEP(ConstantVal, (LLVMValueRef*) Op_val(Indices), + Wosize_val(Indices)); +} + +/* llvalue -> lltype -> is_signed:bool -> llvalue */ +CAMLprim LLVMValueRef llvm_const_intcast(LLVMValueRef CV, LLVMTypeRef T, + value IsSigned) { + return LLVMConstIntCast(CV, T, Bool_val(IsSigned)); +} + +/* llvalue -> int array -> llvalue */ +CAMLprim LLVMValueRef llvm_const_extractvalue(LLVMValueRef Aggregate, + value Indices) { + CAMLparam1(Indices); + int size = Wosize_val(Indices); + int i; + LLVMValueRef result; + + unsigned* idxs = (unsigned*)malloc(size * sizeof(unsigned)); + for (i = 0; i < size; i++) { + idxs[i] = Int_val(Field(Indices, i)); + } + + result = LLVMConstExtractValue(Aggregate, idxs, size); + free(idxs); + CAMLreturnT(LLVMValueRef, result); +} + +/* llvalue -> llvalue -> int array -> llvalue */ +CAMLprim LLVMValueRef llvm_const_insertvalue(LLVMValueRef Aggregate, + LLVMValueRef Val, value Indices) { + CAMLparam1(Indices); + int size = Wosize_val(Indices); + int i; + LLVMValueRef result; + + unsigned* idxs = (unsigned*)malloc(size * sizeof(unsigned)); + for (i = 0; i < size; i++) { + idxs[i] = Int_val(Field(Indices, i)); + } + + result = LLVMConstInsertValue(Aggregate, Val, idxs, size); + free(idxs); + CAMLreturnT(LLVMValueRef, result); +} + +/* lltype -> string -> string -> bool -> bool -> llvalue */ +CAMLprim LLVMValueRef llvm_const_inline_asm(LLVMTypeRef Ty, value Asm, + value Constraints, value HasSideEffects, + value IsAlignStack) { + return LLVMConstInlineAsm(Ty, String_val(Asm), String_val(Constraints), + Bool_val(HasSideEffects), Bool_val(IsAlignStack)); +} + /*--... Operations on global variables, functions, and aliases (globals) ...--*/ /* llvalue -> bool */ @@ -454,8 +942,47 @@ CAMLprim value llvm_set_alignment(value Bytes, LLVMValueRef Global) { return Val_unit; } +/*--... Operations on uses .................................................--*/ + +/* llvalue -> lluse option */ +CAMLprim value llvm_use_begin(LLVMValueRef Val) { + CAMLparam0(); + LLVMUseRef First; + if ((First = LLVMGetFirstUse(Val))) { + value Option = alloc(1, 0); + Field(Option, 0) = (value) First; + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + +/* lluse -> lluse option */ +CAMLprim value llvm_use_succ(LLVMUseRef U) { + CAMLparam0(); + LLVMUseRef Next; + if ((Next = LLVMGetNextUse(U))) { + value Option = alloc(1, 0); + Field(Option, 0) = (value) Next; + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + +/* lluse -> llvalue */ +CAMLprim LLVMValueRef llvm_user(LLVMUseRef UR) { + return LLVMGetUser(UR); +} + +/* lluse -> llvalue */ +CAMLprim LLVMValueRef llvm_used_value(LLVMUseRef UR) { + return LLVMGetUsedValue(UR); +} + /*--... Operations on global variables .....................................--*/ +DEFINE_ITERATORS(global, Global, LLVMModuleRef, LLVMValueRef, + LLVMGetGlobalParent) + /* lltype -> string -> llmodule -> llvalue */ CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name, LLVMModuleRef M) { @@ -468,6 +995,21 @@ CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name, return LLVMAddGlobal(M, Ty, String_val(Name)); } +/* lltype -> string -> int -> llmodule -> llvalue */ +CAMLprim LLVMValueRef llvm_declare_qualified_global(LLVMTypeRef Ty, value Name, + value AddressSpace, + LLVMModuleRef M) { + LLVMValueRef GlobalVar; + if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) { + if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty) + return LLVMConstBitCast(GlobalVar, + LLVMPointerType(Ty, Int_val(AddressSpace))); + return GlobalVar; + } + return LLVMAddGlobalInAddressSpace(M, Ty, String_val(Name), + Int_val(AddressSpace)); +} + /* string -> llmodule -> llvalue option */ CAMLprim value llvm_lookup_global(value Name, LLVMModuleRef M) { CAMLparam1(Name); @@ -489,6 +1031,19 @@ CAMLprim LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer, return GlobalVar; } +/* string -> llvalue -> int -> llmodule -> llvalue */ +CAMLprim LLVMValueRef llvm_define_qualified_global(value Name, + LLVMValueRef Initializer, + value AddressSpace, + LLVMModuleRef M) { + LLVMValueRef GlobalVar = LLVMAddGlobalInAddressSpace(M, + LLVMTypeOf(Initializer), + String_val(Name), + Int_val(AddressSpace)); + LLVMSetInitializer(GlobalVar, Initializer); + return GlobalVar; +} + /* llvalue -> unit */ CAMLprim value llvm_delete_global(LLVMValueRef GlobalVar) { LLVMDeleteGlobal(GlobalVar); @@ -520,6 +1075,30 @@ CAMLprim value llvm_set_thread_local(value IsThreadLocal, return Val_unit; } +/* llvalue -> ThreadLocalMode.t */ +CAMLprim value llvm_thread_local_mode(LLVMValueRef GlobalVar) { + return Val_int(LLVMGetThreadLocalMode(GlobalVar)); +} + +/* ThreadLocalMode.t -> llvalue -> unit */ +CAMLprim value llvm_set_thread_local_mode(value ThreadLocalMode, + LLVMValueRef GlobalVar) { + LLVMSetThreadLocalMode(GlobalVar, Int_val(ThreadLocalMode)); + return Val_unit; +} + +/* llvalue -> bool */ +CAMLprim value llvm_is_externally_initialized(LLVMValueRef GlobalVar) { + return Val_bool(LLVMIsExternallyInitialized(GlobalVar)); +} + +/* bool -> llvalue -> unit */ +CAMLprim value llvm_set_externally_initialized(value IsExternallyInitialized, + LLVMValueRef GlobalVar) { + LLVMSetExternallyInitialized(GlobalVar, Bool_val(IsExternallyInitialized)); + return Val_unit; +} + /* llvalue -> bool */ CAMLprim value llvm_is_global_constant(LLVMValueRef GlobalVar) { return Val_bool(LLVMIsGlobalConstant(GlobalVar)); @@ -531,8 +1110,18 @@ CAMLprim value llvm_set_global_constant(value Flag, LLVMValueRef GlobalVar) { return Val_unit; } +/*--... Operations on aliases ..............................................--*/ + +CAMLprim LLVMValueRef llvm_add_alias(LLVMModuleRef M, LLVMTypeRef Ty, + LLVMValueRef Aliasee, value Name) { + return LLVMAddAlias(M, Ty, Aliasee, String_val(Name)); +} + /*--... Operations on functions ............................................--*/ +DEFINE_ITERATORS(function, Function, LLVMModuleRef, LLVMValueRef, + LLVMGetGlobalParent) + /* string -> lltype -> llmodule -> llvalue */ CAMLprim LLVMValueRef llvm_declare_function(value Name, LLVMTypeRef Ty, LLVMModuleRef M) { @@ -557,99 +1146,274 @@ CAMLprim value llvm_lookup_function(value Name, LLVMModuleRef M) { CAMLreturn(Val_int(0)); } -/* 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; +/* string -> lltype -> llmodule -> llvalue */ +CAMLprim LLVMValueRef llvm_define_function(value Name, LLVMTypeRef Ty, + LLVMModuleRef M) { + LLVMValueRef Fn = LLVMAddFunction(M, String_val(Name), Ty); + LLVMAppendBasicBlockInContext(LLVMGetTypeContext(Ty), Fn, "entry"); + return Fn; +} + +/* llvalue -> unit */ +CAMLprim value llvm_delete_function(LLVMValueRef Fn) { + LLVMDeleteFunction(Fn); + return Val_unit; +} + +/* 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; +} + +/* llvalue -> string option */ +CAMLprim value llvm_gc(LLVMValueRef Fn) { + const char *GC; + CAMLparam0(); + CAMLlocal2(Name, Option); + + if ((GC = LLVMGetGC(Fn))) { + Name = copy_string(GC); + + Option = alloc(1, 0); + Field(Option, 0) = Name; + CAMLreturn(Option); + } else { + CAMLreturn(Val_int(0)); + } +} + +/* string option -> llvalue -> unit */ +CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) { + LLVMSetGC(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0))); + return Val_unit; +} + +/* llvalue -> int32 -> unit */ +CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) { + LLVMAddFunctionAttr(Arg, Int32_val(PA)); + return Val_unit; +} + +/* llvalue -> string -> string -> unit */ +CAMLprim value llvm_add_target_dependent_function_attr( + LLVMValueRef Arg, value A, value V) { + LLVMAddTargetDependentFunctionAttr(Arg, String_val(A), String_val(V)); + return Val_unit; +} + +/* llvalue -> int32 */ +CAMLprim value llvm_function_attr(LLVMValueRef Fn) +{ + CAMLparam0(); + CAMLreturn(caml_copy_int32(LLVMGetFunctionAttr(Fn))); +} + +/* llvalue -> int32 -> unit */ +CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) { + LLVMRemoveFunctionAttr(Arg, Int32_val(PA)); + return Val_unit; +} +/*--... Operations on parameters ...........................................--*/ + +DEFINE_ITERATORS(param, Param, LLVMValueRef, LLVMValueRef, LLVMGetParamParent) + +/* llvalue -> int -> llvalue */ +CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) { + return LLVMGetParam(Fn, Int_val(Index)); +} + +/* llvalue -> int */ +CAMLprim value llvm_param_attr(LLVMValueRef Param) +{ + CAMLparam0(); + CAMLreturn(caml_copy_int32(LLVMGetAttribute(Param))); +} + +/* llvalue -> llvalue */ +CAMLprim value llvm_params(LLVMValueRef Fn) { + value Params = alloc(LLVMCountParams(Fn), 0); + LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params)); + return Params; +} + +/* llvalue -> int32 -> unit */ +CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) { + LLVMAddAttribute(Arg, Int32_val(PA)); + return Val_unit; +} + +/* llvalue -> int32 -> unit */ +CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) { + LLVMRemoveAttribute(Arg, Int32_val(PA)); + return Val_unit; +} + +/* llvalue -> int -> unit */ +CAMLprim value llvm_set_param_alignment(LLVMValueRef Arg, value align) { + LLVMSetParamAlignment(Arg, Int_val(align)); + return Val_unit; +} + +/*--... Operations on basic blocks .........................................--*/ + +DEFINE_ITERATORS( + block, BasicBlock, LLVMValueRef, LLVMBasicBlockRef, LLVMGetBasicBlockParent) + +/* llbasicblock -> llvalue option */ +CAMLprim value llvm_block_terminator(LLVMBasicBlockRef Block) +{ + CAMLparam0(); + LLVMValueRef Term = LLVMGetBasicBlockTerminator(Block); + if (Term) { + value Option = alloc(1, 0); + Field(Option, 0) = (value) Term; + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + +/* 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; +} + +/* llbasicblock -> unit */ +CAMLprim value llvm_remove_block(LLVMBasicBlockRef BB) { + LLVMRemoveBasicBlockFromParent(BB); + return Val_unit; +} + +/* llbasicblock -> llbasicblock -> unit */ +CAMLprim value llvm_move_block_before(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) { + LLVMMoveBasicBlockBefore(BB, Pos); + return Val_unit; } -/* llvalue -> unit */ -CAMLprim value llvm_delete_function(LLVMValueRef Fn) { - LLVMDeleteFunction(Fn); +/* llbasicblock -> llbasicblock -> unit */ +CAMLprim value llvm_move_block_after(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) { + LLVMMoveBasicBlockAfter(BB, Pos); return Val_unit; } -/* llvalue -> int -> llvalue */ -CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) { - return LLVMGetParam(Fn, Int_val(Index)); +/* string -> llvalue -> llbasicblock */ +CAMLprim LLVMBasicBlockRef llvm_append_block(LLVMContextRef Context, value Name, + LLVMValueRef Fn) { + return LLVMAppendBasicBlockInContext(Context, Fn, String_val(Name)); } -/* 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; +/* string -> llbasicblock -> llbasicblock */ +CAMLprim LLVMBasicBlockRef llvm_insert_block(LLVMContextRef Context, value Name, + LLVMBasicBlockRef BB) { + return LLVMInsertBasicBlockInContext(Context, BB, String_val(Name)); } /* llvalue -> bool */ -CAMLprim value llvm_is_intrinsic(LLVMValueRef Fn) { - return Val_bool(LLVMGetIntrinsicID(Fn)); +CAMLprim value llvm_value_is_block(LLVMValueRef Val) { + return Val_bool(LLVMValueIsBasicBlock(Val)); } -/* llvalue -> int */ -CAMLprim value llvm_function_call_conv(LLVMValueRef Fn) { - return Val_int(LLVMGetFunctionCallConv(Fn)); -} +/*--... Operations on instructions .........................................--*/ -/* int -> llvalue -> unit */ -CAMLprim value llvm_set_function_call_conv(value Id, LLVMValueRef Fn) { - LLVMSetFunctionCallConv(Fn, Int_val(Id)); - return Val_unit; +DEFINE_ITERATORS(instr, Instruction, LLVMBasicBlockRef, LLVMValueRef, + LLVMGetInstructionParent) + +/* llvalue -> Opcode.t */ +CAMLprim value llvm_instr_get_opcode(LLVMValueRef Inst) { + LLVMOpcode o; + if (!LLVMIsAInstruction(Inst)) + failwith("Not an instruction"); + o = LLVMGetInstructionOpcode(Inst); + assert (o <= LLVMLandingPad); + return Val_int(o); } -/* llvalue -> string option */ -CAMLprim value llvm_collector(LLVMValueRef Fn) { - const char *Collector; +/* llvalue -> ICmp.t option */ +CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) { CAMLparam0(); - CAMLlocal2(Name, Option); - - if ((Collector = LLVMGetCollector(Fn))) { - Name = copy_string(Collector); - - Option = alloc(1, 0); - Field(Option, 0) = Name; + int x = LLVMGetICmpPredicate(Val); + if (x) { + value Option = alloc(1, 0); + Field(Option, 0) = Val_int(x - LLVMIntEQ); CAMLreturn(Option); - } else { - CAMLreturn(Val_int(0)); } + CAMLreturn(Val_int(0)); } -/* string option -> llvalue -> unit */ -CAMLprim value llvm_set_collector(value GC, LLVMValueRef Fn) { - LLVMSetCollector(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0))); - return Val_unit; + +/*--... Operations on call sites ...........................................--*/ + +/* llvalue -> int */ +CAMLprim value llvm_instruction_call_conv(LLVMValueRef Inst) { + return Val_int(LLVMGetInstructionCallConv(Inst)); } -/*--... Operations on basic blocks .........................................--*/ +/* int -> llvalue -> unit */ +CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) { + LLVMSetInstructionCallConv(Inst, Int_val(CC)); + return Val_unit; +} -/* llvalue -> llbasicblock array */ -CAMLprim value llvm_basic_blocks(LLVMValueRef Fn) { - value MLArray = alloc(LLVMCountBasicBlocks(Fn), 0); - LLVMGetBasicBlocks(Fn, (LLVMBasicBlockRef *) Op_val(MLArray)); - return MLArray; +/* llvalue -> int -> int32 -> unit */ +CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr, + value index, + value PA) { + LLVMAddInstrAttribute(Instr, Int_val(index), Int32_val(PA)); + return Val_unit; } -/* llbasicblock -> unit */ -CAMLprim value llvm_delete_block(LLVMBasicBlockRef BB) { - LLVMDeleteBasicBlock(BB); +/* llvalue -> int -> int32 -> unit */ +CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr, + value index, + value PA) { + LLVMRemoveInstrAttribute(Instr, Int_val(index), Int32_val(PA)); return Val_unit; } -/* string -> llvalue -> llbasicblock */ -CAMLprim LLVMBasicBlockRef llvm_append_block(value Name, LLVMValueRef Fn) { - return LLVMAppendBasicBlock(Fn, String_val(Name)); +/*--... Operations on call instructions (only) .............................--*/ + +/* llvalue -> bool */ +CAMLprim value llvm_is_tail_call(LLVMValueRef CallInst) { + return Val_bool(LLVMIsTailCall(CallInst)); } -/* string -> llbasicblock -> llbasicblock */ -CAMLprim LLVMBasicBlockRef llvm_insert_block(value Name, LLVMBasicBlockRef BB) { - return LLVMInsertBasicBlock(BB, String_val(Name)); +/* bool -> llvalue -> unit */ +CAMLprim value llvm_set_tail_call(value IsTailCall, + LLVMValueRef CallInst) { + LLVMSetTailCall(CallInst, Bool_val(IsTailCall)); + return Val_unit; } +/*--... Operations on load/store instructions (only)........................--*/ + /* llvalue -> bool */ -CAMLprim value llvm_value_is_block(LLVMValueRef Val) { - return Val_bool(LLVMValueIsBasicBlock(Val)); +CAMLprim value llvm_is_volatile(LLVMValueRef MemoryInst) { + return Val_bool(LLVMGetVolatile(MemoryInst)); +} + +/* bool -> llvalue -> unit */ +CAMLprim value llvm_set_volatile(value IsVolatile, + LLVMValueRef MemoryInst) { + LLVMSetVolatile(MemoryInst, Bool_val(IsVolatile)); + return Val_unit; } /*--... Operations on phi nodes ............................................--*/ @@ -685,6 +1449,11 @@ CAMLprim value llvm_incoming(LLVMValueRef PhiNode) { CAMLreturn(Tl); } +/* llvalue -> unit */ +CAMLprim value llvm_delete_instruction(LLVMValueRef Instruction) { + LLVMInstructionEraseFromParent(Instruction); + return Val_unit; +} /*===-- Instruction builders ----------------------------------------------===*/ @@ -695,12 +1464,15 @@ static void llvm_finalize_builder(value B) { } static struct custom_operations builder_ops = { - (char *) "LLVMBuilder", + (char *) "LLVMIRBuilder", llvm_finalize_builder, custom_compare_default, custom_hash_default, custom_serialize_default, custom_deserialize_default +#ifdef custom_compare_ext_default + , custom_compare_ext_default +#endif }; static value alloc_builder(LLVMBuilderRef B) { @@ -709,37 +1481,70 @@ static value alloc_builder(LLVMBuilderRef B) { return V; } -/* unit-> llbuilder */ -CAMLprim value llvm_builder(value Unit) { - return alloc_builder(LLVMCreateBuilder()); +/* llcontext -> llbuilder */ +CAMLprim value llvm_builder(LLVMContextRef C) { + return alloc_builder(LLVMCreateBuilderInContext(C)); +} + +/* (llbasicblock, llvalue) llpos -> llbuilder -> unit */ +CAMLprim value llvm_position_builder(value Pos, value B) { + if (Tag_val(Pos) == 0) { + LLVMBasicBlockRef BB = (LLVMBasicBlockRef) Op_val(Field(Pos, 0)); + LLVMPositionBuilderAtEnd(Builder_val(B), BB); + } else { + LLVMValueRef I = (LLVMValueRef) Op_val(Field(Pos, 0)); + LLVMPositionBuilderBefore(Builder_val(B), I); + } + return Val_unit; +} + +/* llbuilder -> llbasicblock */ +CAMLprim LLVMBasicBlockRef llvm_insertion_block(value B) { + LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B)); + if (!InsertBlock) + raise_not_found(); + return InsertBlock; } -/* llvalue -> llbuilder */ -CAMLprim value llvm_builder_before(LLVMValueRef Inst) { - LLVMBuilderRef B = LLVMCreateBuilder(); - LLVMPositionBuilderBefore(B, Inst); - return alloc_builder(B); +/* llvalue -> string -> llbuilder -> unit */ +CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name, value B) { + LLVMInsertIntoBuilderWithName(Builder_val(B), I, String_val(Name)); + return Val_unit; } -/* llbasicblock -> llbuilder */ -CAMLprim value llvm_builder_at_end(LLVMBasicBlockRef BB) { - LLVMBuilderRef B = LLVMCreateBuilder(); - LLVMPositionBuilderAtEnd(B, BB); - return alloc_builder(B); +/*--... Metadata ...........................................................--*/ + +/* llbuilder -> llvalue -> unit */ +CAMLprim value llvm_set_current_debug_location(value B, LLVMValueRef V) { + LLVMSetCurrentDebugLocation(Builder_val(B), V); + return Val_unit; } -/* llvalue -> llbuilder -> unit */ -CAMLprim value llvm_position_before(LLVMValueRef Inst, value B) { - LLVMPositionBuilderBefore(Builder_val(B), Inst); +/* llbuilder -> unit */ +CAMLprim value llvm_clear_current_debug_location(value B) { + LLVMSetCurrentDebugLocation(Builder_val(B), NULL); return Val_unit; } -/* llbasicblock -> llbuilder -> unit */ -CAMLprim value llvm_position_at_end(LLVMBasicBlockRef BB, value B) { - LLVMPositionBuilderAtEnd(Builder_val(B), BB); +/* llbuilder -> llvalue option */ +CAMLprim value llvm_current_debug_location(value B) { + CAMLparam0(); + LLVMValueRef L; + if ((L = LLVMGetCurrentDebugLocation(Builder_val(B)))) { + value Option = alloc(1, 0); + Field(Option, 0) = (value) L; + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + +/* llbuilder -> llvalue -> unit */ +CAMLprim value llvm_set_inst_debug_location(value B, LLVMValueRef V) { + LLVMSetInstDebugLocation(Builder_val(B), V); return Val_unit; } + /*--... Terminators ........................................................--*/ /* llbuilder -> llvalue */ @@ -752,6 +1557,12 @@ CAMLprim LLVMValueRef llvm_build_ret(LLVMValueRef Val, value B) { return LLVMBuildRet(Builder_val(B), Val); } +/* llvalue array -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_aggregate_ret(value RetVals, value B) { + return LLVMBuildAggregateRet(Builder_val(B), (LLVMValueRef *) Op_val(RetVals), + Wosize_val(RetVals)); +} + /* llbasicblock -> llbuilder -> llvalue */ CAMLprim LLVMValueRef llvm_build_br(LLVMBasicBlockRef BB, value B) { return LLVMBuildBr(Builder_val(B), BB); @@ -773,6 +1584,48 @@ CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of, return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount)); } +/* 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 Val, + value Name, value B) +{ + return LLVMBuildArrayMalloc(Builder_val(B), Ty, Val, String_val(Name)); +} + +/* llvalue -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef P, value B) +{ + return LLVMBuildFree(Builder_val(B), P); +} + +/* llvalue -> llvalue -> llbasicblock -> unit */ +CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal, + LLVMBasicBlockRef Dest) { + LLVMAddCase(Switch, OnVal, Dest); + return Val_unit; +} + +/* llvalue -> llbasicblock -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_indirect_br(LLVMValueRef Addr, + value EstimatedDests, + value B) { + return LLVMBuildIndirectBr(Builder_val(B), Addr, EstimatedDests); +} + +/* llvalue -> llvalue -> llbasicblock -> unit */ +CAMLprim value llvm_add_destination(LLVMValueRef IndirectBr, + LLVMBasicBlockRef Dest) { + LLVMAddDestination(IndirectBr, Dest); + return Val_unit; +} + /* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string -> llbuilder -> llvalue */ CAMLprim LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args, @@ -792,9 +1645,33 @@ CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) { Args[4], Args[5]); } -/* llbuilder -> llvalue */ -CAMLprim LLVMValueRef llvm_build_unwind(value B) { - return LLVMBuildUnwind(Builder_val(B)); +/* lltype -> llvalue -> int -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn, + value NumClauses, value Name, + value B) { + return LLVMBuildLandingPad(Builder_val(B), Ty, PersFn, Int_val(NumClauses), + String_val(Name)); +} + +/* llvalue -> llvalue -> unit */ +CAMLprim value llvm_add_clause(LLVMValueRef LandingPadInst, LLVMValueRef ClauseVal) +{ + LLVMAddClause(LandingPadInst, ClauseVal); + return Val_unit; +} + + +/* llvalue -> bool -> unit */ +CAMLprim value llvm_set_cleanup(LLVMValueRef LandingPadInst, value flag) +{ + LLVMSetCleanup(LandingPadInst, Bool_val(flag)); + return Val_unit; +} + +/* llvalue -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_resume(LLVMValueRef Exn, value B) +{ + return LLVMBuildResume(Builder_val(B), Exn); } /* llbuilder -> llvalue */ @@ -810,18 +1687,72 @@ CAMLprim LLVMValueRef llvm_build_add(LLVMValueRef LHS, LLVMValueRef RHS, return LLVMBuildAdd(Builder_val(B), LHS, RHS, String_val(Name)); } +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildNSWAdd(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_nuw_add(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildNUWAdd(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fadd(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildFAdd(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_nsw_sub(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildNSWSub(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_nuw_sub(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildNUWSub(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fsub(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildFSub(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_nsw_mul(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildNSWMul(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_nuw_mul(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildNUWMul(Builder_val(B), LHS, RHS, String_val(Name)); +} + +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fmul(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildFMul(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) { @@ -834,6 +1765,12 @@ CAMLprim LLVMValueRef llvm_build_sdiv(LLVMValueRef LHS, LLVMValueRef RHS, return LLVMBuildSDiv(Builder_val(B), LHS, RHS, String_val(Name)); } +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_exact_sdiv(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildExactSDiv(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) { @@ -901,25 +1838,31 @@ CAMLprim LLVMValueRef llvm_build_neg(LLVMValueRef X, } /* llvalue -> string -> llbuilder -> llvalue */ -CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X, - value Name, value B) { - return LLVMBuildNot(Builder_val(B), X, String_val(Name)); +CAMLprim LLVMValueRef llvm_build_nsw_neg(LLVMValueRef X, + value Name, value B) { + return LLVMBuildNSWNeg(Builder_val(B), X, String_val(Name)); } -/*--... Memory .............................................................--*/ +/* llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_nuw_neg(LLVMValueRef X, + value Name, value B) { + return LLVMBuildNUWNeg(Builder_val(B), X, String_val(Name)); +} -/* lltype -> string -> llbuilder -> llvalue */ -CAMLprim LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty, - value Name, value B) { - return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name)); +/* llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fneg(LLVMValueRef X, + value Name, value B) { + return LLVMBuildFNeg(Builder_val(B), X, 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)); +/* 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_alloca(LLVMTypeRef Ty, value Name, value B) { @@ -932,11 +1875,6 @@ CAMLprim LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size, 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) { @@ -949,6 +1887,24 @@ CAMLprim LLVMValueRef llvm_build_store(LLVMValueRef Value, LLVMValueRef Pointer, return LLVMBuildStore(Builder_val(B), Value, Pointer); } +/* AtomicRMWBinOp.t -> llvalue -> llvalue -> AtomicOrdering.t -> + bool -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_atomicrmw_native(value BinOp, LLVMValueRef Ptr, + LLVMValueRef Val, value Ord, + value ST, value Name, value B) { + LLVMValueRef Instr; + Instr = LLVMBuildAtomicRMW(Builder_val(B), Int_val(BinOp), + Ptr, Val, Int_val(Ord), Bool_val(ST)); + LLVMSetValueName(Instr, String_val(Name)); + return Instr; +} + +CAMLprim LLVMValueRef llvm_build_atomicrmw_bytecode(value *argv, int argn) { + return llvm_build_atomicrmw_native(argv[0], (LLVMValueRef) argv[1], + (LLVMValueRef) argv[2], argv[3], + argv[4], argv[5], argv[6]); +} + /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */ CAMLprim LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices, value Name, value B) { @@ -957,6 +1913,36 @@ CAMLprim LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices, String_val(Name)); } +/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer, + value Indices, value Name, + value B) { + return LLVMBuildInBoundsGEP(Builder_val(B), Pointer, + (LLVMValueRef *) Op_val(Indices), + Wosize_val(Indices), String_val(Name)); +} + +/* llvalue -> int -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer, + value Index, value Name, + value B) { + return LLVMBuildStructGEP(Builder_val(B), Pointer, + Int_val(Index), String_val(Name)); +} + +/* string -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_global_string(value Str, value Name, value B) { + return LLVMBuildGlobalString(Builder_val(B), String_val(Str), + String_val(Name)); +} + +/* string -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_global_stringptr(value Str, value Name, + value B) { + return LLVMBuildGlobalStringPtr(Builder_val(B), String_val(Str), + String_val(Name)); +} + /*--... Casts ..............................................................--*/ /* llvalue -> lltype -> string -> llbuilder -> llvalue */ @@ -1031,6 +2017,43 @@ CAMLprim LLVMValueRef llvm_build_bitcast(LLVMValueRef X, LLVMTypeRef Ty, return LLVMBuildBitCast(Builder_val(B), X, Ty, String_val(Name)); } +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_zext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildZExtOrBitCast(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_sext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildSExtOrBitCast(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_trunc_or_bitcast(LLVMValueRef X, + LLVMTypeRef Ty, value Name, + value B) { + return LLVMBuildTruncOrBitCast(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_pointercast(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildPointerCast(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_intcast(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildIntCast(Builder_val(B), X, Ty, String_val(Name)); +} + +/* llvalue -> lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_fpcast(LLVMValueRef X, LLVMTypeRef Ty, + value Name, value B) { + return LLVMBuildFPCast(Builder_val(B), X, Ty, String_val(Name)); +} + /*--... Comparisons ........................................................--*/ /* Icmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */ @@ -1115,15 +2138,38 @@ CAMLprim LLVMValueRef llvm_build_shufflevector(LLVMValueRef V1, LLVMValueRef V2, return LLVMBuildShuffleVector(Builder_val(B), V1, V2, Mask, String_val(Name)); } +/* llvalue -> int -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_extractvalue(LLVMValueRef Aggregate, + value Idx, value Name, value B) { + return LLVMBuildExtractValue(Builder_val(B), Aggregate, Int_val(Idx), + String_val(Name)); +} + +/* llvalue -> llvalue -> int -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_insertvalue(LLVMValueRef Aggregate, + LLVMValueRef Val, value Idx, + value Name, value B) { + return LLVMBuildInsertValue(Builder_val(B), Aggregate, Val, Int_val(Idx), + String_val(Name)); +} -/*===-- Module Providers --------------------------------------------------===*/ +/* llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_is_null(LLVMValueRef Val, value Name, + value B) { + return LLVMBuildIsNull(Builder_val(B), Val, String_val(Name)); +} -/* llmoduleprovider -> unit */ -CAMLprim value llvm_dispose_module_provider(LLVMModuleProviderRef MP) { - LLVMDisposeModuleProvider(MP); - return Val_unit; +/* llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_is_not_null(LLVMValueRef Val, value Name, + value B) { + return LLVMBuildIsNotNull(Builder_val(B), Val, String_val(Name)); } +/* llvalue -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS, + value Name, value B) { + return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name)); +} /*===-- Memory buffers ----------------------------------------------------===*/ @@ -1153,9 +2199,67 @@ CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) { return MemBuf; } +/* ?name:string -> string -> llmemorybuffer */ +CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_string(value Name, value String) { + const char *NameCStr; + if(Name == Val_int(0)) + NameCStr = ""; + else + NameCStr = String_val(Field(Name, 0)); + + LLVMMemoryBufferRef MemBuf; + MemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy( + String_val(String), caml_string_length(String), NameCStr); + + return MemBuf; +} + +/* llmemorybuffer -> string */ +CAMLprim value llvm_memorybuffer_as_string(LLVMMemoryBufferRef MemBuf) { + value String = caml_alloc_string(LLVMGetBufferSize(MemBuf)); + memcpy(String_val(String), LLVMGetBufferStart(MemBuf), + LLVMGetBufferSize(MemBuf)); + + return String; +} + /* llmemorybuffer -> unit */ CAMLprim value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) { LLVMDisposeMemoryBuffer(MemBuf); return Val_unit; } +/*===-- Pass Managers -----------------------------------------------------===*/ + +/* unit -> [ `Module ] PassManager.t */ +CAMLprim LLVMPassManagerRef llvm_passmanager_create(value Unit) { + return LLVMCreatePassManager(); +} + +/* llmodule -> [ `Function ] PassManager.t -> bool */ +CAMLprim value llvm_passmanager_run_module(LLVMModuleRef M, + LLVMPassManagerRef PM) { + return Val_bool(LLVMRunPassManager(PM, M)); +} + +/* [ `Function ] PassManager.t -> bool */ +CAMLprim value llvm_passmanager_initialize(LLVMPassManagerRef FPM) { + return Val_bool(LLVMInitializeFunctionPassManager(FPM)); +} + +/* llvalue -> [ `Function ] PassManager.t -> bool */ +CAMLprim value llvm_passmanager_run_function(LLVMValueRef F, + LLVMPassManagerRef FPM) { + return Val_bool(LLVMRunFunctionPassManager(FPM, F)); +} + +/* [ `Function ] PassManager.t -> bool */ +CAMLprim value llvm_passmanager_finalize(LLVMPassManagerRef FPM) { + return Val_bool(LLVMFinalizeFunctionPassManager(FPM)); +} + +/* PassManager.any PassManager.t -> unit */ +CAMLprim value llvm_passmanager_dispose(LLVMPassManagerRef PM) { + LLVMDisposePassManager(PM); + return Val_unit; +}