Home | History | Annotate | Download | only in llvm
      1 /*===-- llvm_ocaml.c - LLVM OCaml Glue --------------------------*- C++ -*-===*\
      2 |*                                                                            *|
      3 |*                     The LLVM Compiler Infrastructure                       *|
      4 |*                                                                            *|
      5 |* This file is distributed under the University of Illinois Open Source      *|
      6 |* License. See LICENSE.TXT for details.                                      *|
      7 |*                                                                            *|
      8 |*===----------------------------------------------------------------------===*|
      9 |*                                                                            *|
     10 |* This file glues LLVM's OCaml interface to its C interface. These functions *|
     11 |* are by and large transparent wrappers to the corresponding C functions.    *|
     12 |*                                                                            *|
     13 |* Note that these functions intentionally take liberties with the CAMLparamX *|
     14 |* macros, since most of the parameters are not GC heap objects.              *|
     15 |*                                                                            *|
     16 \*===----------------------------------------------------------------------===*/
     17 
     18 #include "llvm-c/Core.h"
     19 #include "caml/alloc.h"
     20 #include "caml/custom.h"
     21 #include "caml/memory.h"
     22 #include "caml/fail.h"
     23 #include "caml/callback.h"
     24 #include <assert.h>
     25 #include <stdlib.h>
     26 #include <string.h>
     27 
     28 
     29 /* Can't use the recommended caml_named_value mechanism for backwards
     30    compatibility reasons. This is largely equivalent. */
     31 static value llvm_ioerror_exn;
     32 
     33 CAMLprim value llvm_register_core_exns(value IoError) {
     34   llvm_ioerror_exn = Field(IoError, 0);
     35   register_global_root(&llvm_ioerror_exn);
     36 
     37   return Val_unit;
     38 }
     39 
     40 static void llvm_raise(value Prototype, char *Message) {
     41   CAMLparam1(Prototype);
     42   CAMLlocal1(CamlMessage);
     43 
     44   CamlMessage = copy_string(Message);
     45   LLVMDisposeMessage(Message);
     46 
     47   raise_with_arg(Prototype, CamlMessage);
     48   abort(); /* NOTREACHED */
     49 #ifdef CAMLnoreturn
     50   CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
     51 #endif
     52 }
     53 
     54 static value llvm_fatal_error_handler;
     55 
     56 static void llvm_fatal_error_trampoline(const char *Reason) {
     57   callback(llvm_fatal_error_handler, copy_string(Reason));
     58 }
     59 
     60 CAMLprim value llvm_install_fatal_error_handler(value Handler) {
     61   LLVMInstallFatalErrorHandler(llvm_fatal_error_trampoline);
     62   llvm_fatal_error_handler = Handler;
     63   caml_register_global_root(&llvm_fatal_error_handler);
     64   return Val_unit;
     65 }
     66 
     67 CAMLprim value llvm_reset_fatal_error_handler(value Unit) {
     68   caml_remove_global_root(&llvm_fatal_error_handler);
     69   LLVMResetFatalErrorHandler();
     70   return Val_unit;
     71 }
     72 
     73 CAMLprim value llvm_enable_pretty_stacktrace(value Unit) {
     74   LLVMEnablePrettyStackTrace();
     75   return Val_unit;
     76 }
     77 
     78 static value alloc_variant(int tag, void *Value) {
     79   value Iter = alloc_small(1, tag);
     80   Field(Iter, 0) = Val_op(Value);
     81   return Iter;
     82 }
     83 
     84 /* Macro to convert the C first/next/last/prev idiom to the Ocaml llpos/
     85    llrev_pos idiom. */
     86 #define DEFINE_ITERATORS(camlname, cname, pty, cty, pfun) \
     87   /* llmodule -> ('a, 'b) llpos */                        \
     88   CAMLprim value llvm_##camlname##_begin(pty Mom) {       \
     89     cty First = LLVMGetFirst##cname(Mom);                 \
     90     if (First)                                            \
     91       return alloc_variant(1, First);                     \
     92     return alloc_variant(0, Mom);                         \
     93   }                                                       \
     94                                                           \
     95   /* llvalue -> ('a, 'b) llpos */                         \
     96   CAMLprim value llvm_##camlname##_succ(cty Kid) {        \
     97     cty Next = LLVMGetNext##cname(Kid);                   \
     98     if (Next)                                             \
     99       return alloc_variant(1, Next);                      \
    100     return alloc_variant(0, pfun(Kid));                   \
    101   }                                                       \
    102                                                           \
    103   /* llmodule -> ('a, 'b) llrev_pos */                    \
    104   CAMLprim value llvm_##camlname##_end(pty Mom) {         \
    105     cty Last = LLVMGetLast##cname(Mom);                   \
    106     if (Last)                                             \
    107       return alloc_variant(1, Last);                      \
    108     return alloc_variant(0, Mom);                         \
    109   }                                                       \
    110                                                           \
    111   /* llvalue -> ('a, 'b) llrev_pos */                     \
    112   CAMLprim value llvm_##camlname##_pred(cty Kid) {        \
    113     cty Prev = LLVMGetPrevious##cname(Kid);               \
    114     if (Prev)                                             \
    115       return alloc_variant(1, Prev);                      \
    116     return alloc_variant(0, pfun(Kid));                   \
    117   }
    118 
    119 
    120 /*===-- Contexts ----------------------------------------------------------===*/
    121 
    122 /* unit -> llcontext */
    123 CAMLprim LLVMContextRef llvm_create_context(value Unit) {
    124   return LLVMContextCreate();
    125 }
    126 
    127 /* llcontext -> unit */
    128 CAMLprim value llvm_dispose_context(LLVMContextRef C) {
    129   LLVMContextDispose(C);
    130   return Val_unit;
    131 }
    132 
    133 /* unit -> llcontext */
    134 CAMLprim LLVMContextRef llvm_global_context(value Unit) {
    135   return LLVMGetGlobalContext();
    136 }
    137 
    138 /* llcontext -> string -> int */
    139 CAMLprim value llvm_mdkind_id(LLVMContextRef C, value Name) {
    140   unsigned MDKindID = LLVMGetMDKindIDInContext(C, String_val(Name),
    141                                                caml_string_length(Name));
    142   return Val_int(MDKindID);
    143 }
    144 
    145 /*===-- Modules -----------------------------------------------------------===*/
    146 
    147 /* llcontext -> string -> llmodule */
    148 CAMLprim LLVMModuleRef llvm_create_module(LLVMContextRef C, value ModuleID) {
    149   return LLVMModuleCreateWithNameInContext(String_val(ModuleID), C);
    150 }
    151 
    152 /* llmodule -> unit */
    153 CAMLprim value llvm_dispose_module(LLVMModuleRef M) {
    154   LLVMDisposeModule(M);
    155   return Val_unit;
    156 }
    157 
    158 /* llmodule -> string */
    159 CAMLprim value llvm_target_triple(LLVMModuleRef M) {
    160   return copy_string(LLVMGetTarget(M));
    161 }
    162 
    163 /* string -> llmodule -> unit */
    164 CAMLprim value llvm_set_target_triple(value Trip, LLVMModuleRef M) {
    165   LLVMSetTarget(M, String_val(Trip));
    166   return Val_unit;
    167 }
    168 
    169 /* llmodule -> string */
    170 CAMLprim value llvm_data_layout(LLVMModuleRef M) {
    171   return copy_string(LLVMGetDataLayout(M));
    172 }
    173 
    174 /* string -> llmodule -> unit */
    175 CAMLprim value llvm_set_data_layout(value Layout, LLVMModuleRef M) {
    176   LLVMSetDataLayout(M, String_val(Layout));
    177   return Val_unit;
    178 }
    179 
    180 /* llmodule -> unit */
    181 CAMLprim value llvm_dump_module(LLVMModuleRef M) {
    182   LLVMDumpModule(M);
    183   return Val_unit;
    184 }
    185 
    186 /* string -> llmodule -> unit */
    187 CAMLprim value llvm_print_module(value Filename, LLVMModuleRef M) {
    188   char* Message;
    189   if(LLVMPrintModuleToFile(M, String_val(Filename), &Message)) {
    190     llvm_raise(llvm_ioerror_exn, Message);
    191   }
    192 
    193   return Val_unit;
    194 }
    195 
    196 /* llmodule -> string */
    197 CAMLprim value llvm_string_of_llmodule(LLVMModuleRef M) {
    198   char* ModuleCStr;
    199   ModuleCStr = LLVMPrintModuleToString(M);
    200 
    201   value ModuleStr = caml_copy_string(ModuleCStr);
    202   LLVMDisposeMessage(ModuleCStr);
    203 
    204   return ModuleStr;
    205 }
    206 
    207 /* llmodule -> string -> unit */
    208 CAMLprim value llvm_set_module_inline_asm(LLVMModuleRef M, value Asm) {
    209   LLVMSetModuleInlineAsm(M, String_val(Asm));
    210   return Val_unit;
    211 }
    212 
    213 /*===-- Types -------------------------------------------------------------===*/
    214 
    215 /* lltype -> TypeKind.t */
    216 CAMLprim value llvm_classify_type(LLVMTypeRef Ty) {
    217   return Val_int(LLVMGetTypeKind(Ty));
    218 }
    219 
    220 CAMLprim value llvm_type_is_sized(LLVMTypeRef Ty) {
    221     return Val_bool(LLVMTypeIsSized(Ty));
    222 }
    223 
    224 /* lltype -> llcontext */
    225 CAMLprim LLVMContextRef llvm_type_context(LLVMTypeRef Ty) {
    226   return LLVMGetTypeContext(Ty);
    227 }
    228 
    229 /* lltype -> unit */
    230 CAMLprim value llvm_dump_type(LLVMTypeRef Val) {
    231   LLVMDumpType(Val);
    232   return Val_unit;
    233 }
    234 
    235 /* lltype -> string */
    236 CAMLprim value llvm_string_of_lltype(LLVMTypeRef M) {
    237   char* TypeCStr;
    238   TypeCStr = LLVMPrintTypeToString(M);
    239 
    240   value TypeStr = caml_copy_string(TypeCStr);
    241   LLVMDisposeMessage(TypeCStr);
    242 
    243   return TypeStr;
    244 }
    245 
    246 /*--... Operations on integer types ........................................--*/
    247 
    248 /* llcontext -> lltype */
    249 CAMLprim LLVMTypeRef llvm_i1_type (LLVMContextRef Context) {
    250   return LLVMInt1TypeInContext(Context);
    251 }
    252 
    253 /* llcontext -> lltype */
    254 CAMLprim LLVMTypeRef llvm_i8_type (LLVMContextRef Context) {
    255   return LLVMInt8TypeInContext(Context);
    256 }
    257 
    258 /* llcontext -> lltype */
    259 CAMLprim LLVMTypeRef llvm_i16_type (LLVMContextRef Context) {
    260   return LLVMInt16TypeInContext(Context);
    261 }
    262 
    263 /* llcontext -> lltype */
    264 CAMLprim LLVMTypeRef llvm_i32_type (LLVMContextRef Context) {
    265   return LLVMInt32TypeInContext(Context);
    266 }
    267 
    268 /* llcontext -> lltype */
    269 CAMLprim LLVMTypeRef llvm_i64_type (LLVMContextRef Context) {
    270   return LLVMInt64TypeInContext(Context);
    271 }
    272 
    273 /* llcontext -> int -> lltype */
    274 CAMLprim LLVMTypeRef llvm_integer_type(LLVMContextRef Context, value Width) {
    275   return LLVMIntTypeInContext(Context, Int_val(Width));
    276 }
    277 
    278 /* lltype -> int */
    279 CAMLprim value llvm_integer_bitwidth(LLVMTypeRef IntegerTy) {
    280   return Val_int(LLVMGetIntTypeWidth(IntegerTy));
    281 }
    282 
    283 /*--... Operations on real types ...........................................--*/
    284 
    285 /* llcontext -> lltype */
    286 CAMLprim LLVMTypeRef llvm_float_type(LLVMContextRef Context) {
    287   return LLVMFloatTypeInContext(Context);
    288 }
    289 
    290 /* llcontext -> lltype */
    291 CAMLprim LLVMTypeRef llvm_double_type(LLVMContextRef Context) {
    292   return LLVMDoubleTypeInContext(Context);
    293 }
    294 
    295 /* llcontext -> lltype */
    296 CAMLprim LLVMTypeRef llvm_x86fp80_type(LLVMContextRef Context) {
    297   return LLVMX86FP80TypeInContext(Context);
    298 }
    299 
    300 /* llcontext -> lltype */
    301 CAMLprim LLVMTypeRef llvm_fp128_type(LLVMContextRef Context) {
    302   return LLVMFP128TypeInContext(Context);
    303 }
    304 
    305 /* llcontext -> lltype */
    306 CAMLprim LLVMTypeRef llvm_ppc_fp128_type(LLVMContextRef Context) {
    307   return LLVMPPCFP128TypeInContext(Context);
    308 }
    309 
    310 /*--... Operations on function types .......................................--*/
    311 
    312 /* lltype -> lltype array -> lltype */
    313 CAMLprim LLVMTypeRef llvm_function_type(LLVMTypeRef RetTy, value ParamTys) {
    314   return LLVMFunctionType(RetTy, (LLVMTypeRef *) ParamTys,
    315                           Wosize_val(ParamTys), 0);
    316 }
    317 
    318 /* lltype -> lltype array -> lltype */
    319 CAMLprim LLVMTypeRef llvm_var_arg_function_type(LLVMTypeRef RetTy,
    320                                                 value ParamTys) {
    321   return LLVMFunctionType(RetTy, (LLVMTypeRef *) ParamTys,
    322                           Wosize_val(ParamTys), 1);
    323 }
    324 
    325 /* lltype -> bool */
    326 CAMLprim value llvm_is_var_arg(LLVMTypeRef FunTy) {
    327   return Val_bool(LLVMIsFunctionVarArg(FunTy));
    328 }
    329 
    330 /* lltype -> lltype array */
    331 CAMLprim value llvm_param_types(LLVMTypeRef FunTy) {
    332   value Tys = alloc(LLVMCountParamTypes(FunTy), 0);
    333   LLVMGetParamTypes(FunTy, (LLVMTypeRef *) Tys);
    334   return Tys;
    335 }
    336 
    337 /*--... Operations on struct types .........................................--*/
    338 
    339 /* llcontext -> lltype array -> lltype */
    340 CAMLprim LLVMTypeRef llvm_struct_type(LLVMContextRef C, value ElementTypes) {
    341   return LLVMStructTypeInContext(C, (LLVMTypeRef *) ElementTypes,
    342                                  Wosize_val(ElementTypes), 0);
    343 }
    344 
    345 /* llcontext -> lltype array -> lltype */
    346 CAMLprim LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C,
    347                                              value ElementTypes) {
    348   return LLVMStructTypeInContext(C, (LLVMTypeRef *) ElementTypes,
    349                                  Wosize_val(ElementTypes), 1);
    350 }
    351 
    352 /* llcontext -> string -> lltype */
    353 CAMLprim LLVMTypeRef llvm_named_struct_type(LLVMContextRef C,
    354                                             value Name) {
    355   return LLVMStructCreateNamed(C, String_val(Name));
    356 }
    357 
    358 CAMLprim value llvm_struct_set_body(LLVMTypeRef Ty,
    359                                     value ElementTypes,
    360                                     value Packed) {
    361   LLVMStructSetBody(Ty, (LLVMTypeRef *) ElementTypes,
    362                     Wosize_val(ElementTypes), Bool_val(Packed));
    363   return Val_unit;
    364 }
    365 
    366 /* lltype -> string option */
    367 CAMLprim value llvm_struct_name(LLVMTypeRef Ty)
    368 {
    369   CAMLparam0();
    370   const char *C = LLVMGetStructName(Ty);
    371   if (C) {
    372     CAMLlocal1(result);
    373     result = caml_alloc_small(1, 0);
    374     Store_field(result, 0, caml_copy_string(C));
    375     CAMLreturn(result);
    376   }
    377   CAMLreturn(Val_int(0));
    378 }
    379 
    380 /* lltype -> lltype array */
    381 CAMLprim value llvm_struct_element_types(LLVMTypeRef StructTy) {
    382   value Tys = alloc(LLVMCountStructElementTypes(StructTy), 0);
    383   LLVMGetStructElementTypes(StructTy, (LLVMTypeRef *) Tys);
    384   return Tys;
    385 }
    386 
    387 /* lltype -> bool */
    388 CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) {
    389   return Val_bool(LLVMIsPackedStruct(StructTy));
    390 }
    391 
    392 /* lltype -> bool */
    393 CAMLprim value llvm_is_opaque(LLVMTypeRef StructTy) {
    394   return Val_bool(LLVMIsOpaqueStruct(StructTy));
    395 }
    396 
    397 /*--... Operations on array, pointer, and vector types .....................--*/
    398 
    399 /* lltype -> int -> lltype */
    400 CAMLprim LLVMTypeRef llvm_array_type(LLVMTypeRef ElementTy, value Count) {
    401   return LLVMArrayType(ElementTy, Int_val(Count));
    402 }
    403 
    404 /* lltype -> lltype */
    405 CAMLprim LLVMTypeRef llvm_pointer_type(LLVMTypeRef ElementTy) {
    406   return LLVMPointerType(ElementTy, 0);
    407 }
    408 
    409 /* lltype -> int -> lltype */
    410 CAMLprim LLVMTypeRef llvm_qualified_pointer_type(LLVMTypeRef ElementTy,
    411                                                  value AddressSpace) {
    412   return LLVMPointerType(ElementTy, Int_val(AddressSpace));
    413 }
    414 
    415 /* lltype -> int -> lltype */
    416 CAMLprim LLVMTypeRef llvm_vector_type(LLVMTypeRef ElementTy, value Count) {
    417   return LLVMVectorType(ElementTy, Int_val(Count));
    418 }
    419 
    420 /* lltype -> int */
    421 CAMLprim value llvm_array_length(LLVMTypeRef ArrayTy) {
    422   return Val_int(LLVMGetArrayLength(ArrayTy));
    423 }
    424 
    425 /* lltype -> int */
    426 CAMLprim value llvm_address_space(LLVMTypeRef PtrTy) {
    427   return Val_int(LLVMGetPointerAddressSpace(PtrTy));
    428 }
    429 
    430 /* lltype -> int */
    431 CAMLprim value llvm_vector_size(LLVMTypeRef VectorTy) {
    432   return Val_int(LLVMGetVectorSize(VectorTy));
    433 }
    434 
    435 /*--... Operations on other types ..........................................--*/
    436 
    437 /* llcontext -> lltype */
    438 CAMLprim LLVMTypeRef llvm_void_type (LLVMContextRef Context) {
    439   return LLVMVoidTypeInContext(Context);
    440 }
    441 
    442 /* llcontext -> lltype */
    443 CAMLprim LLVMTypeRef llvm_label_type(LLVMContextRef Context) {
    444   return LLVMLabelTypeInContext(Context);
    445 }
    446 
    447 /* llcontext -> lltype */
    448 CAMLprim LLVMTypeRef llvm_x86_mmx_type(LLVMContextRef Context) {
    449   return LLVMX86MMXTypeInContext(Context);
    450 }
    451 
    452 CAMLprim value llvm_type_by_name(LLVMModuleRef M, value Name)
    453 {
    454   CAMLparam1(Name);
    455   LLVMTypeRef Ty = LLVMGetTypeByName(M, String_val(Name));
    456   if (Ty) {
    457     value Option = alloc(1, 0);
    458     Field(Option, 0) = (value) Ty;
    459     CAMLreturn(Option);
    460   }
    461   CAMLreturn(Val_int(0));
    462 }
    463 
    464 /*===-- VALUES ------------------------------------------------------------===*/
    465 
    466 /* llvalue -> lltype */
    467 CAMLprim LLVMTypeRef llvm_type_of(LLVMValueRef Val) {
    468   return LLVMTypeOf(Val);
    469 }
    470 
    471 /* keep in sync with ValueKind.t */
    472 enum ValueKind {
    473   NullValue=0,
    474   Argument,
    475   BasicBlock,
    476   InlineAsm,
    477   MDNode,
    478   MDString,
    479   BlockAddress,
    480   ConstantAggregateZero,
    481   ConstantArray,
    482   ConstantDataArray,
    483   ConstantDataVector,
    484   ConstantExpr,
    485   ConstantFP,
    486   ConstantInt,
    487   ConstantPointerNull,
    488   ConstantStruct,
    489   ConstantVector,
    490   Function,
    491   GlobalAlias,
    492   GlobalVariable,
    493   UndefValue,
    494   Instruction
    495 };
    496 
    497 /* llvalue -> ValueKind.t */
    498 #define DEFINE_CASE(Val, Kind) \
    499     do {if (LLVMIsA##Kind(Val)) CAMLreturn(Val_int(Kind));} while(0)
    500 
    501 CAMLprim value llvm_classify_value(LLVMValueRef Val) {
    502   CAMLparam0();
    503   if (!Val)
    504     CAMLreturn(Val_int(NullValue));
    505   if (LLVMIsAConstant(Val)) {
    506     DEFINE_CASE(Val, BlockAddress);
    507     DEFINE_CASE(Val, ConstantAggregateZero);
    508     DEFINE_CASE(Val, ConstantArray);
    509     DEFINE_CASE(Val, ConstantDataArray);
    510     DEFINE_CASE(Val, ConstantDataVector);
    511     DEFINE_CASE(Val, ConstantExpr);
    512     DEFINE_CASE(Val, ConstantFP);
    513     DEFINE_CASE(Val, ConstantInt);
    514     DEFINE_CASE(Val, ConstantPointerNull);
    515     DEFINE_CASE(Val, ConstantStruct);
    516     DEFINE_CASE(Val, ConstantVector);
    517   }
    518   if (LLVMIsAInstruction(Val)) {
    519     CAMLlocal1(result);
    520     result = caml_alloc_small(1, 0);
    521     Store_field(result, 0, Val_int(LLVMGetInstructionOpcode(Val)));
    522     CAMLreturn(result);
    523   }
    524   if (LLVMIsAGlobalValue(Val)) {
    525     DEFINE_CASE(Val, Function);
    526     DEFINE_CASE(Val, GlobalAlias);
    527     DEFINE_CASE(Val, GlobalVariable);
    528   }
    529   DEFINE_CASE(Val, Argument);
    530   DEFINE_CASE(Val, BasicBlock);
    531   DEFINE_CASE(Val, InlineAsm);
    532   DEFINE_CASE(Val, MDNode);
    533   DEFINE_CASE(Val, MDString);
    534   DEFINE_CASE(Val, UndefValue);
    535   failwith("Unknown Value class");
    536 }
    537 
    538 /* llvalue -> string */
    539 CAMLprim value llvm_value_name(LLVMValueRef Val) {
    540   return copy_string(LLVMGetValueName(Val));
    541 }
    542 
    543 /* string -> llvalue -> unit */
    544 CAMLprim value llvm_set_value_name(value Name, LLVMValueRef Val) {
    545   LLVMSetValueName(Val, String_val(Name));
    546   return Val_unit;
    547 }
    548 
    549 /* llvalue -> unit */
    550 CAMLprim value llvm_dump_value(LLVMValueRef Val) {
    551   LLVMDumpValue(Val);
    552   return Val_unit;
    553 }
    554 
    555 /* llvalue -> string */
    556 CAMLprim value llvm_string_of_llvalue(LLVMValueRef M) {
    557   char* ValueCStr;
    558   ValueCStr = LLVMPrintValueToString(M);
    559 
    560   value ValueStr = caml_copy_string(ValueCStr);
    561   LLVMDisposeMessage(ValueCStr);
    562 
    563   return ValueStr;
    564 }
    565 
    566 /* llvalue -> llvalue -> unit */
    567 CAMLprim value llvm_replace_all_uses_with(LLVMValueRef OldVal,
    568                                           LLVMValueRef NewVal) {
    569   LLVMReplaceAllUsesWith(OldVal, NewVal);
    570   return Val_unit;
    571 }
    572 
    573 /*--... Operations on users ................................................--*/
    574 
    575 /* llvalue -> int -> llvalue */
    576 CAMLprim LLVMValueRef llvm_operand(LLVMValueRef V, value I) {
    577   return LLVMGetOperand(V, Int_val(I));
    578 }
    579 
    580 /* llvalue -> int -> llvalue -> unit */
    581 CAMLprim value llvm_set_operand(LLVMValueRef U, value I, LLVMValueRef V) {
    582   LLVMSetOperand(U, Int_val(I), V);
    583   return Val_unit;
    584 }
    585 
    586 /* llvalue -> int */
    587 CAMLprim value llvm_num_operands(LLVMValueRef V) {
    588   return Val_int(LLVMGetNumOperands(V));
    589 }
    590 
    591 /*--... Operations on constants of (mostly) any type .......................--*/
    592 
    593 /* llvalue -> bool */
    594 CAMLprim value llvm_is_constant(LLVMValueRef Val) {
    595   return Val_bool(LLVMIsConstant(Val));
    596 }
    597 
    598 /* llvalue -> bool */
    599 CAMLprim value llvm_is_null(LLVMValueRef Val) {
    600   return Val_bool(LLVMIsNull(Val));
    601 }
    602 
    603 /* llvalue -> bool */
    604 CAMLprim value llvm_is_undef(LLVMValueRef Val) {
    605   return Val_bool(LLVMIsUndef(Val));
    606 }
    607 
    608 /* llvalue -> Opcode.t */
    609 CAMLprim value llvm_constexpr_get_opcode(LLVMValueRef Val) {
    610   return LLVMIsAConstantExpr(Val) ?
    611       Val_int(LLVMGetConstOpcode(Val)) : Val_int(0);
    612 }
    613 
    614 /*--... Operations on instructions .........................................--*/
    615 
    616 /* llvalue -> bool */
    617 CAMLprim value llvm_has_metadata(LLVMValueRef Val) {
    618   return Val_bool(LLVMHasMetadata(Val));
    619 }
    620 
    621 /* llvalue -> int -> llvalue option */
    622 CAMLprim value llvm_metadata(LLVMValueRef Val, value MDKindID) {
    623   CAMLparam1(MDKindID);
    624   LLVMValueRef MD;
    625   if ((MD = LLVMGetMetadata(Val, Int_val(MDKindID)))) {
    626     value Option = alloc(1, 0);
    627     Field(Option, 0) = (value) MD;
    628     CAMLreturn(Option);
    629   }
    630   CAMLreturn(Val_int(0));
    631 }
    632 
    633 /* llvalue -> int -> llvalue -> unit */
    634 CAMLprim value llvm_set_metadata(LLVMValueRef Val, value MDKindID,
    635                                  LLVMValueRef MD) {
    636   LLVMSetMetadata(Val, Int_val(MDKindID), MD);
    637   return Val_unit;
    638 }
    639 
    640 /* llvalue -> int -> unit */
    641 CAMLprim value llvm_clear_metadata(LLVMValueRef Val, value MDKindID) {
    642   LLVMSetMetadata(Val, Int_val(MDKindID), NULL);
    643   return Val_unit;
    644 }
    645 
    646 
    647 /*--... Operations on metadata .............................................--*/
    648 
    649 /* llcontext -> string -> llvalue */
    650 CAMLprim LLVMValueRef llvm_mdstring(LLVMContextRef C, value S) {
    651   return LLVMMDStringInContext(C, String_val(S), caml_string_length(S));
    652 }
    653 
    654 /* llcontext -> llvalue array -> llvalue */
    655 CAMLprim LLVMValueRef llvm_mdnode(LLVMContextRef C, value ElementVals) {
    656   return LLVMMDNodeInContext(C, (LLVMValueRef*) Op_val(ElementVals),
    657                              Wosize_val(ElementVals));
    658 }
    659 
    660 /* llvalue -> string option */
    661 CAMLprim value llvm_get_mdstring(LLVMValueRef V) {
    662   CAMLparam0();
    663   const char *S;
    664   unsigned Len;
    665 
    666   if ((S = LLVMGetMDString(V, &Len))) {
    667     CAMLlocal2(Option, Str);
    668 
    669     Str = caml_alloc_string(Len);
    670     memcpy(String_val(Str), S, Len);
    671     Option = alloc(1,0);
    672     Store_field(Option, 0, Str);
    673     CAMLreturn(Option);
    674   }
    675   CAMLreturn(Val_int(0));
    676 }
    677 
    678 /* llmodule -> string -> llvalue array */
    679 CAMLprim value llvm_get_namedmd(LLVMModuleRef M, value Name)
    680 {
    681   CAMLparam1(Name);
    682   CAMLlocal1(Nodes);
    683   Nodes = alloc(LLVMGetNamedMetadataNumOperands(M, String_val(Name)), 0);
    684   LLVMGetNamedMetadataOperands(M, String_val(Name), (LLVMValueRef *) Nodes);
    685   CAMLreturn(Nodes);
    686 }
    687 
    688 /* llmodule -> string -> llvalue -> unit */
    689 CAMLprim value llvm_append_namedmd(LLVMModuleRef M, value Name, LLVMValueRef Val) {
    690   LLVMAddNamedMetadataOperand(M, String_val(Name), Val);
    691   return Val_unit;
    692 }
    693 
    694 /*--... Operations on scalar constants .....................................--*/
    695 
    696 /* lltype -> int -> llvalue */
    697 CAMLprim LLVMValueRef llvm_const_int(LLVMTypeRef IntTy, value N) {
    698   return LLVMConstInt(IntTy, (long long) Int_val(N), 1);
    699 }
    700 
    701 /* lltype -> Int64.t -> bool -> llvalue */
    702 CAMLprim LLVMValueRef llvm_const_of_int64(LLVMTypeRef IntTy, value N,
    703                                           value SExt) {
    704   return LLVMConstInt(IntTy, Int64_val(N), Bool_val(SExt));
    705 }
    706 
    707 /* llvalue -> Int64.t */
    708 CAMLprim value llvm_int64_of_const(LLVMValueRef Const)
    709 {
    710   CAMLparam0();
    711   if (LLVMIsAConstantInt(Const) &&
    712       LLVMGetIntTypeWidth(LLVMTypeOf(Const)) <= 64) {
    713     value Option = alloc(1, 0);
    714     Field(Option, 0) = caml_copy_int64(LLVMConstIntGetSExtValue(Const));
    715     CAMLreturn(Option);
    716   }
    717   CAMLreturn(Val_int(0));
    718 }
    719 
    720 /* lltype -> string -> int -> llvalue */
    721 CAMLprim LLVMValueRef llvm_const_int_of_string(LLVMTypeRef IntTy, value S,
    722                                                value Radix) {
    723   return LLVMConstIntOfStringAndSize(IntTy, String_val(S), caml_string_length(S),
    724                                      Int_val(Radix));
    725 }
    726 
    727 /* lltype -> float -> llvalue */
    728 CAMLprim LLVMValueRef llvm_const_float(LLVMTypeRef RealTy, value N) {
    729   return LLVMConstReal(RealTy, Double_val(N));
    730 }
    731 
    732 /* lltype -> string -> llvalue */
    733 CAMLprim LLVMValueRef llvm_const_float_of_string(LLVMTypeRef RealTy, value S) {
    734   return LLVMConstRealOfStringAndSize(RealTy, String_val(S),
    735                                       caml_string_length(S));
    736 }
    737 
    738 /*--... Operations on composite constants ..................................--*/
    739 
    740 /* llcontext -> string -> llvalue */
    741 CAMLprim LLVMValueRef llvm_const_string(LLVMContextRef Context, value Str,
    742                                         value NullTerminate) {
    743   return LLVMConstStringInContext(Context, String_val(Str), string_length(Str),
    744                                   1);
    745 }
    746 
    747 /* llcontext -> string -> llvalue */
    748 CAMLprim LLVMValueRef llvm_const_stringz(LLVMContextRef Context, value Str,
    749                                          value NullTerminate) {
    750   return LLVMConstStringInContext(Context, String_val(Str), string_length(Str),
    751                                   0);
    752 }
    753 
    754 /* lltype -> llvalue array -> llvalue */
    755 CAMLprim LLVMValueRef llvm_const_array(LLVMTypeRef ElementTy,
    756                                                value ElementVals) {
    757   return LLVMConstArray(ElementTy, (LLVMValueRef*) Op_val(ElementVals),
    758                         Wosize_val(ElementVals));
    759 }
    760 
    761 /* llcontext -> llvalue array -> llvalue */
    762 CAMLprim LLVMValueRef llvm_const_struct(LLVMContextRef C, value ElementVals) {
    763   return LLVMConstStructInContext(C, (LLVMValueRef *) Op_val(ElementVals),
    764                                   Wosize_val(ElementVals), 0);
    765 }
    766 
    767 /* lltype -> llvalue array -> llvalue */
    768 CAMLprim LLVMValueRef llvm_const_named_struct(LLVMTypeRef Ty, value ElementVals) {
    769     return LLVMConstNamedStruct(Ty, (LLVMValueRef *) Op_val(ElementVals),  Wosize_val(ElementVals));
    770 }
    771 
    772 /* llcontext -> llvalue array -> llvalue */
    773 CAMLprim LLVMValueRef llvm_const_packed_struct(LLVMContextRef C,
    774                                                value ElementVals) {
    775   return LLVMConstStructInContext(C, (LLVMValueRef *) Op_val(ElementVals),
    776                                   Wosize_val(ElementVals), 1);
    777 }
    778 
    779 /* llvalue array -> llvalue */
    780 CAMLprim LLVMValueRef llvm_const_vector(value ElementVals) {
    781   return LLVMConstVector((LLVMValueRef*) Op_val(ElementVals),
    782                          Wosize_val(ElementVals));
    783 }
    784 
    785 /*--... Constant expressions ...............................................--*/
    786 
    787 /* Icmp.t -> llvalue -> llvalue -> llvalue */
    788 CAMLprim LLVMValueRef llvm_const_icmp(value Pred,
    789                                       LLVMValueRef LHSConstant,
    790                                       LLVMValueRef RHSConstant) {
    791   return LLVMConstICmp(Int_val(Pred) + LLVMIntEQ, LHSConstant, RHSConstant);
    792 }
    793 
    794 /* Fcmp.t -> llvalue -> llvalue -> llvalue */
    795 CAMLprim LLVMValueRef llvm_const_fcmp(value Pred,
    796                                       LLVMValueRef LHSConstant,
    797                                       LLVMValueRef RHSConstant) {
    798   return LLVMConstFCmp(Int_val(Pred), LHSConstant, RHSConstant);
    799 }
    800 
    801 /* llvalue -> llvalue array -> llvalue */
    802 CAMLprim LLVMValueRef llvm_const_gep(LLVMValueRef ConstantVal, value Indices) {
    803   return LLVMConstGEP(ConstantVal, (LLVMValueRef*) Op_val(Indices),
    804                       Wosize_val(Indices));
    805 }
    806 
    807 /* llvalue -> llvalue array -> llvalue */
    808 CAMLprim LLVMValueRef llvm_const_in_bounds_gep(LLVMValueRef ConstantVal,
    809                                                value Indices) {
    810   return LLVMConstInBoundsGEP(ConstantVal, (LLVMValueRef*) Op_val(Indices),
    811                               Wosize_val(Indices));
    812 }
    813 
    814 /* llvalue -> lltype -> is_signed:bool -> llvalue */
    815 CAMLprim LLVMValueRef llvm_const_intcast(LLVMValueRef CV, LLVMTypeRef T,
    816                                          value IsSigned) {
    817   return LLVMConstIntCast(CV, T, Bool_val(IsSigned));
    818 }
    819 
    820 /* llvalue -> int array -> llvalue */
    821 CAMLprim LLVMValueRef llvm_const_extractvalue(LLVMValueRef Aggregate,
    822                                               value Indices) {
    823   CAMLparam1(Indices);
    824   int size = Wosize_val(Indices);
    825   int i;
    826   LLVMValueRef result;
    827 
    828   unsigned* idxs = (unsigned*)malloc(size * sizeof(unsigned));
    829   for (i = 0; i < size; i++) {
    830     idxs[i] = Int_val(Field(Indices, i));
    831   }
    832 
    833   result = LLVMConstExtractValue(Aggregate, idxs, size);
    834   free(idxs);
    835   CAMLreturnT(LLVMValueRef, result);
    836 }
    837 
    838 /* llvalue -> llvalue -> int array -> llvalue */
    839 CAMLprim LLVMValueRef llvm_const_insertvalue(LLVMValueRef Aggregate,
    840                                              LLVMValueRef Val, value Indices) {
    841   CAMLparam1(Indices);
    842   int size = Wosize_val(Indices);
    843   int i;
    844   LLVMValueRef result;
    845 
    846   unsigned* idxs = (unsigned*)malloc(size * sizeof(unsigned));
    847   for (i = 0; i < size; i++) {
    848     idxs[i] = Int_val(Field(Indices, i));
    849   }
    850 
    851   result = LLVMConstInsertValue(Aggregate, Val, idxs, size);
    852   free(idxs);
    853   CAMLreturnT(LLVMValueRef, result);
    854 }
    855 
    856 /* lltype -> string -> string -> bool -> bool -> llvalue */
    857 CAMLprim LLVMValueRef llvm_const_inline_asm(LLVMTypeRef Ty, value Asm,
    858                                      value Constraints, value HasSideEffects,
    859                                      value IsAlignStack) {
    860   return LLVMConstInlineAsm(Ty, String_val(Asm), String_val(Constraints),
    861                             Bool_val(HasSideEffects), Bool_val(IsAlignStack));
    862 }
    863 
    864 /*--... Operations on global variables, functions, and aliases (globals) ...--*/
    865 
    866 /* llvalue -> bool */
    867 CAMLprim value llvm_is_declaration(LLVMValueRef Global) {
    868   return Val_bool(LLVMIsDeclaration(Global));
    869 }
    870 
    871 /* llvalue -> Linkage.t */
    872 CAMLprim value llvm_linkage(LLVMValueRef Global) {
    873   return Val_int(LLVMGetLinkage(Global));
    874 }
    875 
    876 /* Linkage.t -> llvalue -> unit */
    877 CAMLprim value llvm_set_linkage(value Linkage, LLVMValueRef Global) {
    878   LLVMSetLinkage(Global, Int_val(Linkage));
    879   return Val_unit;
    880 }
    881 
    882 /* llvalue -> string */
    883 CAMLprim value llvm_section(LLVMValueRef Global) {
    884   return copy_string(LLVMGetSection(Global));
    885 }
    886 
    887 /* string -> llvalue -> unit */
    888 CAMLprim value llvm_set_section(value Section, LLVMValueRef Global) {
    889   LLVMSetSection(Global, String_val(Section));
    890   return Val_unit;
    891 }
    892 
    893 /* llvalue -> Visibility.t */
    894 CAMLprim value llvm_visibility(LLVMValueRef Global) {
    895   return Val_int(LLVMGetVisibility(Global));
    896 }
    897 
    898 /* Visibility.t -> llvalue -> unit */
    899 CAMLprim value llvm_set_visibility(value Viz, LLVMValueRef Global) {
    900   LLVMSetVisibility(Global, Int_val(Viz));
    901   return Val_unit;
    902 }
    903 
    904 /* llvalue -> int */
    905 CAMLprim value llvm_alignment(LLVMValueRef Global) {
    906   return Val_int(LLVMGetAlignment(Global));
    907 }
    908 
    909 /* int -> llvalue -> unit */
    910 CAMLprim value llvm_set_alignment(value Bytes, LLVMValueRef Global) {
    911   LLVMSetAlignment(Global, Int_val(Bytes));
    912   return Val_unit;
    913 }
    914 
    915 /*--... Operations on uses .................................................--*/
    916 
    917 /* llvalue -> lluse option */
    918 CAMLprim value llvm_use_begin(LLVMValueRef Val) {
    919   CAMLparam0();
    920   LLVMUseRef First;
    921   if ((First = LLVMGetFirstUse(Val))) {
    922     value Option = alloc(1, 0);
    923     Field(Option, 0) = (value) First;
    924     CAMLreturn(Option);
    925   }
    926   CAMLreturn(Val_int(0));
    927 }
    928 
    929 /* lluse -> lluse option */
    930 CAMLprim value llvm_use_succ(LLVMUseRef U) {
    931   CAMLparam0();
    932   LLVMUseRef Next;
    933   if ((Next = LLVMGetNextUse(U))) {
    934     value Option = alloc(1, 0);
    935     Field(Option, 0) = (value) Next;
    936     CAMLreturn(Option);
    937   }
    938   CAMLreturn(Val_int(0));
    939 }
    940 
    941 /* lluse -> llvalue */
    942 CAMLprim LLVMValueRef llvm_user(LLVMUseRef UR) {
    943   return LLVMGetUser(UR);
    944 }
    945 
    946 /* lluse -> llvalue */
    947 CAMLprim LLVMValueRef llvm_used_value(LLVMUseRef UR) {
    948   return LLVMGetUsedValue(UR);
    949 }
    950 
    951 /*--... Operations on global variables .....................................--*/
    952 
    953 DEFINE_ITERATORS(global, Global, LLVMModuleRef, LLVMValueRef,
    954                  LLVMGetGlobalParent)
    955 
    956 /* lltype -> string -> llmodule -> llvalue */
    957 CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name,
    958                                           LLVMModuleRef M) {
    959   LLVMValueRef GlobalVar;
    960   if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
    961     if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty)
    962       return LLVMConstBitCast(GlobalVar, LLVMPointerType(Ty, 0));
    963     return GlobalVar;
    964   }
    965   return LLVMAddGlobal(M, Ty, String_val(Name));
    966 }
    967 
    968 /* lltype -> string -> int -> llmodule -> llvalue */
    969 CAMLprim LLVMValueRef llvm_declare_qualified_global(LLVMTypeRef Ty, value Name,
    970                                                     value AddressSpace,
    971                                                     LLVMModuleRef M) {
    972   LLVMValueRef GlobalVar;
    973   if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
    974     if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty)
    975       return LLVMConstBitCast(GlobalVar,
    976                               LLVMPointerType(Ty, Int_val(AddressSpace)));
    977     return GlobalVar;
    978   }
    979   return LLVMAddGlobalInAddressSpace(M, Ty, String_val(Name),
    980                                      Int_val(AddressSpace));
    981 }
    982 
    983 /* string -> llmodule -> llvalue option */
    984 CAMLprim value llvm_lookup_global(value Name, LLVMModuleRef M) {
    985   CAMLparam1(Name);
    986   LLVMValueRef GlobalVar;
    987   if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
    988     value Option = alloc(1, 0);
    989     Field(Option, 0) = (value) GlobalVar;
    990     CAMLreturn(Option);
    991   }
    992   CAMLreturn(Val_int(0));
    993 }
    994 
    995 /* string -> llvalue -> llmodule -> llvalue */
    996 CAMLprim LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer,
    997                                          LLVMModuleRef M) {
    998   LLVMValueRef GlobalVar = LLVMAddGlobal(M, LLVMTypeOf(Initializer),
    999                                          String_val(Name));
   1000   LLVMSetInitializer(GlobalVar, Initializer);
   1001   return GlobalVar;
   1002 }
   1003 
   1004 /* string -> llvalue -> int -> llmodule -> llvalue */
   1005 CAMLprim LLVMValueRef llvm_define_qualified_global(value Name,
   1006                                                    LLVMValueRef Initializer,
   1007                                                    value AddressSpace,
   1008                                                    LLVMModuleRef M) {
   1009   LLVMValueRef GlobalVar = LLVMAddGlobalInAddressSpace(M,
   1010                                                        LLVMTypeOf(Initializer),
   1011                                                        String_val(Name),
   1012                                                        Int_val(AddressSpace));
   1013   LLVMSetInitializer(GlobalVar, Initializer);
   1014   return GlobalVar;
   1015 }
   1016 
   1017 /* llvalue -> unit */
   1018 CAMLprim value llvm_delete_global(LLVMValueRef GlobalVar) {
   1019   LLVMDeleteGlobal(GlobalVar);
   1020   return Val_unit;
   1021 }
   1022 
   1023 /* llvalue -> llvalue -> unit */
   1024 CAMLprim value llvm_set_initializer(LLVMValueRef ConstantVal,
   1025                                     LLVMValueRef GlobalVar) {
   1026   LLVMSetInitializer(GlobalVar, ConstantVal);
   1027   return Val_unit;
   1028 }
   1029 
   1030 /* llvalue -> unit */
   1031 CAMLprim value llvm_remove_initializer(LLVMValueRef GlobalVar) {
   1032   LLVMSetInitializer(GlobalVar, NULL);
   1033   return Val_unit;
   1034 }
   1035 
   1036 /* llvalue -> bool */
   1037 CAMLprim value llvm_is_thread_local(LLVMValueRef GlobalVar) {
   1038   return Val_bool(LLVMIsThreadLocal(GlobalVar));
   1039 }
   1040 
   1041 /* bool -> llvalue -> unit */
   1042 CAMLprim value llvm_set_thread_local(value IsThreadLocal,
   1043                                      LLVMValueRef GlobalVar) {
   1044   LLVMSetThreadLocal(GlobalVar, Bool_val(IsThreadLocal));
   1045   return Val_unit;
   1046 }
   1047 
   1048 /* llvalue -> ThreadLocalMode.t */
   1049 CAMLprim value llvm_thread_local_mode(LLVMValueRef GlobalVar) {
   1050   return Val_int(LLVMGetThreadLocalMode(GlobalVar));
   1051 }
   1052 
   1053 /* ThreadLocalMode.t -> llvalue -> unit */
   1054 CAMLprim value llvm_set_thread_local_mode(value ThreadLocalMode,
   1055                                           LLVMValueRef GlobalVar) {
   1056   LLVMSetThreadLocalMode(GlobalVar, Int_val(ThreadLocalMode));
   1057   return Val_unit;
   1058 }
   1059 
   1060 /* llvalue -> bool */
   1061 CAMLprim value llvm_is_externally_initialized(LLVMValueRef GlobalVar) {
   1062   return Val_bool(LLVMIsExternallyInitialized(GlobalVar));
   1063 }
   1064 
   1065 /* bool -> llvalue -> unit */
   1066 CAMLprim value llvm_set_externally_initialized(value IsExternallyInitialized,
   1067                                                LLVMValueRef GlobalVar) {
   1068   LLVMSetExternallyInitialized(GlobalVar, Bool_val(IsExternallyInitialized));
   1069   return Val_unit;
   1070 }
   1071 
   1072 /* llvalue -> bool */
   1073 CAMLprim value llvm_is_global_constant(LLVMValueRef GlobalVar) {
   1074   return Val_bool(LLVMIsGlobalConstant(GlobalVar));
   1075 }
   1076 
   1077 /* bool -> llvalue -> unit */
   1078 CAMLprim value llvm_set_global_constant(value Flag, LLVMValueRef GlobalVar) {
   1079   LLVMSetGlobalConstant(GlobalVar, Bool_val(Flag));
   1080   return Val_unit;
   1081 }
   1082 
   1083 /*--... Operations on aliases ..............................................--*/
   1084 
   1085 CAMLprim LLVMValueRef llvm_add_alias(LLVMModuleRef M, LLVMTypeRef Ty,
   1086                                      LLVMValueRef Aliasee, value Name) {
   1087   return LLVMAddAlias(M, Ty, Aliasee, String_val(Name));
   1088 }
   1089 
   1090 /*--... Operations on functions ............................................--*/
   1091 
   1092 DEFINE_ITERATORS(function, Function, LLVMModuleRef, LLVMValueRef,
   1093                  LLVMGetGlobalParent)
   1094 
   1095 /* string -> lltype -> llmodule -> llvalue */
   1096 CAMLprim LLVMValueRef llvm_declare_function(value Name, LLVMTypeRef Ty,
   1097                                             LLVMModuleRef M) {
   1098   LLVMValueRef Fn;
   1099   if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
   1100     if (LLVMGetElementType(LLVMTypeOf(Fn)) != Ty)
   1101       return LLVMConstBitCast(Fn, LLVMPointerType(Ty, 0));
   1102     return Fn;
   1103   }
   1104   return LLVMAddFunction(M, String_val(Name), Ty);
   1105 }
   1106 
   1107 /* string -> llmodule -> llvalue option */
   1108 CAMLprim value llvm_lookup_function(value Name, LLVMModuleRef M) {
   1109   CAMLparam1(Name);
   1110   LLVMValueRef Fn;
   1111   if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
   1112     value Option = alloc(1, 0);
   1113     Field(Option, 0) = (value) Fn;
   1114     CAMLreturn(Option);
   1115   }
   1116   CAMLreturn(Val_int(0));
   1117 }
   1118 
   1119 /* string -> lltype -> llmodule -> llvalue */
   1120 CAMLprim LLVMValueRef llvm_define_function(value Name, LLVMTypeRef Ty,
   1121                                            LLVMModuleRef M) {
   1122   LLVMValueRef Fn = LLVMAddFunction(M, String_val(Name), Ty);
   1123   LLVMAppendBasicBlockInContext(LLVMGetTypeContext(Ty), Fn, "entry");
   1124   return Fn;
   1125 }
   1126 
   1127 /* llvalue -> unit */
   1128 CAMLprim value llvm_delete_function(LLVMValueRef Fn) {
   1129   LLVMDeleteFunction(Fn);
   1130   return Val_unit;
   1131 }
   1132 
   1133 /* llvalue -> bool */
   1134 CAMLprim value llvm_is_intrinsic(LLVMValueRef Fn) {
   1135   return Val_bool(LLVMGetIntrinsicID(Fn));
   1136 }
   1137 
   1138 /* llvalue -> int */
   1139 CAMLprim value llvm_function_call_conv(LLVMValueRef Fn) {
   1140   return Val_int(LLVMGetFunctionCallConv(Fn));
   1141 }
   1142 
   1143 /* int -> llvalue -> unit */
   1144 CAMLprim value llvm_set_function_call_conv(value Id, LLVMValueRef Fn) {
   1145   LLVMSetFunctionCallConv(Fn, Int_val(Id));
   1146   return Val_unit;
   1147 }
   1148 
   1149 /* llvalue -> string option */
   1150 CAMLprim value llvm_gc(LLVMValueRef Fn) {
   1151   const char *GC;
   1152   CAMLparam0();
   1153   CAMLlocal2(Name, Option);
   1154 
   1155   if ((GC = LLVMGetGC(Fn))) {
   1156     Name = copy_string(GC);
   1157 
   1158     Option = alloc(1, 0);
   1159     Field(Option, 0) = Name;
   1160     CAMLreturn(Option);
   1161   } else {
   1162     CAMLreturn(Val_int(0));
   1163   }
   1164 }
   1165 
   1166 /* string option -> llvalue -> unit */
   1167 CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) {
   1168   LLVMSetGC(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0)));
   1169   return Val_unit;
   1170 }
   1171 
   1172 /* llvalue -> int32 -> unit */
   1173 CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) {
   1174   LLVMAddFunctionAttr(Arg, Int32_val(PA));
   1175   return Val_unit;
   1176 }
   1177 
   1178 /* llvalue -> string -> string -> unit */
   1179 CAMLprim value llvm_add_target_dependent_function_attr(
   1180                   LLVMValueRef Arg, value A, value V) {
   1181   LLVMAddTargetDependentFunctionAttr(Arg, String_val(A), String_val(V));
   1182   return Val_unit;
   1183 }
   1184 
   1185 /* llvalue -> int32 */
   1186 CAMLprim value llvm_function_attr(LLVMValueRef Fn)
   1187 {
   1188     CAMLparam0();
   1189     CAMLreturn(caml_copy_int32(LLVMGetFunctionAttr(Fn)));
   1190 }
   1191 
   1192 /* llvalue -> int32 -> unit */
   1193 CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) {
   1194   LLVMRemoveFunctionAttr(Arg, Int32_val(PA));
   1195   return Val_unit;
   1196 }
   1197 /*--... Operations on parameters ...........................................--*/
   1198 
   1199 DEFINE_ITERATORS(param, Param, LLVMValueRef, LLVMValueRef, LLVMGetParamParent)
   1200 
   1201 /* llvalue -> int -> llvalue */
   1202 CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) {
   1203   return LLVMGetParam(Fn, Int_val(Index));
   1204 }
   1205 
   1206 /* llvalue -> int */
   1207 CAMLprim value llvm_param_attr(LLVMValueRef Param)
   1208 {
   1209     CAMLparam0();
   1210     CAMLreturn(caml_copy_int32(LLVMGetAttribute(Param)));
   1211 }
   1212 
   1213 /* llvalue -> llvalue */
   1214 CAMLprim value llvm_params(LLVMValueRef Fn) {
   1215   value Params = alloc(LLVMCountParams(Fn), 0);
   1216   LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params));
   1217   return Params;
   1218 }
   1219 
   1220 /* llvalue -> int32 -> unit */
   1221 CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) {
   1222   LLVMAddAttribute(Arg, Int32_val(PA));
   1223   return Val_unit;
   1224 }
   1225 
   1226 /* llvalue -> int32 -> unit */
   1227 CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) {
   1228   LLVMRemoveAttribute(Arg, Int32_val(PA));
   1229   return Val_unit;
   1230 }
   1231 
   1232 /* llvalue -> int -> unit */
   1233 CAMLprim value llvm_set_param_alignment(LLVMValueRef Arg, value align) {
   1234   LLVMSetParamAlignment(Arg, Int_val(align));
   1235   return Val_unit;
   1236 }
   1237 
   1238 /*--... Operations on basic blocks .........................................--*/
   1239 
   1240 DEFINE_ITERATORS(
   1241   block, BasicBlock, LLVMValueRef, LLVMBasicBlockRef, LLVMGetBasicBlockParent)
   1242 
   1243 /* llbasicblock -> llvalue option */
   1244 CAMLprim value llvm_block_terminator(LLVMBasicBlockRef Block)
   1245 {
   1246   CAMLparam0();
   1247   LLVMValueRef Term = LLVMGetBasicBlockTerminator(Block);
   1248   if (Term) {
   1249     value Option = alloc(1, 0);
   1250     Field(Option, 0) = (value) Term;
   1251     CAMLreturn(Option);
   1252   }
   1253   CAMLreturn(Val_int(0));
   1254 }
   1255 
   1256 /* llvalue -> llbasicblock array */
   1257 CAMLprim value llvm_basic_blocks(LLVMValueRef Fn) {
   1258   value MLArray = alloc(LLVMCountBasicBlocks(Fn), 0);
   1259   LLVMGetBasicBlocks(Fn, (LLVMBasicBlockRef *) Op_val(MLArray));
   1260   return MLArray;
   1261 }
   1262 
   1263 /* llbasicblock -> unit */
   1264 CAMLprim value llvm_delete_block(LLVMBasicBlockRef BB) {
   1265   LLVMDeleteBasicBlock(BB);
   1266   return Val_unit;
   1267 }
   1268 
   1269 /* llbasicblock -> unit */
   1270 CAMLprim value llvm_remove_block(LLVMBasicBlockRef BB) {
   1271   LLVMRemoveBasicBlockFromParent(BB);
   1272   return Val_unit;
   1273 }
   1274 
   1275 /* llbasicblock -> llbasicblock -> unit */
   1276 CAMLprim value llvm_move_block_before(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) {
   1277   LLVMMoveBasicBlockBefore(BB, Pos);
   1278   return Val_unit;
   1279 }
   1280 
   1281 /* llbasicblock -> llbasicblock -> unit */
   1282 CAMLprim value llvm_move_block_after(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) {
   1283   LLVMMoveBasicBlockAfter(BB, Pos);
   1284   return Val_unit;
   1285 }
   1286 
   1287 /* string -> llvalue -> llbasicblock */
   1288 CAMLprim LLVMBasicBlockRef llvm_append_block(LLVMContextRef Context, value Name,
   1289                                              LLVMValueRef Fn) {
   1290   return LLVMAppendBasicBlockInContext(Context, Fn, String_val(Name));
   1291 }
   1292 
   1293 /* string -> llbasicblock -> llbasicblock */
   1294 CAMLprim LLVMBasicBlockRef llvm_insert_block(LLVMContextRef Context, value Name,
   1295                                              LLVMBasicBlockRef BB) {
   1296   return LLVMInsertBasicBlockInContext(Context, BB, String_val(Name));
   1297 }
   1298 
   1299 /* llvalue -> bool */
   1300 CAMLprim value llvm_value_is_block(LLVMValueRef Val) {
   1301   return Val_bool(LLVMValueIsBasicBlock(Val));
   1302 }
   1303 
   1304 /*--... Operations on instructions .........................................--*/
   1305 
   1306 DEFINE_ITERATORS(instr, Instruction, LLVMBasicBlockRef, LLVMValueRef,
   1307                  LLVMGetInstructionParent)
   1308 
   1309 /* llvalue -> Opcode.t */
   1310 CAMLprim value llvm_instr_get_opcode(LLVMValueRef Inst) {
   1311   LLVMOpcode o;
   1312   if (!LLVMIsAInstruction(Inst))
   1313       failwith("Not an instruction");
   1314   o = LLVMGetInstructionOpcode(Inst);
   1315   assert (o <= LLVMLandingPad);
   1316   return Val_int(o);
   1317 }
   1318 
   1319 /* llvalue -> ICmp.t option */
   1320 CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) {
   1321   CAMLparam0();
   1322   int x = LLVMGetICmpPredicate(Val);
   1323   if (x) {
   1324     value Option = alloc(1, 0);
   1325     Field(Option, 0) = Val_int(x - LLVMIntEQ);
   1326     CAMLreturn(Option);
   1327   }
   1328   CAMLreturn(Val_int(0));
   1329 }
   1330 
   1331 
   1332 /*--... Operations on call sites ...........................................--*/
   1333 
   1334 /* llvalue -> int */
   1335 CAMLprim value llvm_instruction_call_conv(LLVMValueRef Inst) {
   1336   return Val_int(LLVMGetInstructionCallConv(Inst));
   1337 }
   1338 
   1339 /* int -> llvalue -> unit */
   1340 CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) {
   1341   LLVMSetInstructionCallConv(Inst, Int_val(CC));
   1342   return Val_unit;
   1343 }
   1344 
   1345 /* llvalue -> int -> int32 -> unit */
   1346 CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr,
   1347                                                value index,
   1348                                                value PA) {
   1349   LLVMAddInstrAttribute(Instr, Int_val(index), Int32_val(PA));
   1350   return Val_unit;
   1351 }
   1352 
   1353 /* llvalue -> int -> int32 -> unit */
   1354 CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr,
   1355                                                   value index,
   1356                                                   value PA) {
   1357   LLVMRemoveInstrAttribute(Instr, Int_val(index), Int32_val(PA));
   1358   return Val_unit;
   1359 }
   1360 
   1361 /*--... Operations on call instructions (only) .............................--*/
   1362 
   1363 /* llvalue -> bool */
   1364 CAMLprim value llvm_is_tail_call(LLVMValueRef CallInst) {
   1365   return Val_bool(LLVMIsTailCall(CallInst));
   1366 }
   1367 
   1368 /* bool -> llvalue -> unit */
   1369 CAMLprim value llvm_set_tail_call(value IsTailCall,
   1370                                   LLVMValueRef CallInst) {
   1371   LLVMSetTailCall(CallInst, Bool_val(IsTailCall));
   1372   return Val_unit;
   1373 }
   1374 
   1375 /*--... Operations on load/store instructions (only)........................--*/
   1376 
   1377 /* llvalue -> bool */
   1378 CAMLprim value llvm_is_volatile(LLVMValueRef MemoryInst) {
   1379   return Val_bool(LLVMGetVolatile(MemoryInst));
   1380 }
   1381 
   1382 /* bool -> llvalue -> unit */
   1383 CAMLprim value llvm_set_volatile(value IsVolatile,
   1384                                   LLVMValueRef MemoryInst) {
   1385   LLVMSetVolatile(MemoryInst, Bool_val(IsVolatile));
   1386   return Val_unit;
   1387 }
   1388 
   1389 /*--... Operations on phi nodes ............................................--*/
   1390 
   1391 /* (llvalue * llbasicblock) -> llvalue -> unit */
   1392 CAMLprim value llvm_add_incoming(value Incoming, LLVMValueRef PhiNode) {
   1393   LLVMAddIncoming(PhiNode,
   1394                   (LLVMValueRef*) &Field(Incoming, 0),
   1395                   (LLVMBasicBlockRef*) &Field(Incoming, 1),
   1396                   1);
   1397   return Val_unit;
   1398 }
   1399 
   1400 /* llvalue -> (llvalue * llbasicblock) list */
   1401 CAMLprim value llvm_incoming(LLVMValueRef PhiNode) {
   1402   unsigned I;
   1403   CAMLparam0();
   1404   CAMLlocal3(Hd, Tl, Tmp);
   1405 
   1406   /* Build a tuple list of them. */
   1407   Tl = Val_int(0);
   1408   for (I = LLVMCountIncoming(PhiNode); I != 0; ) {
   1409     Hd = alloc(2, 0);
   1410     Store_field(Hd, 0, (value) LLVMGetIncomingValue(PhiNode, --I));
   1411     Store_field(Hd, 1, (value) LLVMGetIncomingBlock(PhiNode, I));
   1412 
   1413     Tmp = alloc(2, 0);
   1414     Store_field(Tmp, 0, Hd);
   1415     Store_field(Tmp, 1, Tl);
   1416     Tl = Tmp;
   1417   }
   1418 
   1419   CAMLreturn(Tl);
   1420 }
   1421 
   1422 /* llvalue -> unit */
   1423 CAMLprim value llvm_delete_instruction(LLVMValueRef Instruction) {
   1424   LLVMInstructionEraseFromParent(Instruction);
   1425   return Val_unit;
   1426 }
   1427 
   1428 /*===-- Instruction builders ----------------------------------------------===*/
   1429 
   1430 #define Builder_val(v)  (*(LLVMBuilderRef *)(Data_custom_val(v)))
   1431 
   1432 static void llvm_finalize_builder(value B) {
   1433   LLVMDisposeBuilder(Builder_val(B));
   1434 }
   1435 
   1436 static struct custom_operations builder_ops = {
   1437   (char *) "LLVMIRBuilder",
   1438   llvm_finalize_builder,
   1439   custom_compare_default,
   1440   custom_hash_default,
   1441   custom_serialize_default,
   1442   custom_deserialize_default
   1443 #ifdef custom_compare_ext_default
   1444   , custom_compare_ext_default
   1445 #endif
   1446 };
   1447 
   1448 static value alloc_builder(LLVMBuilderRef B) {
   1449   value V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1);
   1450   Builder_val(V) = B;
   1451   return V;
   1452 }
   1453 
   1454 /* llcontext -> llbuilder */
   1455 CAMLprim value llvm_builder(LLVMContextRef C) {
   1456   return alloc_builder(LLVMCreateBuilderInContext(C));
   1457 }
   1458 
   1459 /* (llbasicblock, llvalue) llpos -> llbuilder -> unit */
   1460 CAMLprim value llvm_position_builder(value Pos, value B) {
   1461   if (Tag_val(Pos) == 0) {
   1462     LLVMBasicBlockRef BB = (LLVMBasicBlockRef) Op_val(Field(Pos, 0));
   1463     LLVMPositionBuilderAtEnd(Builder_val(B), BB);
   1464   } else {
   1465     LLVMValueRef I = (LLVMValueRef) Op_val(Field(Pos, 0));
   1466     LLVMPositionBuilderBefore(Builder_val(B), I);
   1467   }
   1468   return Val_unit;
   1469 }
   1470 
   1471 /* llbuilder -> llbasicblock */
   1472 CAMLprim LLVMBasicBlockRef llvm_insertion_block(value B) {
   1473   LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B));
   1474   if (!InsertBlock)
   1475     raise_not_found();
   1476   return InsertBlock;
   1477 }
   1478 
   1479 /* llvalue -> string -> llbuilder -> unit */
   1480 CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name, value B) {
   1481   LLVMInsertIntoBuilderWithName(Builder_val(B), I, String_val(Name));
   1482   return Val_unit;
   1483 }
   1484 
   1485 /*--... Metadata ...........................................................--*/
   1486 
   1487 /* llbuilder -> llvalue -> unit */
   1488 CAMLprim value llvm_set_current_debug_location(value B, LLVMValueRef V) {
   1489   LLVMSetCurrentDebugLocation(Builder_val(B), V);
   1490   return Val_unit;
   1491 }
   1492 
   1493 /* llbuilder -> unit */
   1494 CAMLprim value llvm_clear_current_debug_location(value B) {
   1495   LLVMSetCurrentDebugLocation(Builder_val(B), NULL);
   1496   return Val_unit;
   1497 }
   1498 
   1499 /* llbuilder -> llvalue option */
   1500 CAMLprim value llvm_current_debug_location(value B) {
   1501   CAMLparam0();
   1502   LLVMValueRef L;
   1503   if ((L = LLVMGetCurrentDebugLocation(Builder_val(B)))) {
   1504     value Option = alloc(1, 0);
   1505     Field(Option, 0) = (value) L;
   1506     CAMLreturn(Option);
   1507   }
   1508   CAMLreturn(Val_int(0));
   1509 }
   1510 
   1511 /* llbuilder -> llvalue -> unit */
   1512 CAMLprim value llvm_set_inst_debug_location(value B, LLVMValueRef V) {
   1513   LLVMSetInstDebugLocation(Builder_val(B), V);
   1514   return Val_unit;
   1515 }
   1516 
   1517 
   1518 /*--... Terminators ........................................................--*/
   1519 
   1520 /* llbuilder -> llvalue */
   1521 CAMLprim LLVMValueRef llvm_build_ret_void(value B) {
   1522   return LLVMBuildRetVoid(Builder_val(B));
   1523 }
   1524 
   1525 /* llvalue -> llbuilder -> llvalue */
   1526 CAMLprim LLVMValueRef llvm_build_ret(LLVMValueRef Val, value B) {
   1527   return LLVMBuildRet(Builder_val(B), Val);
   1528 }
   1529 
   1530 /* llvalue array -> llbuilder -> llvalue */
   1531 CAMLprim LLVMValueRef llvm_build_aggregate_ret(value RetVals, value B) {
   1532   return LLVMBuildAggregateRet(Builder_val(B), (LLVMValueRef *) Op_val(RetVals),
   1533                                Wosize_val(RetVals));
   1534 }
   1535 
   1536 /* llbasicblock -> llbuilder -> llvalue */
   1537 CAMLprim LLVMValueRef llvm_build_br(LLVMBasicBlockRef BB, value B) {
   1538   return LLVMBuildBr(Builder_val(B), BB);
   1539 }
   1540 
   1541 /* llvalue -> llbasicblock -> llbasicblock -> llbuilder -> llvalue */
   1542 CAMLprim LLVMValueRef llvm_build_cond_br(LLVMValueRef If,
   1543                                          LLVMBasicBlockRef Then,
   1544                                          LLVMBasicBlockRef Else,
   1545                                          value B) {
   1546   return LLVMBuildCondBr(Builder_val(B), If, Then, Else);
   1547 }
   1548 
   1549 /* llvalue -> llbasicblock -> int -> llbuilder -> llvalue */
   1550 CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of,
   1551                                         LLVMBasicBlockRef Else,
   1552                                         value EstimatedCount,
   1553                                         value B) {
   1554   return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
   1555 }
   1556 
   1557 /* lltype -> string -> llbuilder -> llvalue */
   1558 CAMLprim LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty, value Name,
   1559                                         value B)
   1560 {
   1561   return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name));
   1562 }
   1563 
   1564 /* lltype -> llvalue -> string -> llbuilder -> llvalue */
   1565 CAMLprim LLVMValueRef llvm_build_array_malloc(LLVMTypeRef Ty,
   1566                                               LLVMValueRef Val,
   1567                                               value Name, value B)
   1568 {
   1569   return LLVMBuildArrayMalloc(Builder_val(B), Ty, Val, String_val(Name));
   1570 }
   1571 
   1572 /* llvalue -> llbuilder -> llvalue */
   1573 CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef P, value B)
   1574 {
   1575   return LLVMBuildFree(Builder_val(B), P);
   1576 }
   1577 
   1578 /* llvalue -> llvalue -> llbasicblock -> unit */
   1579 CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
   1580                              LLVMBasicBlockRef Dest) {
   1581   LLVMAddCase(Switch, OnVal, Dest);
   1582   return Val_unit;
   1583 }
   1584 
   1585 /* llvalue -> llbasicblock -> llbuilder -> llvalue */
   1586 CAMLprim LLVMValueRef llvm_build_indirect_br(LLVMValueRef Addr,
   1587                                              value EstimatedDests,
   1588                                              value B) {
   1589   return LLVMBuildIndirectBr(Builder_val(B), Addr, EstimatedDests);
   1590 }
   1591 
   1592 /* llvalue -> llvalue -> llbasicblock -> unit */
   1593 CAMLprim value llvm_add_destination(LLVMValueRef IndirectBr,
   1594                                     LLVMBasicBlockRef Dest) {
   1595   LLVMAddDestination(IndirectBr, Dest);
   1596   return Val_unit;
   1597 }
   1598 
   1599 /* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
   1600    llbuilder -> llvalue */
   1601 CAMLprim LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args,
   1602                                             LLVMBasicBlockRef Then,
   1603                                             LLVMBasicBlockRef Catch,
   1604                                             value Name, value B) {
   1605   return LLVMBuildInvoke(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Args),
   1606                          Wosize_val(Args), Then, Catch, String_val(Name));
   1607 }
   1608 
   1609 /* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
   1610    llbuilder -> llvalue */
   1611 CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) {
   1612   return llvm_build_invoke_nat((LLVMValueRef) Args[0], Args[1],
   1613                                (LLVMBasicBlockRef) Args[2],
   1614                                (LLVMBasicBlockRef) Args[3],
   1615                                Args[4], Args[5]);
   1616 }
   1617 
   1618 /* lltype -> llvalue -> int -> string -> llbuilder -> llvalue */
   1619 CAMLprim LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn,
   1620                                             value NumClauses,  value Name,
   1621                                             value B) {
   1622     return LLVMBuildLandingPad(Builder_val(B), Ty, PersFn, Int_val(NumClauses),
   1623                                String_val(Name));
   1624 }
   1625 
   1626 /* llvalue -> llvalue -> unit */
   1627 CAMLprim value llvm_add_clause(LLVMValueRef LandingPadInst, LLVMValueRef ClauseVal)
   1628 {
   1629     LLVMAddClause(LandingPadInst, ClauseVal);
   1630     return Val_unit;
   1631 }
   1632 
   1633 
   1634 /* llvalue -> bool -> unit */
   1635 CAMLprim value llvm_set_cleanup(LLVMValueRef LandingPadInst, value flag)
   1636 {
   1637     LLVMSetCleanup(LandingPadInst, Bool_val(flag));
   1638     return Val_unit;
   1639 }
   1640 
   1641 /* llvalue -> llbuilder -> llvalue */
   1642 CAMLprim LLVMValueRef llvm_build_resume(LLVMValueRef Exn, value B)
   1643 {
   1644     return LLVMBuildResume(Builder_val(B), Exn);
   1645 }
   1646 
   1647 /* llbuilder -> llvalue */
   1648 CAMLprim LLVMValueRef llvm_build_unreachable(value B) {
   1649   return LLVMBuildUnreachable(Builder_val(B));
   1650 }
   1651 
   1652 /*--... Arithmetic .........................................................--*/
   1653 
   1654 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1655 CAMLprim LLVMValueRef llvm_build_add(LLVMValueRef LHS, LLVMValueRef RHS,
   1656                                      value Name, value B) {
   1657   return LLVMBuildAdd(Builder_val(B), LHS, RHS, String_val(Name));
   1658 }
   1659 
   1660 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1661 CAMLprim LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS,
   1662                                          value Name, value B) {
   1663   return LLVMBuildNSWAdd(Builder_val(B), LHS, RHS, String_val(Name));
   1664 }
   1665 
   1666 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1667 CAMLprim LLVMValueRef llvm_build_nuw_add(LLVMValueRef LHS, LLVMValueRef RHS,
   1668                                          value Name, value B) {
   1669   return LLVMBuildNUWAdd(Builder_val(B), LHS, RHS, String_val(Name));
   1670 }
   1671 
   1672 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1673 CAMLprim LLVMValueRef llvm_build_fadd(LLVMValueRef LHS, LLVMValueRef RHS,
   1674                                       value Name, value B) {
   1675   return LLVMBuildFAdd(Builder_val(B), LHS, RHS, String_val(Name));
   1676 }
   1677 
   1678 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1679 CAMLprim LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS,
   1680                                      value Name, value B) {
   1681   return LLVMBuildSub(Builder_val(B), LHS, RHS, String_val(Name));
   1682 }
   1683 
   1684 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1685 CAMLprim LLVMValueRef llvm_build_nsw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
   1686                                          value Name, value B) {
   1687   return LLVMBuildNSWSub(Builder_val(B), LHS, RHS, String_val(Name));
   1688 }
   1689 
   1690 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1691 CAMLprim LLVMValueRef llvm_build_nuw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
   1692                                          value Name, value B) {
   1693   return LLVMBuildNUWSub(Builder_val(B), LHS, RHS, String_val(Name));
   1694 }
   1695 
   1696 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1697 CAMLprim LLVMValueRef llvm_build_fsub(LLVMValueRef LHS, LLVMValueRef RHS,
   1698                                       value Name, value B) {
   1699   return LLVMBuildFSub(Builder_val(B), LHS, RHS, String_val(Name));
   1700 }
   1701 
   1702 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1703 CAMLprim LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS,
   1704                                      value Name, value B) {
   1705   return LLVMBuildMul(Builder_val(B), LHS, RHS, String_val(Name));
   1706 }
   1707 
   1708 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1709 CAMLprim LLVMValueRef llvm_build_nsw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
   1710                                          value Name, value B) {
   1711   return LLVMBuildNSWMul(Builder_val(B), LHS, RHS, String_val(Name));
   1712 }
   1713 
   1714 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1715 CAMLprim LLVMValueRef llvm_build_nuw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
   1716                                          value Name, value B) {
   1717   return LLVMBuildNUWMul(Builder_val(B), LHS, RHS, String_val(Name));
   1718 }
   1719 
   1720 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1721 CAMLprim LLVMValueRef llvm_build_fmul(LLVMValueRef LHS, LLVMValueRef RHS,
   1722                                       value Name, value B) {
   1723   return LLVMBuildFMul(Builder_val(B), LHS, RHS, String_val(Name));
   1724 }
   1725 
   1726 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1727 CAMLprim LLVMValueRef llvm_build_udiv(LLVMValueRef LHS, LLVMValueRef RHS,
   1728                                       value Name, value B) {
   1729   return LLVMBuildUDiv(Builder_val(B), LHS, RHS, String_val(Name));
   1730 }
   1731 
   1732 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1733 CAMLprim LLVMValueRef llvm_build_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
   1734                                       value Name, value B) {
   1735   return LLVMBuildSDiv(Builder_val(B), LHS, RHS, String_val(Name));
   1736 }
   1737 
   1738 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1739 CAMLprim LLVMValueRef llvm_build_exact_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
   1740                                             value Name, value B) {
   1741   return LLVMBuildExactSDiv(Builder_val(B), LHS, RHS, String_val(Name));
   1742 }
   1743 
   1744 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1745 CAMLprim LLVMValueRef llvm_build_fdiv(LLVMValueRef LHS, LLVMValueRef RHS,
   1746                                       value Name, value B) {
   1747   return LLVMBuildFDiv(Builder_val(B), LHS, RHS, String_val(Name));
   1748 }
   1749 
   1750 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1751 CAMLprim LLVMValueRef llvm_build_urem(LLVMValueRef LHS, LLVMValueRef RHS,
   1752                                       value Name, value B) {
   1753   return LLVMBuildURem(Builder_val(B), LHS, RHS, String_val(Name));
   1754 }
   1755 
   1756 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1757 CAMLprim LLVMValueRef llvm_build_srem(LLVMValueRef LHS, LLVMValueRef RHS,
   1758                                       value Name, value B) {
   1759   return LLVMBuildSRem(Builder_val(B), LHS, RHS, String_val(Name));
   1760 }
   1761 
   1762 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1763 CAMLprim LLVMValueRef llvm_build_frem(LLVMValueRef LHS, LLVMValueRef RHS,
   1764                                       value Name, value B) {
   1765   return LLVMBuildFRem(Builder_val(B), LHS, RHS, String_val(Name));
   1766 }
   1767 
   1768 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1769 CAMLprim LLVMValueRef llvm_build_shl(LLVMValueRef LHS, LLVMValueRef RHS,
   1770                                      value Name, value B) {
   1771   return LLVMBuildShl(Builder_val(B), LHS, RHS, String_val(Name));
   1772 }
   1773 
   1774 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1775 CAMLprim LLVMValueRef llvm_build_lshr(LLVMValueRef LHS, LLVMValueRef RHS,
   1776                                       value Name, value B) {
   1777   return LLVMBuildLShr(Builder_val(B), LHS, RHS, String_val(Name));
   1778 }
   1779 
   1780 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1781 CAMLprim LLVMValueRef llvm_build_ashr(LLVMValueRef LHS, LLVMValueRef RHS,
   1782                                       value Name, value B) {
   1783   return LLVMBuildAShr(Builder_val(B), LHS, RHS, String_val(Name));
   1784 }
   1785 
   1786 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1787 CAMLprim LLVMValueRef llvm_build_and(LLVMValueRef LHS, LLVMValueRef RHS,
   1788                                      value Name, value B) {
   1789   return LLVMBuildAnd(Builder_val(B), LHS, RHS, String_val(Name));
   1790 }
   1791 
   1792 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1793 CAMLprim LLVMValueRef llvm_build_or(LLVMValueRef LHS, LLVMValueRef RHS,
   1794                                     value Name, value B) {
   1795   return LLVMBuildOr(Builder_val(B), LHS, RHS, String_val(Name));
   1796 }
   1797 
   1798 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   1799 CAMLprim LLVMValueRef llvm_build_xor(LLVMValueRef LHS, LLVMValueRef RHS,
   1800                                      value Name, value B) {
   1801   return LLVMBuildXor(Builder_val(B), LHS, RHS, String_val(Name));
   1802 }
   1803 
   1804 /* llvalue -> string -> llbuilder -> llvalue */
   1805 CAMLprim LLVMValueRef llvm_build_neg(LLVMValueRef X,
   1806                                      value Name, value B) {
   1807   return LLVMBuildNeg(Builder_val(B), X, String_val(Name));
   1808 }
   1809 
   1810 /* llvalue -> string -> llbuilder -> llvalue */
   1811 CAMLprim LLVMValueRef llvm_build_nsw_neg(LLVMValueRef X,
   1812                                          value Name, value B) {
   1813   return LLVMBuildNSWNeg(Builder_val(B), X, String_val(Name));
   1814 }
   1815 
   1816 /* llvalue -> string -> llbuilder -> llvalue */
   1817 CAMLprim LLVMValueRef llvm_build_nuw_neg(LLVMValueRef X,
   1818                                          value Name, value B) {
   1819   return LLVMBuildNUWNeg(Builder_val(B), X, String_val(Name));
   1820 }
   1821 
   1822 /* llvalue -> string -> llbuilder -> llvalue */
   1823 CAMLprim LLVMValueRef llvm_build_fneg(LLVMValueRef X,
   1824                                      value Name, value B) {
   1825   return LLVMBuildFNeg(Builder_val(B), X, String_val(Name));
   1826 }
   1827 
   1828 /* llvalue -> string -> llbuilder -> llvalue */
   1829 CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X,
   1830                                      value Name, value B) {
   1831   return LLVMBuildNot(Builder_val(B), X, String_val(Name));
   1832 }
   1833 
   1834 /*--... Memory .............................................................--*/
   1835 
   1836 /* lltype -> string -> llbuilder -> llvalue */
   1837 CAMLprim LLVMValueRef llvm_build_alloca(LLVMTypeRef Ty,
   1838                                         value Name, value B) {
   1839   return LLVMBuildAlloca(Builder_val(B), Ty, String_val(Name));
   1840 }
   1841 
   1842 /* lltype -> llvalue -> string -> llbuilder -> llvalue */
   1843 CAMLprim LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size,
   1844                                               value Name, value B) {
   1845   return LLVMBuildArrayAlloca(Builder_val(B), Ty, Size, String_val(Name));
   1846 }
   1847 
   1848 /* llvalue -> string -> llbuilder -> llvalue */
   1849 CAMLprim LLVMValueRef llvm_build_load(LLVMValueRef Pointer,
   1850                                       value Name, value B) {
   1851   return LLVMBuildLoad(Builder_val(B), Pointer, String_val(Name));
   1852 }
   1853 
   1854 /* llvalue -> llvalue -> llbuilder -> llvalue */
   1855 CAMLprim LLVMValueRef llvm_build_store(LLVMValueRef Value, LLVMValueRef Pointer,
   1856                                        value B) {
   1857   return LLVMBuildStore(Builder_val(B), Value, Pointer);
   1858 }
   1859 
   1860 /* AtomicRMWBinOp.t -> llvalue -> llvalue -> AtomicOrdering.t ->
   1861    bool -> llbuilder -> llvalue */
   1862 CAMLprim LLVMValueRef llvm_build_atomicrmw_native(value BinOp, LLVMValueRef Ptr,
   1863                                                   LLVMValueRef Val, value Ord,
   1864                                                   value ST, value Name, value B) {
   1865   LLVMValueRef Instr;
   1866   Instr = LLVMBuildAtomicRMW(Builder_val(B), Int_val(BinOp),
   1867                              Ptr, Val, Int_val(Ord), Bool_val(ST));
   1868   LLVMSetValueName(Instr, String_val(Name));
   1869   return Instr;
   1870 }
   1871 
   1872 CAMLprim LLVMValueRef llvm_build_atomicrmw_bytecode(value *argv, int argn) {
   1873   return llvm_build_atomicrmw_native(argv[0], (LLVMValueRef) argv[1],
   1874                                      (LLVMValueRef) argv[2], argv[3],
   1875                                      argv[4], argv[5], argv[6]);
   1876 }
   1877 
   1878 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
   1879 CAMLprim LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices,
   1880                                      value Name, value B) {
   1881   return LLVMBuildGEP(Builder_val(B), Pointer,
   1882                       (LLVMValueRef *) Op_val(Indices), Wosize_val(Indices),
   1883                       String_val(Name));
   1884 }
   1885 
   1886 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
   1887 CAMLprim LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer,
   1888                                                value Indices, value Name,
   1889                                                value B) {
   1890   return LLVMBuildInBoundsGEP(Builder_val(B), Pointer,
   1891                               (LLVMValueRef *) Op_val(Indices),
   1892                               Wosize_val(Indices), String_val(Name));
   1893 }
   1894 
   1895 /* llvalue -> int -> string -> llbuilder -> llvalue */
   1896 CAMLprim LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer,
   1897                                                value Index, value Name,
   1898                                                value B) {
   1899   return LLVMBuildStructGEP(Builder_val(B), Pointer,
   1900                               Int_val(Index), String_val(Name));
   1901 }
   1902 
   1903 /* string -> string -> llbuilder -> llvalue */
   1904 CAMLprim LLVMValueRef llvm_build_global_string(value Str, value Name, value B) {
   1905   return LLVMBuildGlobalString(Builder_val(B), String_val(Str),
   1906                                String_val(Name));
   1907 }
   1908 
   1909 /* string -> string -> llbuilder -> llvalue */
   1910 CAMLprim LLVMValueRef llvm_build_global_stringptr(value Str, value Name,
   1911                                                   value B) {
   1912   return LLVMBuildGlobalStringPtr(Builder_val(B), String_val(Str),
   1913                                   String_val(Name));
   1914 }
   1915 
   1916 /*--... Casts ..............................................................--*/
   1917 
   1918 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1919 CAMLprim LLVMValueRef llvm_build_trunc(LLVMValueRef X, LLVMTypeRef Ty,
   1920                                        value Name, value B) {
   1921   return LLVMBuildTrunc(Builder_val(B), X, Ty, String_val(Name));
   1922 }
   1923 
   1924 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1925 CAMLprim LLVMValueRef llvm_build_zext(LLVMValueRef X, LLVMTypeRef Ty,
   1926                                       value Name, value B) {
   1927   return LLVMBuildZExt(Builder_val(B), X, Ty, String_val(Name));
   1928 }
   1929 
   1930 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1931 CAMLprim LLVMValueRef llvm_build_sext(LLVMValueRef X, LLVMTypeRef Ty,
   1932                                       value Name, value B) {
   1933   return LLVMBuildSExt(Builder_val(B), X, Ty, String_val(Name));
   1934 }
   1935 
   1936 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1937 CAMLprim LLVMValueRef llvm_build_fptoui(LLVMValueRef X, LLVMTypeRef Ty,
   1938                                         value Name, value B) {
   1939   return LLVMBuildFPToUI(Builder_val(B), X, Ty, String_val(Name));
   1940 }
   1941 
   1942 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1943 CAMLprim LLVMValueRef llvm_build_fptosi(LLVMValueRef X, LLVMTypeRef Ty,
   1944                                         value Name, value B) {
   1945   return LLVMBuildFPToSI(Builder_val(B), X, Ty, String_val(Name));
   1946 }
   1947 
   1948 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1949 CAMLprim LLVMValueRef llvm_build_uitofp(LLVMValueRef X, LLVMTypeRef Ty,
   1950                                         value Name, value B) {
   1951   return LLVMBuildUIToFP(Builder_val(B), X, Ty, String_val(Name));
   1952 }
   1953 
   1954 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1955 CAMLprim LLVMValueRef llvm_build_sitofp(LLVMValueRef X, LLVMTypeRef Ty,
   1956                                         value Name, value B) {
   1957   return LLVMBuildSIToFP(Builder_val(B), X, Ty, String_val(Name));
   1958 }
   1959 
   1960 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1961 CAMLprim LLVMValueRef llvm_build_fptrunc(LLVMValueRef X, LLVMTypeRef Ty,
   1962                                          value Name, value B) {
   1963   return LLVMBuildFPTrunc(Builder_val(B), X, Ty, String_val(Name));
   1964 }
   1965 
   1966 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1967 CAMLprim LLVMValueRef llvm_build_fpext(LLVMValueRef X, LLVMTypeRef Ty,
   1968                                        value Name, value B) {
   1969   return LLVMBuildFPExt(Builder_val(B), X, Ty, String_val(Name));
   1970 }
   1971 
   1972 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1973 CAMLprim LLVMValueRef llvm_build_prttoint(LLVMValueRef X, LLVMTypeRef Ty,
   1974                                           value Name, value B) {
   1975   return LLVMBuildPtrToInt(Builder_val(B), X, Ty, String_val(Name));
   1976 }
   1977 
   1978 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1979 CAMLprim LLVMValueRef llvm_build_inttoptr(LLVMValueRef X, LLVMTypeRef Ty,
   1980                                           value Name, value B) {
   1981   return LLVMBuildIntToPtr(Builder_val(B), X, Ty, String_val(Name));
   1982 }
   1983 
   1984 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1985 CAMLprim LLVMValueRef llvm_build_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
   1986                                          value Name, value B) {
   1987   return LLVMBuildBitCast(Builder_val(B), X, Ty, String_val(Name));
   1988 }
   1989 
   1990 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1991 CAMLprim LLVMValueRef llvm_build_zext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
   1992                                                  value Name, value B) {
   1993   return LLVMBuildZExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
   1994 }
   1995 
   1996 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   1997 CAMLprim LLVMValueRef llvm_build_sext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
   1998                                                  value Name, value B) {
   1999   return LLVMBuildSExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
   2000 }
   2001 
   2002 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   2003 CAMLprim LLVMValueRef llvm_build_trunc_or_bitcast(LLVMValueRef X,
   2004                                                   LLVMTypeRef Ty, value Name,
   2005                                                   value B) {
   2006   return LLVMBuildTruncOrBitCast(Builder_val(B), X, Ty, String_val(Name));
   2007 }
   2008 
   2009 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   2010 CAMLprim LLVMValueRef llvm_build_pointercast(LLVMValueRef X, LLVMTypeRef Ty,
   2011                                              value Name, value B) {
   2012   return LLVMBuildPointerCast(Builder_val(B), X, Ty, String_val(Name));
   2013 }
   2014 
   2015 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   2016 CAMLprim LLVMValueRef llvm_build_intcast(LLVMValueRef X, LLVMTypeRef Ty,
   2017                                          value Name, value B) {
   2018   return LLVMBuildIntCast(Builder_val(B), X, Ty, String_val(Name));
   2019 }
   2020 
   2021 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   2022 CAMLprim LLVMValueRef llvm_build_fpcast(LLVMValueRef X, LLVMTypeRef Ty,
   2023                                         value Name, value B) {
   2024   return LLVMBuildFPCast(Builder_val(B), X, Ty, String_val(Name));
   2025 }
   2026 
   2027 /*--... Comparisons ........................................................--*/
   2028 
   2029 /* Icmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
   2030 CAMLprim LLVMValueRef llvm_build_icmp(value Pred,
   2031                                       LLVMValueRef LHS, LLVMValueRef RHS,
   2032                                       value Name, value B) {
   2033   return LLVMBuildICmp(Builder_val(B), Int_val(Pred) + LLVMIntEQ, LHS, RHS,
   2034                        String_val(Name));
   2035 }
   2036 
   2037 /* Fcmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
   2038 CAMLprim LLVMValueRef llvm_build_fcmp(value Pred,
   2039                                       LLVMValueRef LHS, LLVMValueRef RHS,
   2040                                       value Name, value B) {
   2041   return LLVMBuildFCmp(Builder_val(B), Int_val(Pred), LHS, RHS,
   2042                        String_val(Name));
   2043 }
   2044 
   2045 /*--... Miscellaneous instructions .........................................--*/
   2046 
   2047 /* (llvalue * llbasicblock) list -> string -> llbuilder -> llvalue */
   2048 CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) {
   2049   value Hd, Tl;
   2050   LLVMValueRef FirstValue, PhiNode;
   2051 
   2052   assert(Incoming != Val_int(0) && "Empty list passed to Llvm.build_phi!");
   2053 
   2054   Hd = Field(Incoming, 0);
   2055   FirstValue = (LLVMValueRef) Field(Hd, 0);
   2056   PhiNode = LLVMBuildPhi(Builder_val(B), LLVMTypeOf(FirstValue),
   2057                          String_val(Name));
   2058 
   2059   for (Tl = Incoming; Tl != Val_int(0); Tl = Field(Tl, 1)) {
   2060     value Hd = Field(Tl, 0);
   2061     LLVMAddIncoming(PhiNode, (LLVMValueRef*) &Field(Hd, 0),
   2062                     (LLVMBasicBlockRef*) &Field(Hd, 1), 1);
   2063   }
   2064 
   2065   return PhiNode;
   2066 }
   2067 
   2068 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
   2069 CAMLprim LLVMValueRef llvm_build_call(LLVMValueRef Fn, value Params,
   2070                                       value Name, value B) {
   2071   return LLVMBuildCall(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Params),
   2072                        Wosize_val(Params), String_val(Name));
   2073 }
   2074 
   2075 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
   2076 CAMLprim LLVMValueRef llvm_build_select(LLVMValueRef If,
   2077                                         LLVMValueRef Then, LLVMValueRef Else,
   2078                                         value Name, value B) {
   2079   return LLVMBuildSelect(Builder_val(B), If, Then, Else, String_val(Name));
   2080 }
   2081 
   2082 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
   2083 CAMLprim LLVMValueRef llvm_build_va_arg(LLVMValueRef List, LLVMTypeRef Ty,
   2084                                         value Name, value B) {
   2085   return LLVMBuildVAArg(Builder_val(B), List, Ty, String_val(Name));
   2086 }
   2087 
   2088 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   2089 CAMLprim LLVMValueRef llvm_build_extractelement(LLVMValueRef Vec,
   2090                                                 LLVMValueRef Idx,
   2091                                                 value Name, value B) {
   2092   return LLVMBuildExtractElement(Builder_val(B), Vec, Idx, String_val(Name));
   2093 }
   2094 
   2095 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
   2096 CAMLprim LLVMValueRef llvm_build_insertelement(LLVMValueRef Vec,
   2097                                                LLVMValueRef Element,
   2098                                                LLVMValueRef Idx,
   2099                                                value Name, value B) {
   2100   return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx,
   2101                                 String_val(Name));
   2102 }
   2103 
   2104 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
   2105 CAMLprim LLVMValueRef llvm_build_shufflevector(LLVMValueRef V1, LLVMValueRef V2,
   2106                                                LLVMValueRef Mask,
   2107                                                value Name, value B) {
   2108   return LLVMBuildShuffleVector(Builder_val(B), V1, V2, Mask, String_val(Name));
   2109 }
   2110 
   2111 /* llvalue -> int -> string -> llbuilder -> llvalue */
   2112 CAMLprim LLVMValueRef llvm_build_extractvalue(LLVMValueRef Aggregate,
   2113                                               value Idx, value Name, value B) {
   2114   return LLVMBuildExtractValue(Builder_val(B), Aggregate, Int_val(Idx),
   2115                                String_val(Name));
   2116 }
   2117 
   2118 /* llvalue -> llvalue -> int -> string -> llbuilder -> llvalue */
   2119 CAMLprim LLVMValueRef llvm_build_insertvalue(LLVMValueRef Aggregate,
   2120                                              LLVMValueRef Val, value Idx,
   2121                                              value Name, value B) {
   2122   return LLVMBuildInsertValue(Builder_val(B), Aggregate, Val, Int_val(Idx),
   2123                               String_val(Name));
   2124 }
   2125 
   2126 /* llvalue -> string -> llbuilder -> llvalue */
   2127 CAMLprim LLVMValueRef llvm_build_is_null(LLVMValueRef Val, value Name,
   2128                                          value B) {
   2129   return LLVMBuildIsNull(Builder_val(B), Val, String_val(Name));
   2130 }
   2131 
   2132 /* llvalue -> string -> llbuilder -> llvalue */
   2133 CAMLprim LLVMValueRef llvm_build_is_not_null(LLVMValueRef Val, value Name,
   2134                                              value B) {
   2135   return LLVMBuildIsNotNull(Builder_val(B), Val, String_val(Name));
   2136 }
   2137 
   2138 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
   2139 CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS,
   2140                                          value Name, value B) {
   2141   return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name));
   2142 }
   2143 
   2144 /*===-- Memory buffers ----------------------------------------------------===*/
   2145 
   2146 /* string -> llmemorybuffer
   2147    raises IoError msg on error */
   2148 CAMLprim value llvm_memorybuffer_of_file(value Path) {
   2149   CAMLparam1(Path);
   2150   char *Message;
   2151   LLVMMemoryBufferRef MemBuf;
   2152 
   2153   if (LLVMCreateMemoryBufferWithContentsOfFile(String_val(Path),
   2154                                                &MemBuf, &Message))
   2155     llvm_raise(llvm_ioerror_exn, Message);
   2156 
   2157   CAMLreturn((value) MemBuf);
   2158 }
   2159 
   2160 /* unit -> llmemorybuffer
   2161    raises IoError msg on error */
   2162 CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) {
   2163   char *Message;
   2164   LLVMMemoryBufferRef MemBuf;
   2165 
   2166   if (LLVMCreateMemoryBufferWithSTDIN(&MemBuf, &Message))
   2167     llvm_raise(llvm_ioerror_exn, Message);
   2168 
   2169   return MemBuf;
   2170 }
   2171 
   2172 /* ?name:string -> string -> llmemorybuffer */
   2173 CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_string(value Name, value String) {
   2174   const char *NameCStr;
   2175   if(Name == Val_int(0))
   2176     NameCStr = "";
   2177   else
   2178     NameCStr = String_val(Field(Name, 0));
   2179 
   2180   LLVMMemoryBufferRef MemBuf;
   2181   MemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(
   2182                 String_val(String), caml_string_length(String), NameCStr);
   2183 
   2184   return MemBuf;
   2185 }
   2186 
   2187 /* llmemorybuffer -> string */
   2188 CAMLprim value llvm_memorybuffer_as_string(LLVMMemoryBufferRef MemBuf) {
   2189   value String = caml_alloc_string(LLVMGetBufferSize(MemBuf));
   2190   memcpy(String_val(String), LLVMGetBufferStart(MemBuf),
   2191          LLVMGetBufferSize(MemBuf));
   2192 
   2193   return String;
   2194 }
   2195 
   2196 /* llmemorybuffer -> unit */
   2197 CAMLprim value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) {
   2198   LLVMDisposeMemoryBuffer(MemBuf);
   2199   return Val_unit;
   2200 }
   2201 
   2202 /*===-- Pass Managers -----------------------------------------------------===*/
   2203 
   2204 /* unit -> [ `Module ] PassManager.t */
   2205 CAMLprim LLVMPassManagerRef llvm_passmanager_create(value Unit) {
   2206   return LLVMCreatePassManager();
   2207 }
   2208 
   2209 /* llmodule -> [ `Function ] PassManager.t -> bool */
   2210 CAMLprim value llvm_passmanager_run_module(LLVMModuleRef M,
   2211                                            LLVMPassManagerRef PM) {
   2212   return Val_bool(LLVMRunPassManager(PM, M));
   2213 }
   2214 
   2215 /* [ `Function ] PassManager.t -> bool */
   2216 CAMLprim value llvm_passmanager_initialize(LLVMPassManagerRef FPM) {
   2217   return Val_bool(LLVMInitializeFunctionPassManager(FPM));
   2218 }
   2219 
   2220 /* llvalue -> [ `Function ] PassManager.t -> bool */
   2221 CAMLprim value llvm_passmanager_run_function(LLVMValueRef F,
   2222                                              LLVMPassManagerRef FPM) {
   2223   return Val_bool(LLVMRunFunctionPassManager(FPM, F));
   2224 }
   2225 
   2226 /* [ `Function ] PassManager.t -> bool */
   2227 CAMLprim value llvm_passmanager_finalize(LLVMPassManagerRef FPM) {
   2228   return Val_bool(LLVMFinalizeFunctionPassManager(FPM));
   2229 }
   2230 
   2231 /* PassManager.any PassManager.t -> unit */
   2232 CAMLprim value llvm_passmanager_dispose(LLVMPassManagerRef PM) {
   2233   LLVMDisposePassManager(PM);
   2234   return Val_unit;
   2235 }
   2236