xref: /llvm-project/llvm/bindings/ocaml/executionengine/executionengine_ocaml.c (revision 30f423a543641816e367cd17dad3d4808cba8a79)
1 /*===-- executionengine_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 "caml/alloc.h"
19 #include "caml/callback.h"
20 #include "caml/custom.h"
21 #include "caml/fail.h"
22 #include "caml/memory.h"
23 #include "llvm_ocaml.h"
24 #include "llvm-c/Core.h"
25 #include "llvm-c/ExecutionEngine.h"
26 #include "llvm-c/Target.h"
27 #include <assert.h>
28 #include <string.h>
29 
30 #define ExecutionEngine_val(v) ((LLVMExecutionEngineRef)from_val(v))
31 
32 void llvm_raise(value Prototype, char *Message);
33 
34 /* unit -> bool */
llvm_ee_initialize(value Unit)35 value llvm_ee_initialize(value Unit) {
36   LLVMLinkInMCJIT();
37 
38   return Val_bool(!LLVMInitializeNativeTarget() &&
39                   !LLVMInitializeNativeAsmParser() &&
40                   !LLVMInitializeNativeAsmPrinter());
41 }
42 
43 /* llcompileroption -> llmodule -> ExecutionEngine.t */
llvm_ee_create(value OptRecordOpt,value M)44 value llvm_ee_create(value OptRecordOpt, value M) {
45   LLVMExecutionEngineRef MCJIT;
46   char *Error;
47   struct LLVMMCJITCompilerOptions Options;
48 
49   LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
50   if (OptRecordOpt != Val_int(0)) {
51     value OptRecord = Field(OptRecordOpt, 0);
52     Options.OptLevel = Int_val(Field(OptRecord, 0));
53     Options.CodeModel = Int_val(Field(OptRecord, 1));
54     Options.NoFramePointerElim = Int_val(Field(OptRecord, 2));
55     Options.EnableFastISel = Int_val(Field(OptRecord, 3));
56     Options.MCJMM = NULL;
57   }
58 
59   if (LLVMCreateMCJITCompilerForModule(&MCJIT, Module_val(M), &Options,
60                                        sizeof(Options), &Error))
61     llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
62   return to_val(MCJIT);
63 }
64 
65 /* ExecutionEngine.t -> unit */
llvm_ee_dispose(value EE)66 value llvm_ee_dispose(value EE) {
67   LLVMDisposeExecutionEngine(ExecutionEngine_val(EE));
68   return Val_unit;
69 }
70 
71 /* llmodule -> ExecutionEngine.t -> unit */
llvm_ee_add_module(value M,value EE)72 value llvm_ee_add_module(value M, value EE) {
73   LLVMAddModule(ExecutionEngine_val(EE), Module_val(M));
74   return Val_unit;
75 }
76 
77 /* llmodule -> ExecutionEngine.t -> llmodule */
llvm_ee_remove_module(value M,value EE)78 value llvm_ee_remove_module(value M, value EE) {
79   LLVMModuleRef RemovedModule;
80   char *Error;
81   if (LLVMRemoveModule(ExecutionEngine_val(EE), Module_val(M), &RemovedModule,
82                        &Error))
83     llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
84   return Val_unit;
85 }
86 
87 /* ExecutionEngine.t -> unit */
llvm_ee_run_static_ctors(value EE)88 value llvm_ee_run_static_ctors(value EE) {
89   LLVMRunStaticConstructors(ExecutionEngine_val(EE));
90   return Val_unit;
91 }
92 
93 /* ExecutionEngine.t -> unit */
llvm_ee_run_static_dtors(value EE)94 value llvm_ee_run_static_dtors(value EE) {
95   LLVMRunStaticDestructors(ExecutionEngine_val(EE));
96   return Val_unit;
97 }
98 
99 extern value llvm_alloc_data_layout(LLVMTargetDataRef TargetData);
100 
101 /* ExecutionEngine.t -> Llvm_target.DataLayout.t */
llvm_ee_get_data_layout(value EE)102 value llvm_ee_get_data_layout(value EE) {
103   value DataLayout;
104   LLVMTargetDataRef OrigDataLayout;
105   char *TargetDataCStr;
106 
107   OrigDataLayout = LLVMGetExecutionEngineTargetData(ExecutionEngine_val(EE));
108   TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
109   DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
110   LLVMDisposeMessage(TargetDataCStr);
111 
112   return DataLayout;
113 }
114 
115 /* Llvm.llvalue -> int64 -> llexecutionengine -> unit */
llvm_ee_add_global_mapping(value Global,value Ptr,value EE)116 value llvm_ee_add_global_mapping(value Global, value Ptr, value EE) {
117   LLVMAddGlobalMapping(ExecutionEngine_val(EE), Value_val(Global),
118                        (void *)(Int64_val(Ptr)));
119   return Val_unit;
120 }
121 
llvm_ee_get_global_value_address(value Name,value EE)122 value llvm_ee_get_global_value_address(value Name, value EE) {
123   return caml_copy_int64((int64_t)LLVMGetGlobalValueAddress(
124       ExecutionEngine_val(EE), String_val(Name)));
125 }
126 
llvm_ee_get_function_address(value Name,value EE)127 value llvm_ee_get_function_address(value Name, value EE) {
128   return caml_copy_int64((int64_t)LLVMGetFunctionAddress(
129       ExecutionEngine_val(EE), String_val(Name)));
130 }
131