X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=bindings%2Focaml%2Fllvm%2Fllvm_ocaml.c;h=be6e808d73318d23374fdae623091caff017a75c;hp=69bd0a2fbc111bb92020a210d9f4874331d9eb51;hb=6b228e506f42972c003599f4873a24910f8a530a;hpb=45d6ac2cc13f7881687c2d7f03f9b9892fd85e6e diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c index 69bd0a2fbc1..be6e808d733 100644 --- a/bindings/ocaml/llvm/llvm_ocaml.c +++ b/bindings/ocaml/llvm/llvm_ocaml.c @@ -24,6 +24,7 @@ #include "llvm/Config/config.h" #include #include +#include /* Can't use the recommended caml_named_value mechanism for backwards @@ -92,11 +93,36 @@ static value alloc_variant(int tag, void *Value) { } +/*===-- 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 */ @@ -127,24 +153,17 @@ 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); -} - -/* string -> llmodule -> unit */ -CAMLprim value llvm_delete_type_name(value Name, LLVMModuleRef M) { - LLVMDeleteTypeName(M, String_val(Name)); - return Val_unit; -} - /* llmodule -> unit */ CAMLprim value llvm_dump_module(LLVMModuleRef M) { LLVMDumpModule(M); return Val_unit; } +/* llmodule -> string -> unit */ +CAMLprim value llvm_set_module_inline_asm(LLVMModuleRef M, value Asm) { + LLVMSetModuleInlineAsm(M, String_val(Asm)); + return Val_unit; +} /*===-- Types -------------------------------------------------------------===*/ @@ -153,18 +172,45 @@ 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); +} + /*--... 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 */ @@ -174,29 +220,34 @@ 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); +} + +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_double_type(LLVMContextRef Context) { + return LLVMDoubleTypeInContext(Context); } -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_double_type(value Unit) { - return LLVMDoubleType(); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_x86fp80_type(LLVMContextRef Context) { + return LLVMX86FP80TypeInContext(Context); } -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_x86fp80_type(value Unit) { - return LLVMX86FP80Type(); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_fp128_type(LLVMContextRef Context) { + return LLVMFP128TypeInContext(Context); } -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_fp128_type(value Unit) { - return LLVMFP128Type(); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_ppc_fp128_type(LLVMContextRef Context) { + return LLVMPPCFP128TypeInContext(Context); } -/* unit -> lltype */ -CAMLprim LLVMTypeRef llvm_ppc_fp128_type(value Unit) { - return LLVMPPCFP128Type(); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_x86mmx_type(LLVMContextRef Context) { + return LLVMX86MMXTypeInContext(Context); } /*--... Operations on function types .......................................--*/ @@ -228,20 +279,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); } -/* lltype array -> lltype */ -CAMLprim LLVMTypeRef llvm_packed_struct_type(value ElementTypes) { - return LLVMStructType((LLVMTypeRef *) ElementTypes, - Wosize_val(ElementTypes), 1); +/* llcontext -> lltype array -> lltype */ +CAMLprim LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C, + value ElementTypes) { + return LLVMStructTypeInContext(C, (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; @@ -252,6 +332,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 */ @@ -292,48 +377,16 @@ 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(); -} - -/*--... 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; -} - -CAMLprim LLVMTypeRef llvm_type_of_handle(value TH) { - return LLVMResolveTypeHandle(Typehandle_val(TH)); +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_void_type (LLVMContextRef Context) { + return LLVMVoidTypeInContext(Context); } -CAMLprim value llvm_refine_type(LLVMTypeRef AbstractTy, LLVMTypeRef ConcreteTy){ - LLVMRefineType(AbstractTy, ConcreteTy); - return Val_unit; +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_label_type(LLVMContextRef Context) { + return LLVMLabelTypeInContext(Context); } - /*===-- VALUES ------------------------------------------------------------===*/ /* llvalue -> lltype */ @@ -341,6 +394,69 @@ 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, + 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, 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)); @@ -358,6 +474,24 @@ CAMLprim value llvm_dump_value(LLVMValueRef Val) { 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 -> 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 */ @@ -375,6 +509,84 @@ 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)); +} + +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); +} /*--... Operations on scalar constants .....................................--*/ /* lltype -> int -> llvalue */ @@ -388,6 +600,19 @@ 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) { @@ -408,14 +633,18 @@ CAMLprim LLVMValueRef llvm_const_float_of_string(LLVMTypeRef RealTy, value 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 */ @@ -425,16 +654,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 */ @@ -508,6 +743,14 @@ CAMLprim LLVMValueRef llvm_const_insertvalue(LLVMValueRef Aggregate, 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 */ @@ -559,6 +802,42 @@ 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, @@ -576,6 +855,20 @@ 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 LLVMAddGlobal(M, Ty, String_val(Name)); +} + /* string -> llmodule -> llvalue option */ CAMLprim value llvm_lookup_global(value Name, LLVMModuleRef M) { CAMLparam1(Name); @@ -597,6 +890,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); @@ -639,6 +945,13 @@ 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, @@ -672,7 +985,7 @@ CAMLprim value llvm_lookup_function(value Name, LLVMModuleRef M) { CAMLprim LLVMValueRef llvm_define_function(value Name, LLVMTypeRef Ty, LLVMModuleRef M) { LLVMValueRef Fn = LLVMAddFunction(M, String_val(Name), Ty); - LLVMAppendBasicBlock(Fn, "entry"); + LLVMAppendBasicBlockInContext(LLVMGetTypeContext(Ty), Fn, "entry"); return Fn; } @@ -723,13 +1036,13 @@ CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) { /* llvalue -> Attribute.t -> unit */ CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) { - LLVMAddFunctionAttr(Arg, 1< Attribute.t -> unit */ CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) { - LLVMRemoveFunctionAttr(Arg, 1< int -> llvalue */ -CAMLprim value llvm_params(LLVMValueRef Fn, value Index) { +/* llvalue -> llvalue */ +CAMLprim value llvm_params(LLVMValueRef Fn) { value Params = alloc(LLVMCountParams(Fn), 0); LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params)); return Params; @@ -750,13 +1063,13 @@ CAMLprim value llvm_params(LLVMValueRef Fn, value Index) { /* llvalue -> Attribute.t -> unit */ CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) { - LLVMAddAttribute(Arg, 1< Attribute.t -> unit */ CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) { - LLVMRemoveAttribute(Arg, 1< llvalue -> llbasicblock */ -CAMLprim LLVMBasicBlockRef llvm_append_block(value Name, LLVMValueRef Fn) { - return LLVMAppendBasicBlock(Fn, String_val(Name)); +CAMLprim LLVMBasicBlockRef llvm_append_block(LLVMContextRef Context, value Name, + LLVMValueRef Fn) { + return LLVMAppendBasicBlockInContext(Context, Fn, String_val(Name)); } /* string -> llbasicblock -> llbasicblock */ -CAMLprim LLVMBasicBlockRef llvm_insert_block(value Name, LLVMBasicBlockRef BB) { - return LLVMInsertBasicBlock(BB, String_val(Name)); +CAMLprim LLVMBasicBlockRef llvm_insert_block(LLVMContextRef Context, value Name, + LLVMBasicBlockRef BB) { + return LLVMInsertBasicBlockInContext(Context, BB, String_val(Name)); } /* llvalue -> bool */ @@ -804,6 +1119,28 @@ CAMLprim value llvm_value_is_block(LLVMValueRef Val) { 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 <= LLVMUnwind ); + return Val_int(o); +} + +/* llvalue -> ICmp.t */ +CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) { + CAMLparam0(); + int x = LLVMGetICmpPredicate(Val); + if (x) { + value Option = alloc(1, 0); + Field(Option, 0) = Val_int(x - LLVMIntEQ); + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + /*--... Operations on call sites ...........................................--*/ @@ -822,7 +1159,7 @@ CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) { CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr, value index, value PA) { - LLVMAddInstrAttribute(Instr, Int_val(index), 1< 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 */ @@ -923,7 +1260,7 @@ CAMLprim value llvm_position_builder(value Pos, value B) { } /* llbuilder -> llbasicblock */ -CAMLprim LLVMBasicBlockRef llvm_insertion_block(LLVMBuilderRef B) { +CAMLprim LLVMBasicBlockRef llvm_insertion_block(value B) { LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B)); if (!InsertBlock) raise_not_found(); @@ -931,12 +1268,44 @@ CAMLprim LLVMBasicBlockRef llvm_insertion_block(LLVMBuilderRef B) { } /* llvalue -> string -> llbuilder -> unit */ -CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name, - LLVMBuilderRef B) { - LLVMInsertIntoBuilderWithName(B, I, String_val(Name)); +CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name, value B) { + LLVMInsertIntoBuilderWithName(Builder_val(B), I, String_val(Name)); + return Val_unit; +} + +/*--... Metadata ...........................................................--*/ + +/* llbuilder -> llvalue -> unit */ +CAMLprim value llvm_set_current_debug_location(value B, LLVMValueRef V) { + LLVMSetCurrentDebugLocation(Builder_val(B), V); + return Val_unit; +} + +/* llbuilder -> unit */ +CAMLprim value llvm_clear_current_debug_location(value B) { + LLVMSetCurrentDebugLocation(Builder_val(B), NULL); + return Val_unit; +} + +/* 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 */ @@ -949,6 +1318,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); @@ -970,13 +1345,27 @@ CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of, return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount)); } -CAMLprim value llvm_add_case(LLVMValueRef Switch, - LLVMValueRef OnVal, +/* 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, @@ -996,9 +1385,17 @@ 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)); +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)); +} + +CAMLprim value llvm_set_cleanup(LLVMValueRef LandingPadInst, value flag) +{ + LLVMSetCleanup(LandingPadInst, Bool_val(flag)); + return Val_unit; } /* llbuilder -> llvalue */ @@ -1020,6 +1417,12 @@ CAMLprim LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS, 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) { @@ -1032,6 +1435,18 @@ CAMLprim LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS, 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) { @@ -1044,6 +1459,18 @@ CAMLprim LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS, 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) { @@ -1135,25 +1562,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) { @@ -1166,11 +1599,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) { @@ -1202,11 +1630,10 @@ CAMLprim LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer, /* llvalue -> int -> string -> llbuilder -> llvalue */ CAMLprim LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer, - value Indices, value Name, + value Index, value Name, value B) { - return LLVMBuildInBoundsGEP(Builder_val(B), Pointer, - (LLVMValueRef *) Op_val(Indices), - Wosize_val(Indices), String_val(Name)); + return LLVMBuildStructGEP(Builder_val(B), Pointer, + Int_val(Index), String_val(Name)); } /* string -> string -> llbuilder -> llvalue */ @@ -1450,14 +1877,6 @@ CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS, return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name)); } -/*===-- Module Providers --------------------------------------------------===*/ - -/* llmoduleprovider -> unit */ -CAMLprim value llvm_dispose_module_provider(LLVMModuleProviderRef MP) { - LLVMDisposeModuleProvider(MP); - return Val_unit; -} - /*===-- Memory buffers ----------------------------------------------------===*/