mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-07 12:28:24 +00:00
[OCaml] Expose Llvm_executionengine.ExecutionEngine.create_mcjit.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220619 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -200,6 +200,24 @@ llvm_ee_create_jit(LLVMModuleRef M, value OptLevel) {
|
||||
return JIT;
|
||||
}
|
||||
|
||||
/* llmodule -> llcompileroption -> ExecutionEngine.t */
|
||||
CAMLprim LLVMExecutionEngineRef
|
||||
llvm_ee_create_mcjit(LLVMModuleRef M, value OptRecord) {
|
||||
LLVMExecutionEngineRef MCJIT;
|
||||
char *Error;
|
||||
struct LLVMMCJITCompilerOptions Options = {
|
||||
.OptLevel = Int_val(Field(OptRecord, 0)),
|
||||
.CodeModel = Int_val(Field(OptRecord, 1)),
|
||||
.NoFramePointerElim = Int_val(Field(OptRecord, 2)),
|
||||
.EnableFastISel = Int_val(Field(OptRecord, 3)),
|
||||
.MCJMM = NULL
|
||||
};
|
||||
if (LLVMCreateMCJITCompilerForModule(&MCJIT, M, &Options,
|
||||
sizeof(Options), &Error))
|
||||
llvm_raise(llvm_ee_error_exn, Error);
|
||||
return MCJIT;
|
||||
}
|
||||
|
||||
/* ExecutionEngine.t -> unit */
|
||||
CAMLprim value llvm_ee_dispose(LLVMExecutionEngineRef EE) {
|
||||
LLVMDisposeExecutionEngine(EE);
|
||||
|
@@ -14,6 +14,16 @@ external register_exns: exn -> unit
|
||||
= "llvm_register_ee_exns"
|
||||
|
||||
|
||||
module CodeModel = struct
|
||||
type t =
|
||||
| Default
|
||||
| JIT_default
|
||||
| Small
|
||||
| Kernel
|
||||
| Medium
|
||||
| Large
|
||||
end
|
||||
|
||||
module GenericValue = struct
|
||||
type t
|
||||
|
||||
@@ -48,6 +58,19 @@ end
|
||||
module ExecutionEngine = struct
|
||||
type t
|
||||
|
||||
type compileroptions = {
|
||||
opt_level: int;
|
||||
code_model: CodeModel.t;
|
||||
no_framepointer_elim: bool;
|
||||
enable_fast_isel: bool;
|
||||
}
|
||||
|
||||
let default_compiler_options = {
|
||||
opt_level = 0;
|
||||
code_model = CodeModel.JIT_default;
|
||||
no_framepointer_elim = false;
|
||||
enable_fast_isel = false }
|
||||
|
||||
(* FIXME: Ocaml is not running this setup code unless we use 'val' in the
|
||||
interface, which causes the emission of a stub for each function;
|
||||
using 'external' in the module allows direct calls into
|
||||
@@ -62,6 +85,8 @@ module ExecutionEngine = struct
|
||||
= "llvm_ee_create_interpreter"
|
||||
external create_jit: Llvm.llmodule -> int -> t
|
||||
= "llvm_ee_create_jit"
|
||||
external create_mcjit: Llvm.llmodule -> compileroptions -> t
|
||||
= "llvm_ee_create_mcjit"
|
||||
external dispose: t -> unit
|
||||
= "llvm_ee_dispose"
|
||||
external add_module: Llvm.llmodule -> t -> unit
|
||||
|
@@ -14,6 +14,17 @@
|
||||
|
||||
exception Error of string
|
||||
|
||||
(** The JIT code model. See [llvm::CodeModel::Model]. *)
|
||||
module CodeModel : sig
|
||||
type t =
|
||||
| Default
|
||||
| JIT_default
|
||||
| Small
|
||||
| Kernel
|
||||
| Medium
|
||||
| Large
|
||||
end
|
||||
|
||||
module GenericValue: sig
|
||||
(** [GenericValue.t] is a boxed union type used to portably pass arguments to
|
||||
and receive values from the execution engine. It supports only a limited
|
||||
@@ -85,6 +96,19 @@ module ExecutionEngine: sig
|
||||
invoking a static compiler and generating a native executable. *)
|
||||
type t
|
||||
|
||||
(** MCJIT compiler options. See [llvm::TargetOptions]. *)
|
||||
type compileroptions = {
|
||||
opt_level: int;
|
||||
code_model: CodeModel.t;
|
||||
no_framepointer_elim: bool;
|
||||
enable_fast_isel: bool;
|
||||
}
|
||||
|
||||
(** Default MCJIT compiler options:
|
||||
[{ opt_level = 0; code_model = CodeModel.JIT_default;
|
||||
no_framepointer_elim = false; enable_fast_isel = false }] *)
|
||||
val default_compiler_options : compileroptions
|
||||
|
||||
(** [create m] creates a new execution engine, taking ownership of the
|
||||
module [m] if successful. Creates a JIT if possible, else falls back to an
|
||||
interpreter. Raises [Error msg] if an error occurrs. The execution engine
|
||||
@@ -103,9 +127,18 @@ module ExecutionEngine: sig
|
||||
ownership of the module [m] if successful with the desired optimization
|
||||
level [optlevel]. Raises [Error msg] if an error occurrs. The execution
|
||||
engine is not garbage collected and must be destroyed with [dispose ee].
|
||||
See the function [llvm::EngineBuilder::create]. *)
|
||||
See the function [llvm::EngineBuilder::create].
|
||||
|
||||
Deprecated; use {!create_mcjit}. This function is a shim for {!create_mcjit}. *)
|
||||
val create_jit : Llvm.llmodule -> int -> t
|
||||
|
||||
(** [create_jit m optlevel] creates a new JIT (just-in-time compiler), taking
|
||||
ownership of the module [m] if successful with the desired optimization
|
||||
level [optlevel]. Raises [Error msg] if an error occurrs. The execution
|
||||
engine is not garbage collected and must be destroyed with [dispose ee].
|
||||
See the function [llvm::EngineBuilder::create]. *)
|
||||
val create_mcjit : Llvm.llmodule -> compileroptions -> t
|
||||
|
||||
(** [dispose ee] releases the memory used by the execution engine and must be
|
||||
invoked to avoid memory leaks. *)
|
||||
val dispose : t -> unit
|
||||
|
@@ -60,7 +60,7 @@ let test_genericvalue () =
|
||||
let i64gv = GenericValue.of_int64 i64_type (Int64.of_int 6) in
|
||||
assert ((Int64.of_int 6) = GenericValue.as_int64 i64gv)
|
||||
|
||||
let test_executionengine () =
|
||||
let test_executionengine engine =
|
||||
(* create *)
|
||||
let m = create_module (global_context ()) "test_module" in
|
||||
let main = define_main_fn m 42 in
|
||||
@@ -68,7 +68,12 @@ let test_executionengine () =
|
||||
let m2 = create_module (global_context ()) "test_module2" in
|
||||
define_plus m2;
|
||||
|
||||
let ee = ExecutionEngine.create m in
|
||||
let ee =
|
||||
match engine with
|
||||
| `Interpreter -> ExecutionEngine.create_interpreter m
|
||||
| `JIT -> ExecutionEngine.create_jit m 0
|
||||
| `MCJIT -> ExecutionEngine.create_mcjit m ExecutionEngine.default_compiler_options
|
||||
in
|
||||
ExecutionEngine.add_module m2 ee;
|
||||
|
||||
(* run_static_ctors *)
|
||||
@@ -90,12 +95,17 @@ let test_executionengine () =
|
||||
| None -> raise (Failure "find_function 'plus' failed")
|
||||
| Some plus ->
|
||||
|
||||
begin match engine with
|
||||
| `MCJIT -> () (* Currently can only invoke 0-ary functions *)
|
||||
| `JIT -> () (* JIT is now a shim around MCJIT, jokes on you *)
|
||||
| _ ->
|
||||
(* run_function *)
|
||||
let res = ExecutionEngine.run_function plus
|
||||
[| GenericValue.of_int i32_type 2;
|
||||
GenericValue.of_int i32_type 2 |]
|
||||
ee in
|
||||
if 4 != GenericValue.as_int res then bomb "plus did not work";
|
||||
end;
|
||||
|
||||
(* remove_module *)
|
||||
Llvm.dispose_module (ExecutionEngine.remove_module m2 ee);
|
||||
@@ -113,6 +123,9 @@ let test_executionengine () =
|
||||
(* dispose *)
|
||||
ExecutionEngine.dispose ee
|
||||
|
||||
let _ =
|
||||
let () =
|
||||
test_genericvalue ();
|
||||
test_executionengine ()
|
||||
test_executionengine `Interpreter;
|
||||
test_executionengine `JIT;
|
||||
test_executionengine `MCJIT;
|
||||
()
|
||||
|
Reference in New Issue
Block a user