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