Sylvestre Ledru | 493cd8c | 2013-11-01 00:26:01 +0000 | [diff] [blame] | 1 | /*===-- executionengine_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\ |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 2 | |* *| |
| 3 | |* The LLVM Compiler Infrastructure *| |
| 4 | |* *| |
Chris Lattner | 6787a45 | 2007-12-29 22:59:10 +0000 | [diff] [blame] | 5 | |* This file is distributed under the University of Illinois Open Source *| |
| 6 | |* License. See LICENSE.TXT for details. *| |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 7 | |* *| |
| 8 | |*===----------------------------------------------------------------------===*| |
| 9 | |* *| |
Sylvestre Ledru | 493cd8c | 2013-11-01 00:26:01 +0000 | [diff] [blame] | 10 | |* This file glues LLVM's OCaml interface to its C interface. These functions *| |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 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 | |
Peter Zotov | 662538a | 2014-10-29 08:15:54 +0000 | [diff] [blame] | 18 | #include <string.h> |
| 19 | #include <assert.h> |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 20 | #include "llvm-c/ExecutionEngine.h" |
Bob Wilson | a1d3e66 | 2009-06-24 21:09:18 +0000 | [diff] [blame] | 21 | #include "llvm-c/Target.h" |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 22 | #include "caml/alloc.h" |
| 23 | #include "caml/custom.h" |
| 24 | #include "caml/fail.h" |
| 25 | #include "caml/memory.h" |
Peter Zotov | 662538a | 2014-10-29 08:15:54 +0000 | [diff] [blame] | 26 | #include "caml/callback.h" |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 27 | |
Peter Zotov | 1b254f9 | 2014-10-30 08:29:29 +0000 | [diff] [blame] | 28 | void llvm_raise(value Prototype, char *Message); |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 29 | |
Peter Zotov | 662538a | 2014-10-29 08:15:54 +0000 | [diff] [blame] | 30 | /* unit -> bool */ |
Peter Zotov | b1f54ff | 2014-10-31 09:05:36 +0000 | [diff] [blame] | 31 | CAMLprim value llvm_ee_initialize(value Unit) { |
Peter Zotov | 662538a | 2014-10-29 08:15:54 +0000 | [diff] [blame] | 32 | LLVMLinkInMCJIT(); |
| 33 | |
| 34 | return Val_bool(!LLVMInitializeNativeTarget() && |
| 35 | !LLVMInitializeNativeAsmParser() && |
| 36 | !LLVMInitializeNativeAsmPrinter()); |
| 37 | } |
| 38 | |
Peter Zotov | d1531a2 | 2014-10-25 18:49:56 +0000 | [diff] [blame] | 39 | /* llmodule -> llcompileroption -> ExecutionEngine.t */ |
Peter Zotov | b1f54ff | 2014-10-31 09:05:36 +0000 | [diff] [blame] | 40 | CAMLprim LLVMExecutionEngineRef llvm_ee_create(value OptRecordOpt, LLVMModuleRef M) { |
| 41 | value OptRecord; |
Peter Zotov | d1531a2 | 2014-10-25 18:49:56 +0000 | [diff] [blame] | 42 | LLVMExecutionEngineRef MCJIT; |
| 43 | char *Error; |
Peter Zotov | 662538a | 2014-10-29 08:15:54 +0000 | [diff] [blame] | 44 | struct LLVMMCJITCompilerOptions Options; |
| 45 | |
| 46 | LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options)); |
Peter Zotov | b1f54ff | 2014-10-31 09:05:36 +0000 | [diff] [blame] | 47 | if (OptRecordOpt != Val_int(0)) { |
| 48 | OptRecord = Field(OptRecordOpt, 0); |
| 49 | Options.OptLevel = Int_val(Field(OptRecord, 0)); |
| 50 | Options.CodeModel = Int_val(Field(OptRecord, 1)); |
| 51 | Options.NoFramePointerElim = Int_val(Field(OptRecord, 2)); |
| 52 | Options.EnableFastISel = Int_val(Field(OptRecord, 3)); |
| 53 | Options.MCJMM = NULL; |
| 54 | } |
Peter Zotov | 662538a | 2014-10-29 08:15:54 +0000 | [diff] [blame] | 55 | |
Peter Zotov | d1531a2 | 2014-10-25 18:49:56 +0000 | [diff] [blame] | 56 | if (LLVMCreateMCJITCompilerForModule(&MCJIT, M, &Options, |
| 57 | sizeof(Options), &Error)) |
Peter Zotov | 662538a | 2014-10-29 08:15:54 +0000 | [diff] [blame] | 58 | llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error); |
Peter Zotov | d1531a2 | 2014-10-25 18:49:56 +0000 | [diff] [blame] | 59 | return MCJIT; |
| 60 | } |
| 61 | |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 62 | /* ExecutionEngine.t -> unit */ |
| 63 | CAMLprim value llvm_ee_dispose(LLVMExecutionEngineRef EE) { |
| 64 | LLVMDisposeExecutionEngine(EE); |
| 65 | return Val_unit; |
| 66 | } |
| 67 | |
Erick Tryzelaar | 98b05d6 | 2010-03-02 23:59:00 +0000 | [diff] [blame] | 68 | /* llmodule -> ExecutionEngine.t -> unit */ |
Erick Tryzelaar | 3e64c26 | 2010-03-03 23:51:30 +0000 | [diff] [blame] | 69 | CAMLprim value llvm_ee_add_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) { |
Erick Tryzelaar | 98b05d6 | 2010-03-02 23:59:00 +0000 | [diff] [blame] | 70 | LLVMAddModule(EE, M); |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 71 | return Val_unit; |
| 72 | } |
| 73 | |
Erick Tryzelaar | 98b05d6 | 2010-03-02 23:59:00 +0000 | [diff] [blame] | 74 | /* llmodule -> ExecutionEngine.t -> llmodule */ |
Peter Zotov | b1f54ff | 2014-10-31 09:05:36 +0000 | [diff] [blame] | 75 | CAMLprim value llvm_ee_remove_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) { |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 76 | LLVMModuleRef RemovedModule; |
| 77 | char *Error; |
Erick Tryzelaar | 98b05d6 | 2010-03-02 23:59:00 +0000 | [diff] [blame] | 78 | if (LLVMRemoveModule(EE, M, &RemovedModule, &Error)) |
Peter Zotov | 662538a | 2014-10-29 08:15:54 +0000 | [diff] [blame] | 79 | llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error); |
Peter Zotov | b1f54ff | 2014-10-31 09:05:36 +0000 | [diff] [blame] | 80 | return Val_unit; |
Gordon Henriksen | 2a8cd89 | 2007-12-23 16:59:28 +0000 | [diff] [blame] | 81 | } |
| 82 | |
| 83 | /* ExecutionEngine.t -> unit */ |
| 84 | CAMLprim value llvm_ee_run_static_ctors(LLVMExecutionEngineRef EE) { |
| 85 | LLVMRunStaticConstructors(EE); |
| 86 | return Val_unit; |
| 87 | } |
| 88 | |
| 89 | /* ExecutionEngine.t -> unit */ |
| 90 | CAMLprim value llvm_ee_run_static_dtors(LLVMExecutionEngineRef EE) { |
| 91 | LLVMRunStaticDestructors(EE); |
| 92 | return Val_unit; |
| 93 | } |
| 94 | |
Peter Zotov | 8a1a3bf | 2013-11-15 02:51:44 +0000 | [diff] [blame] | 95 | extern value llvm_alloc_data_layout(LLVMTargetDataRef TargetData); |
Peter Zotov | d52cf17 | 2013-11-11 14:47:11 +0000 | [diff] [blame] | 96 | |
Peter Zotov | 8a1a3bf | 2013-11-15 02:51:44 +0000 | [diff] [blame] | 97 | /* ExecutionEngine.t -> Llvm_target.DataLayout.t */ |
| 98 | CAMLprim value llvm_ee_get_data_layout(LLVMExecutionEngineRef EE) { |
| 99 | value DataLayout; |
| 100 | LLVMTargetDataRef OrigDataLayout; |
Peter Zotov | 8a1a3bf | 2013-11-15 02:51:44 +0000 | [diff] [blame] | 101 | char* TargetDataCStr; |
Peter Zotov | 662538a | 2014-10-29 08:15:54 +0000 | [diff] [blame] | 102 | |
| 103 | OrigDataLayout = LLVMGetExecutionEngineTargetData(EE); |
Peter Zotov | 8a1a3bf | 2013-11-15 02:51:44 +0000 | [diff] [blame] | 104 | TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout); |
| 105 | DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr)); |
| 106 | LLVMDisposeMessage(TargetDataCStr); |
| 107 | |
| 108 | return DataLayout; |
Peter Zotov | d52cf17 | 2013-11-11 14:47:11 +0000 | [diff] [blame] | 109 | } |
Peter Zotov | b1f54ff | 2014-10-31 09:05:36 +0000 | [diff] [blame] | 110 | |
| 111 | /* Llvm.llvalue -> int64 -> llexecutionengine -> unit */ |
| 112 | CAMLprim value llvm_ee_add_global_mapping(LLVMValueRef Global, value Ptr, |
| 113 | LLVMExecutionEngineRef EE) { |
| 114 | LLVMAddGlobalMapping(EE, Global, (void*) (Int64_val(Ptr))); |
| 115 | return Val_unit; |
| 116 | } |
| 117 | |
Peter Zotov | af6535b | 2014-12-24 01:52:51 +0000 | [diff] [blame^] | 118 | CAMLprim value llvm_ee_get_global_value_address(value Name, |
| 119 | LLVMExecutionEngineRef EE) { |
| 120 | return caml_copy_int64((int64_t) LLVMGetGlobalValueAddress(EE, String_val(Name))); |
| 121 | } |
| 122 | |
| 123 | CAMLprim value llvm_ee_get_function_address(value Name, |
| 124 | LLVMExecutionEngineRef EE) { |
| 125 | return caml_copy_int64((int64_t) LLVMGetFunctionAddress(EE, String_val(Name))); |
Peter Zotov | b1f54ff | 2014-10-31 09:05:36 +0000 | [diff] [blame] | 126 | } |