1493cd8c0SSylvestre Ledru /*===-- executionengine_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\
22a8cd89dSGordon Henriksen |* *|
32946cd70SChandler Carruth |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
42946cd70SChandler Carruth |* Exceptions. *|
52946cd70SChandler Carruth |* See https://llvm.org/LICENSE.txt for license information. *|
62946cd70SChandler Carruth |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
72a8cd89dSGordon Henriksen |* *|
82a8cd89dSGordon Henriksen |*===----------------------------------------------------------------------===*|
92a8cd89dSGordon Henriksen |* *|
10493cd8c0SSylvestre Ledru |* This file glues LLVM's OCaml interface to its C interface. These functions *|
112a8cd89dSGordon Henriksen |* are by and large transparent wrappers to the corresponding C functions. *|
122a8cd89dSGordon Henriksen |* *|
132a8cd89dSGordon Henriksen |* Note that these functions intentionally take liberties with the CAMLparamX *|
142a8cd89dSGordon Henriksen |* macros, since most of the parameters are not GC heap objects. *|
152a8cd89dSGordon Henriksen |* *|
162a8cd89dSGordon Henriksen \*===----------------------------------------------------------------------===*/
172a8cd89dSGordon Henriksen
18662538acSPeter Zotov #include <string.h>
19662538acSPeter Zotov #include <assert.h>
2052aadc8eSJeroen Ketema #include "llvm-c/Core.h"
212a8cd89dSGordon Henriksen #include "llvm-c/ExecutionEngine.h"
22a1d3e660SBob Wilson #include "llvm-c/Target.h"
232a8cd89dSGordon Henriksen #include "caml/alloc.h"
242a8cd89dSGordon Henriksen #include "caml/custom.h"
252a8cd89dSGordon Henriksen #include "caml/fail.h"
262a8cd89dSGordon Henriksen #include "caml/memory.h"
27662538acSPeter Zotov #include "caml/callback.h"
282a8cd89dSGordon Henriksen
291b254f9aSPeter Zotov void llvm_raise(value Prototype, char *Message);
302a8cd89dSGordon Henriksen
31662538acSPeter Zotov /* unit -> bool */
llvm_ee_initialize(value Unit)328e4fc55aSJosh Berdine value llvm_ee_initialize(value Unit) {
33662538acSPeter Zotov LLVMLinkInMCJIT();
34662538acSPeter Zotov
35662538acSPeter Zotov return Val_bool(!LLVMInitializeNativeTarget() &&
36662538acSPeter Zotov !LLVMInitializeNativeAsmParser() &&
37662538acSPeter Zotov !LLVMInitializeNativeAsmPrinter());
38662538acSPeter Zotov }
39662538acSPeter Zotov
40d1531a23SPeter Zotov /* llmodule -> llcompileroption -> ExecutionEngine.t */
llvm_ee_create(value OptRecordOpt,LLVMModuleRef M)418e4fc55aSJosh Berdine LLVMExecutionEngineRef llvm_ee_create(value OptRecordOpt, LLVMModuleRef M) {
42b1f54ff4SPeter Zotov value OptRecord;
43d1531a23SPeter Zotov LLVMExecutionEngineRef MCJIT;
44d1531a23SPeter Zotov char *Error;
45662538acSPeter Zotov struct LLVMMCJITCompilerOptions Options;
46662538acSPeter Zotov
47662538acSPeter Zotov LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
48b1f54ff4SPeter Zotov if (OptRecordOpt != Val_int(0)) {
49b1f54ff4SPeter Zotov OptRecord = Field(OptRecordOpt, 0);
50662538acSPeter Zotov Options.OptLevel = Int_val(Field(OptRecord, 0));
51662538acSPeter Zotov Options.CodeModel = Int_val(Field(OptRecord, 1));
52662538acSPeter Zotov Options.NoFramePointerElim = Int_val(Field(OptRecord, 2));
53662538acSPeter Zotov Options.EnableFastISel = Int_val(Field(OptRecord, 3));
54662538acSPeter Zotov Options.MCJMM = NULL;
55b1f54ff4SPeter Zotov }
56662538acSPeter Zotov
57*f4d156aeSJosh Berdine if (LLVMCreateMCJITCompilerForModule(&MCJIT, M, &Options, sizeof(Options),
58*f4d156aeSJosh Berdine &Error))
59662538acSPeter Zotov llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
60d1531a23SPeter Zotov return MCJIT;
61d1531a23SPeter Zotov }
62d1531a23SPeter Zotov
632a8cd89dSGordon Henriksen /* ExecutionEngine.t -> unit */
llvm_ee_dispose(LLVMExecutionEngineRef EE)648e4fc55aSJosh Berdine value llvm_ee_dispose(LLVMExecutionEngineRef EE) {
652a8cd89dSGordon Henriksen LLVMDisposeExecutionEngine(EE);
662a8cd89dSGordon Henriksen return Val_unit;
672a8cd89dSGordon Henriksen }
682a8cd89dSGordon Henriksen
6998b05d67SErick Tryzelaar /* llmodule -> ExecutionEngine.t -> unit */
llvm_ee_add_module(LLVMModuleRef M,LLVMExecutionEngineRef EE)708e4fc55aSJosh Berdine value llvm_ee_add_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
7198b05d67SErick Tryzelaar LLVMAddModule(EE, M);
722a8cd89dSGordon Henriksen return Val_unit;
732a8cd89dSGordon Henriksen }
742a8cd89dSGordon Henriksen
7598b05d67SErick Tryzelaar /* llmodule -> ExecutionEngine.t -> llmodule */
llvm_ee_remove_module(LLVMModuleRef M,LLVMExecutionEngineRef EE)768e4fc55aSJosh Berdine value llvm_ee_remove_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
772a8cd89dSGordon Henriksen LLVMModuleRef RemovedModule;
782a8cd89dSGordon Henriksen char *Error;
7998b05d67SErick Tryzelaar if (LLVMRemoveModule(EE, M, &RemovedModule, &Error))
80662538acSPeter Zotov llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
81b1f54ff4SPeter Zotov return Val_unit;
822a8cd89dSGordon Henriksen }
832a8cd89dSGordon Henriksen
842a8cd89dSGordon Henriksen /* ExecutionEngine.t -> unit */
llvm_ee_run_static_ctors(LLVMExecutionEngineRef EE)858e4fc55aSJosh Berdine value llvm_ee_run_static_ctors(LLVMExecutionEngineRef EE) {
862a8cd89dSGordon Henriksen LLVMRunStaticConstructors(EE);
872a8cd89dSGordon Henriksen return Val_unit;
882a8cd89dSGordon Henriksen }
892a8cd89dSGordon Henriksen
902a8cd89dSGordon Henriksen /* ExecutionEngine.t -> unit */
llvm_ee_run_static_dtors(LLVMExecutionEngineRef EE)918e4fc55aSJosh Berdine value llvm_ee_run_static_dtors(LLVMExecutionEngineRef EE) {
922a8cd89dSGordon Henriksen LLVMRunStaticDestructors(EE);
932a8cd89dSGordon Henriksen return Val_unit;
942a8cd89dSGordon Henriksen }
952a8cd89dSGordon Henriksen
968a1a3bfcSPeter Zotov extern value llvm_alloc_data_layout(LLVMTargetDataRef TargetData);
97d52cf175SPeter Zotov
988a1a3bfcSPeter Zotov /* ExecutionEngine.t -> Llvm_target.DataLayout.t */
llvm_ee_get_data_layout(LLVMExecutionEngineRef EE)998e4fc55aSJosh Berdine value llvm_ee_get_data_layout(LLVMExecutionEngineRef EE) {
1008a1a3bfcSPeter Zotov value DataLayout;
1018a1a3bfcSPeter Zotov LLVMTargetDataRef OrigDataLayout;
1028a1a3bfcSPeter Zotov char *TargetDataCStr;
103662538acSPeter Zotov
104662538acSPeter Zotov OrigDataLayout = LLVMGetExecutionEngineTargetData(EE);
1058a1a3bfcSPeter Zotov TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
1068a1a3bfcSPeter Zotov DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
1078a1a3bfcSPeter Zotov LLVMDisposeMessage(TargetDataCStr);
1088a1a3bfcSPeter Zotov
1098a1a3bfcSPeter Zotov return DataLayout;
110d52cf175SPeter Zotov }
111b1f54ff4SPeter Zotov
112b1f54ff4SPeter Zotov /* Llvm.llvalue -> int64 -> llexecutionengine -> unit */
llvm_ee_add_global_mapping(LLVMValueRef Global,value Ptr,LLVMExecutionEngineRef EE)1138e4fc55aSJosh Berdine value llvm_ee_add_global_mapping(LLVMValueRef Global, value Ptr,
114b1f54ff4SPeter Zotov LLVMExecutionEngineRef EE) {
115b1f54ff4SPeter Zotov LLVMAddGlobalMapping(EE, Global, (void *)(Int64_val(Ptr)));
116b1f54ff4SPeter Zotov return Val_unit;
117b1f54ff4SPeter Zotov }
118b1f54ff4SPeter Zotov
llvm_ee_get_global_value_address(value Name,LLVMExecutionEngineRef EE)119*f4d156aeSJosh Berdine value llvm_ee_get_global_value_address(value Name, LLVMExecutionEngineRef EE) {
120*f4d156aeSJosh Berdine return caml_copy_int64(
121*f4d156aeSJosh Berdine (int64_t)LLVMGetGlobalValueAddress(EE, String_val(Name)));
122af6535bfSPeter Zotov }
123af6535bfSPeter Zotov
llvm_ee_get_function_address(value Name,LLVMExecutionEngineRef EE)124*f4d156aeSJosh Berdine value llvm_ee_get_function_address(value Name, LLVMExecutionEngineRef EE) {
125af6535bfSPeter Zotov return caml_copy_int64((int64_t)LLVMGetFunctionAddress(EE, String_val(Name)));
126b1f54ff4SPeter Zotov }
127