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