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