llvm_ocaml.c revision c3c3be582de556f2a199f9154ec48f00be8eb077
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 "llvm/Config/config.h"
25#include <assert.h>
26#include <stdlib.h>
27
28
29/* Can't use the recommended caml_named_value mechanism for backwards
30   compatibility reasons. This is largely equivalent. */
31static value llvm_ioerror_exn;
32
33CAMLprim 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
39static 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
53static 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 */
98CAMLprim LLVMContextRef llvm_create_context(value Unit) {
99  return LLVMContextCreate();
100}
101
102/* llcontext -> unit */
103CAMLprim value llvm_dispose_context(LLVMContextRef C) {
104  LLVMContextDispose(C);
105  return Val_unit;
106}
107
108/* unit -> llcontext */
109CAMLprim LLVMContextRef llvm_global_context(value Unit) {
110  return LLVMGetGlobalContext();
111}
112
113/*===-- Modules -----------------------------------------------------------===*/
114
115/* llcontext -> string -> llmodule */
116CAMLprim LLVMModuleRef llvm_create_module(LLVMContextRef C, value ModuleID) {
117  return LLVMModuleCreateWithNameInContext(String_val(ModuleID), C);
118}
119
120/* llmodule -> unit */
121CAMLprim value llvm_dispose_module(LLVMModuleRef M) {
122  LLVMDisposeModule(M);
123  return Val_unit;
124}
125
126/* llmodule -> string */
127CAMLprim value llvm_target_triple(LLVMModuleRef M) {
128  return copy_string(LLVMGetTarget(M));
129}
130
131/* string -> llmodule -> unit */
132CAMLprim value llvm_set_target_triple(value Trip, LLVMModuleRef M) {
133  LLVMSetTarget(M, String_val(Trip));
134  return Val_unit;
135}
136
137/* llmodule -> string */
138CAMLprim value llvm_data_layout(LLVMModuleRef M) {
139  return copy_string(LLVMGetDataLayout(M));
140}
141
142/* string -> llmodule -> unit */
143CAMLprim value llvm_set_data_layout(value Layout, LLVMModuleRef M) {
144  LLVMSetDataLayout(M, String_val(Layout));
145  return Val_unit;
146}
147
148/* string -> lltype -> llmodule -> bool */
149CAMLprim value llvm_add_type_name(value Name, LLVMTypeRef Ty, LLVMModuleRef M) {
150  int res = LLVMAddTypeName(M, String_val(Name), Ty);
151  return Val_bool(res == 0);
152}
153
154/* string -> llmodule -> unit */
155CAMLprim value llvm_delete_type_name(value Name, LLVMModuleRef M) {
156  LLVMDeleteTypeName(M, String_val(Name));
157  return Val_unit;
158}
159
160/* llmodule -> unit */
161CAMLprim value llvm_dump_module(LLVMModuleRef M) {
162  LLVMDumpModule(M);
163  return Val_unit;
164}
165
166
167/*===-- Types -------------------------------------------------------------===*/
168
169/* lltype -> TypeKind.t */
170CAMLprim value llvm_classify_type(LLVMTypeRef Ty) {
171  return Val_int(LLVMGetTypeKind(Ty));
172}
173
174/* lltype -> llcontext */
175CAMLprim LLVMContextRef llvm_type_context(LLVMTypeRef Ty) {
176  return LLVMGetTypeContext(Ty);
177}
178
179/*--... Operations on integer types ........................................--*/
180
181/* llcontext -> lltype */
182CAMLprim LLVMTypeRef llvm_i1_type (LLVMContextRef Context) {
183  return LLVMInt1TypeInContext(Context);
184}
185
186/* llcontext -> lltype */
187CAMLprim LLVMTypeRef llvm_i8_type (LLVMContextRef Context) {
188  return LLVMInt8TypeInContext(Context);
189}
190
191/* llcontext -> lltype */
192CAMLprim LLVMTypeRef llvm_i16_type (LLVMContextRef Context) {
193  return LLVMInt16TypeInContext(Context);
194}
195
196/* llcontext -> lltype */
197CAMLprim LLVMTypeRef llvm_i32_type (LLVMContextRef Context) {
198  return LLVMInt32TypeInContext(Context);
199}
200
201/* llcontext -> lltype */
202CAMLprim LLVMTypeRef llvm_i64_type (LLVMContextRef Context) {
203  return LLVMInt64TypeInContext(Context);
204}
205
206/* llcontext -> int -> lltype */
207CAMLprim LLVMTypeRef llvm_integer_type(LLVMContextRef Context, value Width) {
208  return LLVMIntTypeInContext(Context, Int_val(Width));
209}
210
211/* lltype -> int */
212CAMLprim value llvm_integer_bitwidth(LLVMTypeRef IntegerTy) {
213  return Val_int(LLVMGetIntTypeWidth(IntegerTy));
214}
215
216/*--... Operations on real types ...........................................--*/
217
218/* llcontext -> lltype */
219CAMLprim LLVMTypeRef llvm_float_type(LLVMContextRef Context) {
220  return LLVMFloatTypeInContext(Context);
221}
222
223/* llcontext -> lltype */
224CAMLprim LLVMTypeRef llvm_double_type(LLVMContextRef Context) {
225  return LLVMDoubleTypeInContext(Context);
226}
227
228/* llcontext -> lltype */
229CAMLprim LLVMTypeRef llvm_x86fp80_type(LLVMContextRef Context) {
230  return LLVMX86FP80TypeInContext(Context);
231}
232
233/* llcontext -> lltype */
234CAMLprim LLVMTypeRef llvm_fp128_type(LLVMContextRef Context) {
235  return LLVMFP128TypeInContext(Context);
236}
237
238/* llcontext -> lltype */
239CAMLprim LLVMTypeRef llvm_ppc_fp128_type(LLVMContextRef Context) {
240  return LLVMPPCFP128TypeInContext(Context);
241}
242
243/*--... Operations on function types .......................................--*/
244
245/* lltype -> lltype array -> lltype */
246CAMLprim LLVMTypeRef llvm_function_type(LLVMTypeRef RetTy, value ParamTys) {
247  return LLVMFunctionType(RetTy, (LLVMTypeRef *) ParamTys,
248                          Wosize_val(ParamTys), 0);
249}
250
251/* lltype -> lltype array -> lltype */
252CAMLprim LLVMTypeRef llvm_var_arg_function_type(LLVMTypeRef RetTy,
253                                                value ParamTys) {
254  return LLVMFunctionType(RetTy, (LLVMTypeRef *) ParamTys,
255                          Wosize_val(ParamTys), 1);
256}
257
258/* lltype -> bool */
259CAMLprim value llvm_is_var_arg(LLVMTypeRef FunTy) {
260  return Val_bool(LLVMIsFunctionVarArg(FunTy));
261}
262
263/* lltype -> lltype array */
264CAMLprim value llvm_param_types(LLVMTypeRef FunTy) {
265  value Tys = alloc(LLVMCountParamTypes(FunTy), 0);
266  LLVMGetParamTypes(FunTy, (LLVMTypeRef *) Tys);
267  return Tys;
268}
269
270/*--... Operations on struct types .........................................--*/
271
272/* llcontext -> lltype array -> lltype */
273CAMLprim LLVMTypeRef llvm_struct_type(LLVMContextRef C, value ElementTypes) {
274  return LLVMStructTypeInContext(C, (LLVMTypeRef *) ElementTypes,
275                                 Wosize_val(ElementTypes), 0);
276}
277
278/* llcontext -> lltype array -> lltype */
279CAMLprim LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C,
280                                             value ElementTypes) {
281  return LLVMStructTypeInContext(C, (LLVMTypeRef *) ElementTypes,
282                                 Wosize_val(ElementTypes), 1);
283}
284
285/* lltype -> lltype array */
286CAMLprim value llvm_element_types(LLVMTypeRef StructTy) {
287  value Tys = alloc(LLVMCountStructElementTypes(StructTy), 0);
288  LLVMGetStructElementTypes(StructTy, (LLVMTypeRef *) Tys);
289  return Tys;
290}
291
292/* lltype -> bool */
293CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) {
294  return Val_bool(LLVMIsPackedStruct(StructTy));
295}
296
297/*--... Operations on array, pointer, and vector types .....................--*/
298
299/* lltype -> int -> lltype */
300CAMLprim LLVMTypeRef llvm_array_type(LLVMTypeRef ElementTy, value Count) {
301  return LLVMArrayType(ElementTy, Int_val(Count));
302}
303
304/* lltype -> lltype */
305CAMLprim LLVMTypeRef llvm_pointer_type(LLVMTypeRef ElementTy) {
306  return LLVMPointerType(ElementTy, 0);
307}
308
309/* lltype -> int -> lltype */
310CAMLprim LLVMTypeRef llvm_qualified_pointer_type(LLVMTypeRef ElementTy,
311                                                 value AddressSpace) {
312  return LLVMPointerType(ElementTy, Int_val(AddressSpace));
313}
314
315/* lltype -> int -> lltype */
316CAMLprim LLVMTypeRef llvm_vector_type(LLVMTypeRef ElementTy, value Count) {
317  return LLVMVectorType(ElementTy, Int_val(Count));
318}
319
320/* lltype -> int */
321CAMLprim value llvm_array_length(LLVMTypeRef ArrayTy) {
322  return Val_int(LLVMGetArrayLength(ArrayTy));
323}
324
325/* lltype -> int */
326CAMLprim value llvm_address_space(LLVMTypeRef PtrTy) {
327  return Val_int(LLVMGetPointerAddressSpace(PtrTy));
328}
329
330/* lltype -> int */
331CAMLprim value llvm_vector_size(LLVMTypeRef VectorTy) {
332  return Val_int(LLVMGetVectorSize(VectorTy));
333}
334
335/*--... Operations on other types ..........................................--*/
336
337/* llcontext -> lltype */
338CAMLprim LLVMTypeRef llvm_void_type (LLVMContextRef Context) {
339  return LLVMVoidTypeInContext(Context);
340}
341
342/* llcontext -> lltype */
343CAMLprim LLVMTypeRef llvm_label_type(LLVMContextRef Context) {
344  return LLVMLabelTypeInContext(Context);
345}
346
347/* llcontext -> lltype */
348CAMLprim LLVMTypeRef llvm_opaque_type(LLVMContextRef Context) {
349  return LLVMOpaqueTypeInContext(Context);
350}
351
352/*--... Operations on type handles .........................................--*/
353
354#define Typehandle_val(v)  (*(LLVMTypeHandleRef *)(Data_custom_val(v)))
355
356static void llvm_finalize_handle(value TH) {
357  LLVMDisposeTypeHandle(Typehandle_val(TH));
358}
359
360static struct custom_operations typehandle_ops = {
361  (char *) "LLVMTypeHandle",
362  llvm_finalize_handle,
363  custom_compare_default,
364  custom_hash_default,
365  custom_serialize_default,
366  custom_deserialize_default
367};
368
369CAMLprim value llvm_handle_to_type(LLVMTypeRef PATy) {
370  value TH = alloc_custom(&typehandle_ops, sizeof(LLVMBuilderRef), 0, 1);
371  Typehandle_val(TH) = LLVMCreateTypeHandle(PATy);
372  return TH;
373}
374
375CAMLprim LLVMTypeRef llvm_type_of_handle(value TH) {
376  return LLVMResolveTypeHandle(Typehandle_val(TH));
377}
378
379CAMLprim value llvm_refine_type(LLVMTypeRef AbstractTy, LLVMTypeRef ConcreteTy){
380  LLVMRefineType(AbstractTy, ConcreteTy);
381  return Val_unit;
382}
383
384
385/*===-- VALUES ------------------------------------------------------------===*/
386
387/* llvalue -> lltype */
388CAMLprim LLVMTypeRef llvm_type_of(LLVMValueRef Val) {
389  return LLVMTypeOf(Val);
390}
391
392/* llvalue -> string */
393CAMLprim value llvm_value_name(LLVMValueRef Val) {
394  return copy_string(LLVMGetValueName(Val));
395}
396
397/* string -> llvalue -> unit */
398CAMLprim value llvm_set_value_name(value Name, LLVMValueRef Val) {
399  LLVMSetValueName(Val, String_val(Name));
400  return Val_unit;
401}
402
403/* llvalue -> unit */
404CAMLprim value llvm_dump_value(LLVMValueRef Val) {
405  LLVMDumpValue(Val);
406  return Val_unit;
407}
408
409/*--... Operations on constants of (mostly) any type .......................--*/
410
411/* llvalue -> bool */
412CAMLprim value llvm_is_constant(LLVMValueRef Val) {
413  return Val_bool(LLVMIsConstant(Val));
414}
415
416/* llvalue -> bool */
417CAMLprim value llvm_is_null(LLVMValueRef Val) {
418  return Val_bool(LLVMIsNull(Val));
419}
420
421/* llvalue -> bool */
422CAMLprim value llvm_is_undef(LLVMValueRef Val) {
423  return Val_bool(LLVMIsUndef(Val));
424}
425
426/*--... Operations on scalar constants .....................................--*/
427
428/* lltype -> int -> llvalue */
429CAMLprim LLVMValueRef llvm_const_int(LLVMTypeRef IntTy, value N) {
430  return LLVMConstInt(IntTy, (long long) Int_val(N), 1);
431}
432
433/* lltype -> Int64.t -> bool -> llvalue */
434CAMLprim LLVMValueRef llvm_const_of_int64(LLVMTypeRef IntTy, value N,
435                                          value SExt) {
436  return LLVMConstInt(IntTy, Int64_val(N), Bool_val(SExt));
437}
438
439/* lltype -> string -> int -> llvalue */
440CAMLprim LLVMValueRef llvm_const_int_of_string(LLVMTypeRef IntTy, value S,
441                                               value Radix) {
442  return LLVMConstIntOfStringAndSize(IntTy, String_val(S), caml_string_length(S),
443                                     Int_val(Radix));
444}
445
446/* lltype -> float -> llvalue */
447CAMLprim LLVMValueRef llvm_const_float(LLVMTypeRef RealTy, value N) {
448  return LLVMConstReal(RealTy, Double_val(N));
449}
450
451/* lltype -> string -> llvalue */
452CAMLprim LLVMValueRef llvm_const_float_of_string(LLVMTypeRef RealTy, value S) {
453  return LLVMConstRealOfStringAndSize(RealTy, String_val(S),
454                                      caml_string_length(S));
455}
456
457/*--... Operations on composite constants ..................................--*/
458
459/* llcontext -> string -> llvalue */
460CAMLprim LLVMValueRef llvm_const_string(LLVMContextRef Context, value Str,
461                                        value NullTerminate) {
462  return LLVMConstStringInContext(Context, String_val(Str), string_length(Str),
463                                  1);
464}
465
466/* llcontext -> string -> llvalue */
467CAMLprim LLVMValueRef llvm_const_stringz(LLVMContextRef Context, value Str,
468                                         value NullTerminate) {
469  return LLVMConstStringInContext(Context, String_val(Str), string_length(Str),
470                                  0);
471}
472
473/* lltype -> llvalue array -> llvalue */
474CAMLprim LLVMValueRef llvm_const_array(LLVMTypeRef ElementTy,
475                                               value ElementVals) {
476  return LLVMConstArray(ElementTy, (LLVMValueRef*) Op_val(ElementVals),
477                        Wosize_val(ElementVals));
478}
479
480/* llcontext -> llvalue array -> llvalue */
481CAMLprim LLVMValueRef llvm_const_struct(LLVMContextRef C, value ElementVals) {
482  return LLVMConstStructInContext(C, (LLVMValueRef *) Op_val(ElementVals),
483                                  Wosize_val(ElementVals), 0);
484}
485
486/* llcontext -> llvalue array -> llvalue */
487CAMLprim LLVMValueRef llvm_const_packed_struct(LLVMContextRef C,
488                                               value ElementVals) {
489  return LLVMConstStructInContext(C, (LLVMValueRef *) Op_val(ElementVals),
490                                  Wosize_val(ElementVals), 1);
491}
492
493/* llvalue array -> llvalue */
494CAMLprim LLVMValueRef llvm_const_vector(value ElementVals) {
495  return LLVMConstVector((LLVMValueRef*) Op_val(ElementVals),
496                         Wosize_val(ElementVals));
497}
498
499/*--... Constant expressions ...............................................--*/
500
501/* Icmp.t -> llvalue -> llvalue -> llvalue */
502CAMLprim LLVMValueRef llvm_const_icmp(value Pred,
503                                      LLVMValueRef LHSConstant,
504                                      LLVMValueRef RHSConstant) {
505  return LLVMConstICmp(Int_val(Pred) + LLVMIntEQ, LHSConstant, RHSConstant);
506}
507
508/* Fcmp.t -> llvalue -> llvalue -> llvalue */
509CAMLprim LLVMValueRef llvm_const_fcmp(value Pred,
510                                      LLVMValueRef LHSConstant,
511                                      LLVMValueRef RHSConstant) {
512  return LLVMConstFCmp(Int_val(Pred), LHSConstant, RHSConstant);
513}
514
515/* llvalue -> llvalue array -> llvalue */
516CAMLprim LLVMValueRef llvm_const_gep(LLVMValueRef ConstantVal, value Indices) {
517  return LLVMConstGEP(ConstantVal, (LLVMValueRef*) Op_val(Indices),
518                      Wosize_val(Indices));
519}
520
521/* llvalue -> llvalue array -> llvalue */
522CAMLprim LLVMValueRef llvm_const_in_bounds_gep(LLVMValueRef ConstantVal,
523                                               value Indices) {
524  return LLVMConstInBoundsGEP(ConstantVal, (LLVMValueRef*) Op_val(Indices),
525                              Wosize_val(Indices));
526}
527
528/* llvalue -> int array -> llvalue */
529CAMLprim LLVMValueRef llvm_const_extractvalue(LLVMValueRef Aggregate,
530                                              value Indices) {
531  CAMLparam1(Indices);
532  int size = Wosize_val(Indices);
533  int i;
534  LLVMValueRef result;
535
536  unsigned* idxs = (unsigned*)malloc(size * sizeof(unsigned));
537  for (i = 0; i < size; i++) {
538    idxs[i] = Int_val(Field(Indices, i));
539  }
540
541  result = LLVMConstExtractValue(Aggregate, idxs, size);
542  free(idxs);
543  CAMLreturnT(LLVMValueRef, result);
544}
545
546/* llvalue -> llvalue -> int array -> llvalue */
547CAMLprim LLVMValueRef llvm_const_insertvalue(LLVMValueRef Aggregate,
548                                             LLVMValueRef Val, value Indices) {
549  CAMLparam1(Indices);
550  int size = Wosize_val(Indices);
551  int i;
552  LLVMValueRef result;
553
554  unsigned* idxs = (unsigned*)malloc(size * sizeof(unsigned));
555  for (i = 0; i < size; i++) {
556    idxs[i] = Int_val(Field(Indices, i));
557  }
558
559  result = LLVMConstInsertValue(Aggregate, Val, idxs, size);
560  free(idxs);
561  CAMLreturnT(LLVMValueRef, result);
562}
563
564/*--... Operations on global variables, functions, and aliases (globals) ...--*/
565
566/* llvalue -> bool */
567CAMLprim value llvm_is_declaration(LLVMValueRef Global) {
568  return Val_bool(LLVMIsDeclaration(Global));
569}
570
571/* llvalue -> Linkage.t */
572CAMLprim value llvm_linkage(LLVMValueRef Global) {
573  return Val_int(LLVMGetLinkage(Global));
574}
575
576/* Linkage.t -> llvalue -> unit */
577CAMLprim value llvm_set_linkage(value Linkage, LLVMValueRef Global) {
578  LLVMSetLinkage(Global, Int_val(Linkage));
579  return Val_unit;
580}
581
582/* llvalue -> string */
583CAMLprim value llvm_section(LLVMValueRef Global) {
584  return copy_string(LLVMGetSection(Global));
585}
586
587/* string -> llvalue -> unit */
588CAMLprim value llvm_set_section(value Section, LLVMValueRef Global) {
589  LLVMSetSection(Global, String_val(Section));
590  return Val_unit;
591}
592
593/* llvalue -> Visibility.t */
594CAMLprim value llvm_visibility(LLVMValueRef Global) {
595  return Val_int(LLVMGetVisibility(Global));
596}
597
598/* Visibility.t -> llvalue -> unit */
599CAMLprim value llvm_set_visibility(value Viz, LLVMValueRef Global) {
600  LLVMSetVisibility(Global, Int_val(Viz));
601  return Val_unit;
602}
603
604/* llvalue -> int */
605CAMLprim value llvm_alignment(LLVMValueRef Global) {
606  return Val_int(LLVMGetAlignment(Global));
607}
608
609/* int -> llvalue -> unit */
610CAMLprim value llvm_set_alignment(value Bytes, LLVMValueRef Global) {
611  LLVMSetAlignment(Global, Int_val(Bytes));
612  return Val_unit;
613}
614
615/*--... Operations on global variables .....................................--*/
616
617DEFINE_ITERATORS(global, Global, LLVMModuleRef, LLVMValueRef,
618                 LLVMGetGlobalParent)
619
620/* lltype -> string -> llmodule -> llvalue */
621CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name,
622                                          LLVMModuleRef M) {
623  LLVMValueRef GlobalVar;
624  if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
625    if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty)
626      return LLVMConstBitCast(GlobalVar, LLVMPointerType(Ty, 0));
627    return GlobalVar;
628  }
629  return LLVMAddGlobal(M, Ty, String_val(Name));
630}
631
632/* string -> llmodule -> llvalue option */
633CAMLprim value llvm_lookup_global(value Name, LLVMModuleRef M) {
634  CAMLparam1(Name);
635  LLVMValueRef GlobalVar;
636  if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
637    value Option = alloc(1, 0);
638    Field(Option, 0) = (value) GlobalVar;
639    CAMLreturn(Option);
640  }
641  CAMLreturn(Val_int(0));
642}
643
644/* string -> llvalue -> llmodule -> llvalue */
645CAMLprim LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer,
646                                         LLVMModuleRef M) {
647  LLVMValueRef GlobalVar = LLVMAddGlobal(M, LLVMTypeOf(Initializer),
648                                         String_val(Name));
649  LLVMSetInitializer(GlobalVar, Initializer);
650  return GlobalVar;
651}
652
653/* llvalue -> unit */
654CAMLprim value llvm_delete_global(LLVMValueRef GlobalVar) {
655  LLVMDeleteGlobal(GlobalVar);
656  return Val_unit;
657}
658
659/* llvalue -> llvalue -> unit */
660CAMLprim value llvm_set_initializer(LLVMValueRef ConstantVal,
661                                    LLVMValueRef GlobalVar) {
662  LLVMSetInitializer(GlobalVar, ConstantVal);
663  return Val_unit;
664}
665
666/* llvalue -> unit */
667CAMLprim value llvm_remove_initializer(LLVMValueRef GlobalVar) {
668  LLVMSetInitializer(GlobalVar, NULL);
669  return Val_unit;
670}
671
672/* llvalue -> bool */
673CAMLprim value llvm_is_thread_local(LLVMValueRef GlobalVar) {
674  return Val_bool(LLVMIsThreadLocal(GlobalVar));
675}
676
677/* bool -> llvalue -> unit */
678CAMLprim value llvm_set_thread_local(value IsThreadLocal,
679                                     LLVMValueRef GlobalVar) {
680  LLVMSetThreadLocal(GlobalVar, Bool_val(IsThreadLocal));
681  return Val_unit;
682}
683
684/* llvalue -> bool */
685CAMLprim value llvm_is_global_constant(LLVMValueRef GlobalVar) {
686  return Val_bool(LLVMIsGlobalConstant(GlobalVar));
687}
688
689/* bool -> llvalue -> unit */
690CAMLprim value llvm_set_global_constant(value Flag, LLVMValueRef GlobalVar) {
691  LLVMSetGlobalConstant(GlobalVar, Bool_val(Flag));
692  return Val_unit;
693}
694
695/*--... Operations on functions ............................................--*/
696
697DEFINE_ITERATORS(function, Function, LLVMModuleRef, LLVMValueRef,
698                 LLVMGetGlobalParent)
699
700/* string -> lltype -> llmodule -> llvalue */
701CAMLprim LLVMValueRef llvm_declare_function(value Name, LLVMTypeRef Ty,
702                                            LLVMModuleRef M) {
703  LLVMValueRef Fn;
704  if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
705    if (LLVMGetElementType(LLVMTypeOf(Fn)) != Ty)
706      return LLVMConstBitCast(Fn, LLVMPointerType(Ty, 0));
707    return Fn;
708  }
709  return LLVMAddFunction(M, String_val(Name), Ty);
710}
711
712/* string -> llmodule -> llvalue option */
713CAMLprim value llvm_lookup_function(value Name, LLVMModuleRef M) {
714  CAMLparam1(Name);
715  LLVMValueRef Fn;
716  if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
717    value Option = alloc(1, 0);
718    Field(Option, 0) = (value) Fn;
719    CAMLreturn(Option);
720  }
721  CAMLreturn(Val_int(0));
722}
723
724/* string -> lltype -> llmodule -> llvalue */
725CAMLprim LLVMValueRef llvm_define_function(value Name, LLVMTypeRef Ty,
726                                           LLVMModuleRef M) {
727  LLVMValueRef Fn = LLVMAddFunction(M, String_val(Name), Ty);
728  LLVMAppendBasicBlockInContext(LLVMGetTypeContext(Ty), Fn, "entry");
729  return Fn;
730}
731
732/* llvalue -> unit */
733CAMLprim value llvm_delete_function(LLVMValueRef Fn) {
734  LLVMDeleteFunction(Fn);
735  return Val_unit;
736}
737
738/* llvalue -> bool */
739CAMLprim value llvm_is_intrinsic(LLVMValueRef Fn) {
740  return Val_bool(LLVMGetIntrinsicID(Fn));
741}
742
743/* llvalue -> int */
744CAMLprim value llvm_function_call_conv(LLVMValueRef Fn) {
745  return Val_int(LLVMGetFunctionCallConv(Fn));
746}
747
748/* int -> llvalue -> unit */
749CAMLprim value llvm_set_function_call_conv(value Id, LLVMValueRef Fn) {
750  LLVMSetFunctionCallConv(Fn, Int_val(Id));
751  return Val_unit;
752}
753
754/* llvalue -> string option */
755CAMLprim value llvm_gc(LLVMValueRef Fn) {
756  const char *GC;
757  CAMLparam0();
758  CAMLlocal2(Name, Option);
759
760  if ((GC = LLVMGetGC(Fn))) {
761    Name = copy_string(GC);
762
763    Option = alloc(1, 0);
764    Field(Option, 0) = Name;
765    CAMLreturn(Option);
766  } else {
767    CAMLreturn(Val_int(0));
768  }
769}
770
771/* string option -> llvalue -> unit */
772CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) {
773  LLVMSetGC(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0)));
774  return Val_unit;
775}
776
777/* llvalue -> Attribute.t -> unit */
778CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) {
779  LLVMAddFunctionAttr(Arg, 1<<Int_val(PA));
780  return Val_unit;
781}
782
783/* llvalue -> Attribute.t -> unit */
784CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) {
785  LLVMRemoveFunctionAttr(Arg, 1<<Int_val(PA));
786  return Val_unit;
787}
788/*--... Operations on parameters ...........................................--*/
789
790DEFINE_ITERATORS(param, Param, LLVMValueRef, LLVMValueRef, LLVMGetParamParent)
791
792/* llvalue -> int -> llvalue */
793CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) {
794  return LLVMGetParam(Fn, Int_val(Index));
795}
796
797/* llvalue -> int -> llvalue */
798CAMLprim value llvm_params(LLVMValueRef Fn, value Index) {
799  value Params = alloc(LLVMCountParams(Fn), 0);
800  LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params));
801  return Params;
802}
803
804/* llvalue -> Attribute.t -> unit */
805CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) {
806  LLVMAddAttribute(Arg, 1<<Int_val(PA));
807  return Val_unit;
808}
809
810/* llvalue -> Attribute.t -> unit */
811CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) {
812  LLVMRemoveAttribute(Arg, 1<<Int_val(PA));
813  return Val_unit;
814}
815
816/* llvalue -> int -> unit */
817CAMLprim value llvm_set_param_alignment(LLVMValueRef Arg, value align) {
818  LLVMSetParamAlignment(Arg, Int_val(align));
819  return Val_unit;
820}
821
822/*--... Operations on basic blocks .........................................--*/
823
824DEFINE_ITERATORS(
825  block, BasicBlock, LLVMValueRef, LLVMBasicBlockRef, LLVMGetBasicBlockParent)
826
827/* llvalue -> llbasicblock array */
828CAMLprim value llvm_basic_blocks(LLVMValueRef Fn) {
829  value MLArray = alloc(LLVMCountBasicBlocks(Fn), 0);
830  LLVMGetBasicBlocks(Fn, (LLVMBasicBlockRef *) Op_val(MLArray));
831  return MLArray;
832}
833
834/* llbasicblock -> unit */
835CAMLprim value llvm_delete_block(LLVMBasicBlockRef BB) {
836  LLVMDeleteBasicBlock(BB);
837  return Val_unit;
838}
839
840/* string -> llvalue -> llbasicblock */
841CAMLprim LLVMBasicBlockRef llvm_append_block(LLVMContextRef Context, value Name,
842                                             LLVMValueRef Fn) {
843  return LLVMAppendBasicBlockInContext(Context, Fn, String_val(Name));
844}
845
846/* string -> llbasicblock -> llbasicblock */
847CAMLprim LLVMBasicBlockRef llvm_insert_block(LLVMContextRef Context, value Name,
848                                             LLVMBasicBlockRef BB) {
849  return LLVMInsertBasicBlockInContext(Context, BB, String_val(Name));
850}
851
852/* llvalue -> bool */
853CAMLprim value llvm_value_is_block(LLVMValueRef Val) {
854  return Val_bool(LLVMValueIsBasicBlock(Val));
855}
856
857/*--... Operations on instructions .........................................--*/
858
859DEFINE_ITERATORS(instr, Instruction, LLVMBasicBlockRef, LLVMValueRef,
860                 LLVMGetInstructionParent)
861
862
863/*--... Operations on call sites ...........................................--*/
864
865/* llvalue -> int */
866CAMLprim value llvm_instruction_call_conv(LLVMValueRef Inst) {
867  return Val_int(LLVMGetInstructionCallConv(Inst));
868}
869
870/* int -> llvalue -> unit */
871CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) {
872  LLVMSetInstructionCallConv(Inst, Int_val(CC));
873  return Val_unit;
874}
875
876/* llvalue -> int -> Attribute.t -> unit */
877CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr,
878                                               value index,
879                                               value PA) {
880  LLVMAddInstrAttribute(Instr, Int_val(index), 1<<Int_val(PA));
881  return Val_unit;
882}
883
884/* llvalue -> int -> Attribute.t -> unit */
885CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr,
886                                                  value index,
887                                                  value PA) {
888  LLVMRemoveInstrAttribute(Instr, Int_val(index), 1<<Int_val(PA));
889  return Val_unit;
890}
891
892/*--... Operations on call instructions (only) .............................--*/
893
894/* llvalue -> bool */
895CAMLprim value llvm_is_tail_call(LLVMValueRef CallInst) {
896  return Val_bool(LLVMIsTailCall(CallInst));
897}
898
899/* bool -> llvalue -> unit */
900CAMLprim value llvm_set_tail_call(value IsTailCall,
901                                  LLVMValueRef CallInst) {
902  LLVMSetTailCall(CallInst, Bool_val(IsTailCall));
903  return Val_unit;
904}
905
906/*--... Operations on phi nodes ............................................--*/
907
908/* (llvalue * llbasicblock) -> llvalue -> unit */
909CAMLprim value llvm_add_incoming(value Incoming, LLVMValueRef PhiNode) {
910  LLVMAddIncoming(PhiNode,
911                  (LLVMValueRef*) &Field(Incoming, 0),
912                  (LLVMBasicBlockRef*) &Field(Incoming, 1),
913                  1);
914  return Val_unit;
915}
916
917/* llvalue -> (llvalue * llbasicblock) list */
918CAMLprim value llvm_incoming(LLVMValueRef PhiNode) {
919  unsigned I;
920  CAMLparam0();
921  CAMLlocal3(Hd, Tl, Tmp);
922
923  /* Build a tuple list of them. */
924  Tl = Val_int(0);
925  for (I = LLVMCountIncoming(PhiNode); I != 0; ) {
926    Hd = alloc(2, 0);
927    Store_field(Hd, 0, (value) LLVMGetIncomingValue(PhiNode, --I));
928    Store_field(Hd, 1, (value) LLVMGetIncomingBlock(PhiNode, I));
929
930    Tmp = alloc(2, 0);
931    Store_field(Tmp, 0, Hd);
932    Store_field(Tmp, 1, Tl);
933    Tl = Tmp;
934  }
935
936  CAMLreturn(Tl);
937}
938
939
940/*===-- Instruction builders ----------------------------------------------===*/
941
942#define Builder_val(v)  (*(LLVMBuilderRef *)(Data_custom_val(v)))
943
944static void llvm_finalize_builder(value B) {
945  LLVMDisposeBuilder(Builder_val(B));
946}
947
948static struct custom_operations builder_ops = {
949  (char *) "IRBuilder",
950  llvm_finalize_builder,
951  custom_compare_default,
952  custom_hash_default,
953  custom_serialize_default,
954  custom_deserialize_default
955};
956
957static value alloc_builder(LLVMBuilderRef B) {
958  value V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1);
959  Builder_val(V) = B;
960  return V;
961}
962
963/* llcontext -> llbuilder */
964CAMLprim value llvm_builder(LLVMContextRef C) {
965  return alloc_builder(LLVMCreateBuilderInContext(C));
966}
967
968/* (llbasicblock, llvalue) llpos -> llbuilder -> unit */
969CAMLprim value llvm_position_builder(value Pos, value B) {
970  if (Tag_val(Pos) == 0) {
971    LLVMBasicBlockRef BB = (LLVMBasicBlockRef) Op_val(Field(Pos, 0));
972    LLVMPositionBuilderAtEnd(Builder_val(B), BB);
973  } else {
974    LLVMValueRef I = (LLVMValueRef) Op_val(Field(Pos, 0));
975    LLVMPositionBuilderBefore(Builder_val(B), I);
976  }
977  return Val_unit;
978}
979
980/* llbuilder -> llbasicblock */
981CAMLprim LLVMBasicBlockRef llvm_insertion_block(LLVMBuilderRef B) {
982  LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B));
983  if (!InsertBlock)
984    raise_not_found();
985  return InsertBlock;
986}
987
988/* llvalue -> string -> llbuilder -> unit */
989CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name,
990                                               LLVMBuilderRef B) {
991  LLVMInsertIntoBuilderWithName(B, I, String_val(Name));
992  return Val_unit;
993}
994
995/*--... Terminators ........................................................--*/
996
997/* llbuilder -> llvalue */
998CAMLprim LLVMValueRef llvm_build_ret_void(value B) {
999  return LLVMBuildRetVoid(Builder_val(B));
1000}
1001
1002/* llvalue -> llbuilder -> llvalue */
1003CAMLprim LLVMValueRef llvm_build_ret(LLVMValueRef Val, value B) {
1004  return LLVMBuildRet(Builder_val(B), Val);
1005}
1006
1007/* llvalue array -> llbuilder -> llvalue */
1008CAMLprim LLVMValueRef llvm_build_aggregate_ret(value RetVals, value B) {
1009  return LLVMBuildAggregateRet(Builder_val(B), (LLVMValueRef *) Op_val(RetVals),
1010                               Wosize_val(RetVals));
1011}
1012
1013/* llbasicblock -> llbuilder -> llvalue */
1014CAMLprim LLVMValueRef llvm_build_br(LLVMBasicBlockRef BB, value B) {
1015  return LLVMBuildBr(Builder_val(B), BB);
1016}
1017
1018/* llvalue -> llbasicblock -> llbasicblock -> llbuilder -> llvalue */
1019CAMLprim LLVMValueRef llvm_build_cond_br(LLVMValueRef If,
1020                                         LLVMBasicBlockRef Then,
1021                                         LLVMBasicBlockRef Else,
1022                                         value B) {
1023  return LLVMBuildCondBr(Builder_val(B), If, Then, Else);
1024}
1025
1026/* llvalue -> llbasicblock -> int -> llbuilder -> llvalue */
1027CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of,
1028                                        LLVMBasicBlockRef Else,
1029                                        value EstimatedCount,
1030                                        value B) {
1031  return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
1032}
1033
1034CAMLprim value llvm_add_case(LLVMValueRef Switch,
1035                             LLVMValueRef OnVal,
1036                             LLVMBasicBlockRef Dest) {
1037  LLVMAddCase(Switch, OnVal, Dest);
1038  return Val_unit;
1039}
1040
1041/* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
1042   llbuilder -> llvalue */
1043CAMLprim LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args,
1044                                            LLVMBasicBlockRef Then,
1045                                            LLVMBasicBlockRef Catch,
1046                                            value Name, value B) {
1047  return LLVMBuildInvoke(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Args),
1048                         Wosize_val(Args), Then, Catch, String_val(Name));
1049}
1050
1051/* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
1052   llbuilder -> llvalue */
1053CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) {
1054  return llvm_build_invoke_nat((LLVMValueRef) Args[0], Args[1],
1055                               (LLVMBasicBlockRef) Args[2],
1056                               (LLVMBasicBlockRef) Args[3],
1057                               Args[4], Args[5]);
1058}
1059
1060/* llbuilder -> llvalue */
1061CAMLprim LLVMValueRef llvm_build_unwind(value B) {
1062  return LLVMBuildUnwind(Builder_val(B));
1063}
1064
1065/* llbuilder -> llvalue */
1066CAMLprim LLVMValueRef llvm_build_unreachable(value B) {
1067  return LLVMBuildUnreachable(Builder_val(B));
1068}
1069
1070/*--... Arithmetic .........................................................--*/
1071
1072/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1073CAMLprim LLVMValueRef llvm_build_add(LLVMValueRef LHS, LLVMValueRef RHS,
1074                                     value Name, value B) {
1075  return LLVMBuildAdd(Builder_val(B), LHS, RHS, String_val(Name));
1076}
1077
1078/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1079CAMLprim LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS,
1080                                         value Name, value B) {
1081  return LLVMBuildNSWAdd(Builder_val(B), LHS, RHS, String_val(Name));
1082}
1083
1084/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1085CAMLprim LLVMValueRef llvm_build_fadd(LLVMValueRef LHS, LLVMValueRef RHS,
1086                                      value Name, value B) {
1087  return LLVMBuildFAdd(Builder_val(B), LHS, RHS, String_val(Name));
1088}
1089
1090/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1091CAMLprim LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS,
1092                                     value Name, value B) {
1093  return LLVMBuildSub(Builder_val(B), LHS, RHS, String_val(Name));
1094}
1095
1096/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1097CAMLprim LLVMValueRef llvm_build_fsub(LLVMValueRef LHS, LLVMValueRef RHS,
1098                                      value Name, value B) {
1099  return LLVMBuildFSub(Builder_val(B), LHS, RHS, String_val(Name));
1100}
1101
1102/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1103CAMLprim LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS,
1104                                     value Name, value B) {
1105  return LLVMBuildMul(Builder_val(B), LHS, RHS, String_val(Name));
1106}
1107
1108/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1109CAMLprim LLVMValueRef llvm_build_fmul(LLVMValueRef LHS, LLVMValueRef RHS,
1110                                      value Name, value B) {
1111  return LLVMBuildFMul(Builder_val(B), LHS, RHS, String_val(Name));
1112}
1113
1114/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1115CAMLprim LLVMValueRef llvm_build_udiv(LLVMValueRef LHS, LLVMValueRef RHS,
1116                                      value Name, value B) {
1117  return LLVMBuildUDiv(Builder_val(B), LHS, RHS, String_val(Name));
1118}
1119
1120/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1121CAMLprim LLVMValueRef llvm_build_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1122                                      value Name, value B) {
1123  return LLVMBuildSDiv(Builder_val(B), LHS, RHS, String_val(Name));
1124}
1125
1126/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1127CAMLprim LLVMValueRef llvm_build_exact_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1128                                            value Name, value B) {
1129  return LLVMBuildExactSDiv(Builder_val(B), LHS, RHS, String_val(Name));
1130}
1131
1132/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1133CAMLprim LLVMValueRef llvm_build_fdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1134                                      value Name, value B) {
1135  return LLVMBuildFDiv(Builder_val(B), LHS, RHS, String_val(Name));
1136}
1137
1138/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1139CAMLprim LLVMValueRef llvm_build_urem(LLVMValueRef LHS, LLVMValueRef RHS,
1140                                      value Name, value B) {
1141  return LLVMBuildURem(Builder_val(B), LHS, RHS, String_val(Name));
1142}
1143
1144/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1145CAMLprim LLVMValueRef llvm_build_srem(LLVMValueRef LHS, LLVMValueRef RHS,
1146                                      value Name, value B) {
1147  return LLVMBuildSRem(Builder_val(B), LHS, RHS, String_val(Name));
1148}
1149
1150/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1151CAMLprim LLVMValueRef llvm_build_frem(LLVMValueRef LHS, LLVMValueRef RHS,
1152                                      value Name, value B) {
1153  return LLVMBuildFRem(Builder_val(B), LHS, RHS, String_val(Name));
1154}
1155
1156/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1157CAMLprim LLVMValueRef llvm_build_shl(LLVMValueRef LHS, LLVMValueRef RHS,
1158                                     value Name, value B) {
1159  return LLVMBuildShl(Builder_val(B), LHS, RHS, String_val(Name));
1160}
1161
1162/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1163CAMLprim LLVMValueRef llvm_build_lshr(LLVMValueRef LHS, LLVMValueRef RHS,
1164                                      value Name, value B) {
1165  return LLVMBuildLShr(Builder_val(B), LHS, RHS, String_val(Name));
1166}
1167
1168/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1169CAMLprim LLVMValueRef llvm_build_ashr(LLVMValueRef LHS, LLVMValueRef RHS,
1170                                      value Name, value B) {
1171  return LLVMBuildAShr(Builder_val(B), LHS, RHS, String_val(Name));
1172}
1173
1174/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1175CAMLprim LLVMValueRef llvm_build_and(LLVMValueRef LHS, LLVMValueRef RHS,
1176                                     value Name, value B) {
1177  return LLVMBuildAnd(Builder_val(B), LHS, RHS, String_val(Name));
1178}
1179
1180/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1181CAMLprim LLVMValueRef llvm_build_or(LLVMValueRef LHS, LLVMValueRef RHS,
1182                                    value Name, value B) {
1183  return LLVMBuildOr(Builder_val(B), LHS, RHS, String_val(Name));
1184}
1185
1186/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1187CAMLprim LLVMValueRef llvm_build_xor(LLVMValueRef LHS, LLVMValueRef RHS,
1188                                     value Name, value B) {
1189  return LLVMBuildXor(Builder_val(B), LHS, RHS, String_val(Name));
1190}
1191
1192/* llvalue -> string -> llbuilder -> llvalue */
1193CAMLprim LLVMValueRef llvm_build_neg(LLVMValueRef X,
1194                                     value Name, value B) {
1195  return LLVMBuildNeg(Builder_val(B), X, String_val(Name));
1196}
1197
1198/* llvalue -> string -> llbuilder -> llvalue */
1199CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X,
1200                                     value Name, value B) {
1201  return LLVMBuildNot(Builder_val(B), X, String_val(Name));
1202}
1203
1204/*--... Memory .............................................................--*/
1205
1206/* lltype -> string -> llbuilder -> llvalue */
1207CAMLprim LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty,
1208                                        value Name, value B) {
1209  return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name));
1210}
1211
1212/* lltype -> llvalue -> string -> llbuilder -> llvalue */
1213CAMLprim LLVMValueRef llvm_build_array_malloc(LLVMTypeRef Ty, LLVMValueRef Size,
1214                                              value Name, value B) {
1215  return LLVMBuildArrayMalloc(Builder_val(B), Ty, Size, String_val(Name));
1216}
1217
1218/* lltype -> string -> llbuilder -> llvalue */
1219CAMLprim LLVMValueRef llvm_build_alloca(LLVMTypeRef Ty,
1220                                        value Name, value B) {
1221  return LLVMBuildAlloca(Builder_val(B), Ty, String_val(Name));
1222}
1223
1224/* lltype -> llvalue -> string -> llbuilder -> llvalue */
1225CAMLprim LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size,
1226                                              value Name, value B) {
1227  return LLVMBuildArrayAlloca(Builder_val(B), Ty, Size, String_val(Name));
1228}
1229
1230/* llvalue -> llbuilder -> llvalue */
1231CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef Pointer, value B) {
1232  return LLVMBuildFree(Builder_val(B), Pointer);
1233}
1234
1235/* llvalue -> string -> llbuilder -> llvalue */
1236CAMLprim LLVMValueRef llvm_build_load(LLVMValueRef Pointer,
1237                                      value Name, value B) {
1238  return LLVMBuildLoad(Builder_val(B), Pointer, String_val(Name));
1239}
1240
1241/* llvalue -> llvalue -> llbuilder -> llvalue */
1242CAMLprim LLVMValueRef llvm_build_store(LLVMValueRef Value, LLVMValueRef Pointer,
1243                                       value B) {
1244  return LLVMBuildStore(Builder_val(B), Value, Pointer);
1245}
1246
1247/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
1248CAMLprim LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices,
1249                                     value Name, value B) {
1250  return LLVMBuildGEP(Builder_val(B), Pointer,
1251                      (LLVMValueRef *) Op_val(Indices), Wosize_val(Indices),
1252                      String_val(Name));
1253}
1254
1255/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
1256CAMLprim LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer,
1257                                               value Indices, value Name,
1258                                               value B) {
1259  return LLVMBuildInBoundsGEP(Builder_val(B), Pointer,
1260                              (LLVMValueRef *) Op_val(Indices),
1261                              Wosize_val(Indices), String_val(Name));
1262}
1263
1264/* llvalue -> int -> string -> llbuilder -> llvalue */
1265CAMLprim LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer,
1266                                               value Index, value Name,
1267                                               value B) {
1268  return LLVMBuildStructGEP(Builder_val(B), Pointer,
1269                              Int_val(Index), String_val(Name));
1270}
1271
1272/* string -> string -> llbuilder -> llvalue */
1273CAMLprim LLVMValueRef llvm_build_global_string(value Str, value Name, value B) {
1274  return LLVMBuildGlobalString(Builder_val(B), String_val(Str),
1275                               String_val(Name));
1276}
1277
1278/* string -> string -> llbuilder -> llvalue */
1279CAMLprim LLVMValueRef llvm_build_global_stringptr(value Str, value Name,
1280                                                  value B) {
1281  return LLVMBuildGlobalStringPtr(Builder_val(B), String_val(Str),
1282                                  String_val(Name));
1283}
1284
1285/*--... Casts ..............................................................--*/
1286
1287/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1288CAMLprim LLVMValueRef llvm_build_trunc(LLVMValueRef X, LLVMTypeRef Ty,
1289                                       value Name, value B) {
1290  return LLVMBuildTrunc(Builder_val(B), X, Ty, String_val(Name));
1291}
1292
1293/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1294CAMLprim LLVMValueRef llvm_build_zext(LLVMValueRef X, LLVMTypeRef Ty,
1295                                      value Name, value B) {
1296  return LLVMBuildZExt(Builder_val(B), X, Ty, String_val(Name));
1297}
1298
1299/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1300CAMLprim LLVMValueRef llvm_build_sext(LLVMValueRef X, LLVMTypeRef Ty,
1301                                      value Name, value B) {
1302  return LLVMBuildSExt(Builder_val(B), X, Ty, String_val(Name));
1303}
1304
1305/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1306CAMLprim LLVMValueRef llvm_build_fptoui(LLVMValueRef X, LLVMTypeRef Ty,
1307                                        value Name, value B) {
1308  return LLVMBuildFPToUI(Builder_val(B), X, Ty, String_val(Name));
1309}
1310
1311/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1312CAMLprim LLVMValueRef llvm_build_fptosi(LLVMValueRef X, LLVMTypeRef Ty,
1313                                        value Name, value B) {
1314  return LLVMBuildFPToSI(Builder_val(B), X, Ty, String_val(Name));
1315}
1316
1317/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1318CAMLprim LLVMValueRef llvm_build_uitofp(LLVMValueRef X, LLVMTypeRef Ty,
1319                                        value Name, value B) {
1320  return LLVMBuildUIToFP(Builder_val(B), X, Ty, String_val(Name));
1321}
1322
1323/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1324CAMLprim LLVMValueRef llvm_build_sitofp(LLVMValueRef X, LLVMTypeRef Ty,
1325                                        value Name, value B) {
1326  return LLVMBuildSIToFP(Builder_val(B), X, Ty, String_val(Name));
1327}
1328
1329/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1330CAMLprim LLVMValueRef llvm_build_fptrunc(LLVMValueRef X, LLVMTypeRef Ty,
1331                                         value Name, value B) {
1332  return LLVMBuildFPTrunc(Builder_val(B), X, Ty, String_val(Name));
1333}
1334
1335/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1336CAMLprim LLVMValueRef llvm_build_fpext(LLVMValueRef X, LLVMTypeRef Ty,
1337                                       value Name, value B) {
1338  return LLVMBuildFPExt(Builder_val(B), X, Ty, String_val(Name));
1339}
1340
1341/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1342CAMLprim LLVMValueRef llvm_build_prttoint(LLVMValueRef X, LLVMTypeRef Ty,
1343                                          value Name, value B) {
1344  return LLVMBuildPtrToInt(Builder_val(B), X, Ty, String_val(Name));
1345}
1346
1347/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1348CAMLprim LLVMValueRef llvm_build_inttoptr(LLVMValueRef X, LLVMTypeRef Ty,
1349                                          value Name, value B) {
1350  return LLVMBuildIntToPtr(Builder_val(B), X, Ty, String_val(Name));
1351}
1352
1353/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1354CAMLprim LLVMValueRef llvm_build_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
1355                                         value Name, value B) {
1356  return LLVMBuildBitCast(Builder_val(B), X, Ty, String_val(Name));
1357}
1358
1359/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1360CAMLprim LLVMValueRef llvm_build_zext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
1361                                                 value Name, value B) {
1362  return LLVMBuildZExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
1363}
1364
1365/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1366CAMLprim LLVMValueRef llvm_build_sext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
1367                                                 value Name, value B) {
1368  return LLVMBuildSExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
1369}
1370
1371/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1372CAMLprim LLVMValueRef llvm_build_trunc_or_bitcast(LLVMValueRef X,
1373                                                  LLVMTypeRef Ty, value Name,
1374                                                  value B) {
1375  return LLVMBuildTruncOrBitCast(Builder_val(B), X, Ty, String_val(Name));
1376}
1377
1378/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1379CAMLprim LLVMValueRef llvm_build_pointercast(LLVMValueRef X, LLVMTypeRef Ty,
1380                                             value Name, value B) {
1381  return LLVMBuildPointerCast(Builder_val(B), X, Ty, String_val(Name));
1382}
1383
1384/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1385CAMLprim LLVMValueRef llvm_build_intcast(LLVMValueRef X, LLVMTypeRef Ty,
1386                                         value Name, value B) {
1387  return LLVMBuildIntCast(Builder_val(B), X, Ty, String_val(Name));
1388}
1389
1390/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1391CAMLprim LLVMValueRef llvm_build_fpcast(LLVMValueRef X, LLVMTypeRef Ty,
1392                                        value Name, value B) {
1393  return LLVMBuildFPCast(Builder_val(B), X, Ty, String_val(Name));
1394}
1395
1396/*--... Comparisons ........................................................--*/
1397
1398/* Icmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
1399CAMLprim LLVMValueRef llvm_build_icmp(value Pred,
1400                                      LLVMValueRef LHS, LLVMValueRef RHS,
1401                                      value Name, value B) {
1402  return LLVMBuildICmp(Builder_val(B), Int_val(Pred) + LLVMIntEQ, LHS, RHS,
1403                       String_val(Name));
1404}
1405
1406/* Fcmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
1407CAMLprim LLVMValueRef llvm_build_fcmp(value Pred,
1408                                      LLVMValueRef LHS, LLVMValueRef RHS,
1409                                      value Name, value B) {
1410  return LLVMBuildFCmp(Builder_val(B), Int_val(Pred), LHS, RHS,
1411                       String_val(Name));
1412}
1413
1414/*--... Miscellaneous instructions .........................................--*/
1415
1416/* (llvalue * llbasicblock) list -> string -> llbuilder -> llvalue */
1417CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) {
1418  value Hd, Tl;
1419  LLVMValueRef FirstValue, PhiNode;
1420
1421  assert(Incoming != Val_int(0) && "Empty list passed to Llvm.build_phi!");
1422
1423  Hd = Field(Incoming, 0);
1424  FirstValue = (LLVMValueRef) Field(Hd, 0);
1425  PhiNode = LLVMBuildPhi(Builder_val(B), LLVMTypeOf(FirstValue),
1426                         String_val(Name));
1427
1428  for (Tl = Incoming; Tl != Val_int(0); Tl = Field(Tl, 1)) {
1429    value Hd = Field(Tl, 0);
1430    LLVMAddIncoming(PhiNode, (LLVMValueRef*) &Field(Hd, 0),
1431                    (LLVMBasicBlockRef*) &Field(Hd, 1), 1);
1432  }
1433
1434  return PhiNode;
1435}
1436
1437/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
1438CAMLprim LLVMValueRef llvm_build_call(LLVMValueRef Fn, value Params,
1439                                      value Name, value B) {
1440  return LLVMBuildCall(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Params),
1441                       Wosize_val(Params), String_val(Name));
1442}
1443
1444/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
1445CAMLprim LLVMValueRef llvm_build_select(LLVMValueRef If,
1446                                        LLVMValueRef Then, LLVMValueRef Else,
1447                                        value Name, value B) {
1448  return LLVMBuildSelect(Builder_val(B), If, Then, Else, String_val(Name));
1449}
1450
1451/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1452CAMLprim LLVMValueRef llvm_build_va_arg(LLVMValueRef List, LLVMTypeRef Ty,
1453                                        value Name, value B) {
1454  return LLVMBuildVAArg(Builder_val(B), List, Ty, String_val(Name));
1455}
1456
1457/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1458CAMLprim LLVMValueRef llvm_build_extractelement(LLVMValueRef Vec,
1459                                                LLVMValueRef Idx,
1460                                                value Name, value B) {
1461  return LLVMBuildExtractElement(Builder_val(B), Vec, Idx, String_val(Name));
1462}
1463
1464/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
1465CAMLprim LLVMValueRef llvm_build_insertelement(LLVMValueRef Vec,
1466                                               LLVMValueRef Element,
1467                                               LLVMValueRef Idx,
1468                                               value Name, value B) {
1469  return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx,
1470                                String_val(Name));
1471}
1472
1473/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
1474CAMLprim LLVMValueRef llvm_build_shufflevector(LLVMValueRef V1, LLVMValueRef V2,
1475                                               LLVMValueRef Mask,
1476                                               value Name, value B) {
1477  return LLVMBuildShuffleVector(Builder_val(B), V1, V2, Mask, String_val(Name));
1478}
1479
1480/* llvalue -> int -> string -> llbuilder -> llvalue */
1481CAMLprim LLVMValueRef llvm_build_extractvalue(LLVMValueRef Aggregate,
1482                                              value Idx, value Name, value B) {
1483  return LLVMBuildExtractValue(Builder_val(B), Aggregate, Int_val(Idx),
1484                               String_val(Name));
1485}
1486
1487/* llvalue -> llvalue -> int -> string -> llbuilder -> llvalue */
1488CAMLprim LLVMValueRef llvm_build_insertvalue(LLVMValueRef Aggregate,
1489                                             LLVMValueRef Val, value Idx,
1490                                             value Name, value B) {
1491  return LLVMBuildInsertValue(Builder_val(B), Aggregate, Val, Int_val(Idx),
1492                              String_val(Name));
1493}
1494
1495/* llvalue -> string -> llbuilder -> llvalue */
1496CAMLprim LLVMValueRef llvm_build_is_null(LLVMValueRef Val, value Name,
1497                                         value B) {
1498  return LLVMBuildIsNull(Builder_val(B), Val, String_val(Name));
1499}
1500
1501/* llvalue -> string -> llbuilder -> llvalue */
1502CAMLprim LLVMValueRef llvm_build_is_not_null(LLVMValueRef Val, value Name,
1503                                             value B) {
1504  return LLVMBuildIsNotNull(Builder_val(B), Val, String_val(Name));
1505}
1506
1507/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1508CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS,
1509                                         value Name, value B) {
1510  return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name));
1511}
1512
1513/*===-- Module Providers --------------------------------------------------===*/
1514
1515/* llmoduleprovider -> unit */
1516CAMLprim value llvm_dispose_module_provider(LLVMModuleProviderRef MP) {
1517  LLVMDisposeModuleProvider(MP);
1518  return Val_unit;
1519}
1520
1521
1522/*===-- Memory buffers ----------------------------------------------------===*/
1523
1524/* string -> llmemorybuffer
1525   raises IoError msg on error */
1526CAMLprim value llvm_memorybuffer_of_file(value Path) {
1527  CAMLparam1(Path);
1528  char *Message;
1529  LLVMMemoryBufferRef MemBuf;
1530
1531  if (LLVMCreateMemoryBufferWithContentsOfFile(String_val(Path),
1532                                               &MemBuf, &Message))
1533    llvm_raise(llvm_ioerror_exn, Message);
1534
1535  CAMLreturn((value) MemBuf);
1536}
1537
1538/* unit -> llmemorybuffer
1539   raises IoError msg on error */
1540CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) {
1541  char *Message;
1542  LLVMMemoryBufferRef MemBuf;
1543
1544  if (LLVMCreateMemoryBufferWithSTDIN(&MemBuf, &Message))
1545    llvm_raise(llvm_ioerror_exn, Message);
1546
1547  return MemBuf;
1548}
1549
1550/* llmemorybuffer -> unit */
1551CAMLprim value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) {
1552  LLVMDisposeMemoryBuffer(MemBuf);
1553  return Val_unit;
1554}
1555
1556/*===-- Pass Managers -----------------------------------------------------===*/
1557
1558/* unit -> [ `Module ] PassManager.t */
1559CAMLprim LLVMPassManagerRef llvm_passmanager_create(value Unit) {
1560  return LLVMCreatePassManager();
1561}
1562
1563/* llmodule -> [ `Function ] PassManager.t -> bool */
1564CAMLprim value llvm_passmanager_run_module(LLVMModuleRef M,
1565                                           LLVMPassManagerRef PM) {
1566  return Val_bool(LLVMRunPassManager(PM, M));
1567}
1568
1569/* [ `Function ] PassManager.t -> bool */
1570CAMLprim value llvm_passmanager_initialize(LLVMPassManagerRef FPM) {
1571  return Val_bool(LLVMInitializeFunctionPassManager(FPM));
1572}
1573
1574/* llvalue -> [ `Function ] PassManager.t -> bool */
1575CAMLprim value llvm_passmanager_run_function(LLVMValueRef F,
1576                                             LLVMPassManagerRef FPM) {
1577  return Val_bool(LLVMRunFunctionPassManager(FPM, F));
1578}
1579
1580/* [ `Function ] PassManager.t -> bool */
1581CAMLprim value llvm_passmanager_finalize(LLVMPassManagerRef FPM) {
1582  return Val_bool(LLVMFinalizeFunctionPassManager(FPM));
1583}
1584
1585/* PassManager.any PassManager.t -> unit */
1586CAMLprim value llvm_passmanager_dispose(LLVMPassManagerRef PM) {
1587  LLVMDisposePassManager(PM);
1588  return Val_unit;
1589}
1590