X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=bindings%2Focaml%2Fllvm%2Fllvm_ocaml.c;h=02107223eb65aaa845ba49168ce1bac7990b0348;hp=21519d474dfccfd682311b25fca01701e34efaa7;hb=0947d0e38ba18b32e8eb2b76009d558bc4b2346e;hpb=31116410de16f435d8c76c53e3d6b95fa812cd2c diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c index 21519d474df..02107223eb6 100644 --- a/bindings/ocaml/llvm/llvm_ocaml.c +++ b/bindings/ocaml/llvm/llvm_ocaml.c @@ -1,4 +1,4 @@ -/*===-- llvm_ocaml.c - LLVM Ocaml Glue --------------------------*- C++ -*-===*\ +/*===-- llvm_ocaml.c - LLVM OCaml Glue --------------------------*- C++ -*-===*\ |* *| |* The LLVM Compiler Infrastructure *| |* *| @@ -7,7 +7,7 @@ |* *| |*===----------------------------------------------------------------------===*| |* *| -|* 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,7 +21,6 @@ #include "caml/memory.h" #include "caml/fail.h" #include "caml/callback.h" -#include "llvm/Config/config.h" #include #include #include @@ -34,16 +33,17 @@ 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; } static void llvm_raise(value Prototype, char *Message) { CAMLparam1(Prototype); CAMLlocal1(CamlMessage); - + CamlMessage = copy_string(Message); LLVMDisposeMessage(Message); - + raise_with_arg(Prototype, CamlMessage); abort(); /* NOTREACHED */ #ifdef CAMLnoreturn @@ -51,6 +51,30 @@ static void llvm_raise(value Prototype, char *Message) { #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); @@ -159,6 +183,27 @@ CAMLprim value llvm_dump_module(LLVMModuleRef M) { return Val_unit; } +/* string -> llmodule -> unit */ +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)); @@ -181,6 +226,23 @@ 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 ........................................--*/ /* llcontext -> lltype */ @@ -245,11 +307,6 @@ CAMLprim LLVMTypeRef llvm_ppc_fp128_type(LLVMContextRef Context) { return LLVMPPCFP128TypeInContext(Context); } -/* llcontext -> lltype */ -CAMLprim LLVMTypeRef llvm_x86mmx_type(LLVMContextRef Context) { - return LLVMX86MMXTypeInContext(Context); -} - /*--... Operations on function types .......................................--*/ /* lltype -> lltype array -> lltype */ @@ -292,6 +349,20 @@ CAMLprim LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C, 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) { @@ -318,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 */ @@ -368,6 +444,23 @@ CAMLprim LLVMTypeRef llvm_label_type(LLVMContextRef Context) { return LLVMLabelTypeInContext(Context); } +/* llcontext -> lltype */ +CAMLprim LLVMTypeRef llvm_x86_mmx_type(LLVMContextRef Context) { + return LLVMX86MMXTypeInContext(Context); +} + +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 */ @@ -375,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)); @@ -392,6 +552,24 @@ 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 */ @@ -399,6 +577,11 @@ 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); @@ -427,6 +610,12 @@ 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 */ @@ -491,19 +680,27 @@ CAMLprim value llvm_get_mdstring(LLVMValueRef V) { CAMLreturn(Val_int(0)); } -CAMLprim value llvm_get_namedmd(LLVMModuleRef M, value name) +/* llmodule -> string -> llvalue array */ +CAMLprim value llvm_get_namedmd(LLVMModuleRef M, value Name) { - CAMLparam1(name); + CAMLparam1(Name); CAMLlocal1(Nodes); - Nodes = alloc(LLVMGetNamedMetadataNumOperands(M, String_val(name)), 0); - LLVMGetNamedMetadataOperands(M, String_val(name), (LLVMValueRef *) 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 */ @@ -512,6 +709,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) { @@ -524,6 +734,22 @@ CAMLprim LLVMValueRef llvm_const_float(LLVMTypeRef RealTy, value N) { return LLVMConstReal(RealTy, Double_val(N)); } + +/* llvalue -> float */ +CAMLprim value llvm_float_of_const(LLVMValueRef Const) +{ + if (LLVMIsAConstantFP(Const)) { + LLVMBool LosesInfo; + double res = LLVMConstRealGetDouble(Const, &LosesInfo); + if (LosesInfo) + return Val_int(0); + value Option = alloc(1, 0); + Field(Option, 0) = caml_copy_double(res); + return Option; + } + return Val_int(0); +} + /* lltype -> string -> llvalue */ CAMLprim LLVMValueRef llvm_const_float_of_string(LLVMTypeRef RealTy, value S) { return LLVMConstRealOfStringAndSize(RealTy, String_val(S), @@ -559,6 +785,11 @@ CAMLprim LLVMValueRef llvm_const_struct(LLVMContextRef C, value ElementVals) { Wosize_val(ElementVals), 0); } +/* 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) { @@ -572,6 +803,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 */ @@ -601,6 +857,12 @@ CAMLprim LLVMValueRef llvm_const_in_bounds_gep(LLVMValueRef ConstantVal, 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) { @@ -760,7 +1022,8 @@ CAMLprim LLVMValueRef llvm_declare_qualified_global(LLVMTypeRef Ty, value Name, LLVMPointerType(Ty, Int_val(AddressSpace))); return GlobalVar; } - return LLVMAddGlobal(M, Ty, String_val(Name)); + return LLVMAddGlobalInAddressSpace(M, Ty, String_val(Name), + Int_val(AddressSpace)); } /* string -> llmodule -> llvalue option */ @@ -828,6 +1091,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)); @@ -910,10 +1197,10 @@ 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); @@ -928,15 +1215,29 @@ CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) { return Val_unit; } -/* llvalue -> Attribute.t -> unit */ +/* llvalue -> int32 -> unit */ CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) { - LLVMAddFunctionAttr(Arg, Int_val(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 -> Attribute.t -> 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, Int_val(PA)); + LLVMRemoveFunctionAttr(Arg, Int32_val(PA)); return Val_unit; } /*--... Operations on parameters ...........................................--*/ @@ -948,6 +1249,13 @@ 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); @@ -955,15 +1263,15 @@ CAMLprim value llvm_params(LLVMValueRef Fn) { return Params; } -/* llvalue -> Attribute.t -> unit */ +/* llvalue -> int32 -> unit */ CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) { - LLVMAddAttribute(Arg, Int_val(PA)); + LLVMAddAttribute(Arg, Int32_val(PA)); return Val_unit; } -/* llvalue -> Attribute.t -> unit */ +/* llvalue -> int32 -> unit */ CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) { - LLVMRemoveAttribute(Arg, Int_val(PA)); + LLVMRemoveAttribute(Arg, Int32_val(PA)); return Val_unit; } @@ -978,6 +1286,19 @@ CAMLprim value llvm_set_param_alignment(LLVMValueRef Arg, value align) { 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); @@ -991,6 +1312,24 @@ CAMLprim value llvm_delete_block(LLVMBasicBlockRef 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; +} + +/* llbasicblock -> llbasicblock -> unit */ +CAMLprim value llvm_move_block_after(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) { + LLVMMoveBasicBlockAfter(BB, Pos); + return Val_unit; +} + /* string -> llvalue -> llbasicblock */ CAMLprim LLVMBasicBlockRef llvm_append_block(LLVMContextRef Context, value Name, LLVMValueRef Fn) { @@ -1013,8 +1352,17 @@ 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 <= LLVMLandingPad); + return Val_int(o); +} -/* llvalue -> ICmp.t */ +/* llvalue -> ICmp.t option */ CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) { CAMLparam0(); int x = LLVMGetICmpPredicate(Val); @@ -1026,6 +1374,25 @@ CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) { CAMLreturn(Val_int(0)); } +/* llvalue -> FCmp.t option */ +CAMLprim value llvm_instr_fcmp_predicate(LLVMValueRef Val) { + CAMLparam0(); + int x = LLVMGetFCmpPredicate(Val); + if (x) { + value Option = alloc(1, 0); + Field(Option, 0) = Val_int(x - LLVMRealPredicateFalse); + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + +/* llvalue -> llvalue */ +CAMLprim LLVMValueRef llvm_instr_clone(LLVMValueRef Inst) { + if (!LLVMIsAInstruction(Inst)) + failwith("Not an instruction"); + return LLVMInstructionClone(Inst); +} + /*--... Operations on call sites ...........................................--*/ @@ -1040,19 +1407,19 @@ CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) { return Val_unit; } -/* llvalue -> int -> Attribute.t -> unit */ +/* llvalue -> int -> int32 -> unit */ CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr, value index, value PA) { - LLVMAddInstrAttribute(Instr, Int_val(index), Int_val(PA)); + LLVMAddInstrAttribute(Instr, Int_val(index), Int32_val(PA)); return Val_unit; } -/* llvalue -> int -> Attribute.t -> unit */ +/* llvalue -> int -> int32 -> unit */ CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr, value index, value PA) { - LLVMRemoveInstrAttribute(Instr, Int_val(index), Int_val(PA)); + LLVMRemoveInstrAttribute(Instr, Int_val(index), Int32_val(PA)); return Val_unit; } @@ -1070,6 +1437,20 @@ CAMLprim value llvm_set_tail_call(value IsTailCall, return Val_unit; } +/*--... Operations on load/store instructions (only)........................--*/ + +/* llvalue -> bool */ +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 ............................................--*/ /* (llvalue * llbasicblock) -> llvalue -> unit */ @@ -1086,23 +1467,28 @@ CAMLprim value llvm_incoming(LLVMValueRef PhiNode) { unsigned I; CAMLparam0(); CAMLlocal3(Hd, Tl, Tmp); - + /* Build a tuple list of them. */ Tl = Val_int(0); for (I = LLVMCountIncoming(PhiNode); I != 0; ) { Hd = alloc(2, 0); Store_field(Hd, 0, (value) LLVMGetIncomingValue(PhiNode, --I)); Store_field(Hd, 1, (value) LLVMGetIncomingBlock(PhiNode, I)); - + Tmp = alloc(2, 0); Store_field(Tmp, 0, Hd); Store_field(Tmp, 1, Tl); Tl = Tmp; } - + CAMLreturn(Tl); } +/* llvalue -> unit */ +CAMLprim value llvm_delete_instruction(LLVMValueRef Instruction) { + LLVMInstructionEraseFromParent(Instruction); + return Val_unit; +} /*===-- Instruction builders ----------------------------------------------===*/ @@ -1113,12 +1499,15 @@ static void llvm_finalize_builder(value B) { } static struct custom_operations builder_ops = { - (char *) "IRBuilder", + (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) { @@ -1230,6 +1619,27 @@ 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) { @@ -1270,6 +1680,7 @@ CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) { Args[4], Args[5]); } +/* lltype -> llvalue -> int -> string -> llbuilder -> llvalue */ CAMLprim LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn, value NumClauses, value Name, value B) { @@ -1277,12 +1688,27 @@ CAMLprim LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn, 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 */ CAMLprim LLVMValueRef llvm_build_unreachable(value B) { return LLVMBuildUnreachable(Builder_val(B)); @@ -1496,6 +1922,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) { @@ -1669,9 +2113,9 @@ CAMLprim LLVMValueRef llvm_build_fcmp(value Pred, CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) { value Hd, Tl; LLVMValueRef FirstValue, PhiNode; - + assert(Incoming != Val_int(0) && "Empty list passed to Llvm.build_phi!"); - + Hd = Field(Incoming, 0); FirstValue = (LLVMValueRef) Field(Hd, 0); PhiNode = LLVMBuildPhi(Builder_val(B), LLVMTypeOf(FirstValue), @@ -1682,7 +2126,7 @@ CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) { LLVMAddIncoming(PhiNode, (LLVMValueRef*) &Field(Hd, 0), (LLVMBasicBlockRef*) &Field(Hd, 1), 1); } - + return PhiNode; } @@ -1718,7 +2162,7 @@ CAMLprim LLVMValueRef llvm_build_insertelement(LLVMValueRef Vec, LLVMValueRef Element, LLVMValueRef Idx, value Name, value B) { - return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx, + return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx, String_val(Name)); } @@ -1762,7 +2206,6 @@ CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS, return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name)); } - /*===-- Memory buffers ----------------------------------------------------===*/ /* string -> llmemorybuffer @@ -1771,11 +2214,11 @@ CAMLprim value llvm_memorybuffer_of_file(value Path) { CAMLparam1(Path); char *Message; LLVMMemoryBufferRef MemBuf; - + if (LLVMCreateMemoryBufferWithContentsOfFile(String_val(Path), &MemBuf, &Message)) llvm_raise(llvm_ioerror_exn, Message); - + CAMLreturn((value) MemBuf); } @@ -1784,13 +2227,37 @@ CAMLprim value llvm_memorybuffer_of_file(value Path) { CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) { char *Message; LLVMMemoryBufferRef MemBuf; - + if (LLVMCreateMemoryBufferWithSTDIN(&MemBuf, &Message)) llvm_raise(llvm_ioerror_exn, Message); - + + 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);