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