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