[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:
Peter Zotov
2014-10-25 18:49:56 +00:00
parent 71fe4f0197
commit 60d3f5918d
4 changed files with 142 additions and 53 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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;
()