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