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