Enable lazy Orc JIT feature (#732)

The feature is disabled by default, to enable it, please use
`cmake -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=1`
to build iwasm.
This commit is contained in:
Wenyong Huang 2021-09-07 11:39:57 +08:00 committed by GitHub
parent 7e60b8608e
commit 4b0d6083a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 535 additions and 6 deletions

View File

@ -83,6 +83,9 @@ endif ()
if (WAMR_BUILD_JIT EQUAL 1) if (WAMR_BUILD_JIT EQUAL 1)
if (WAMR_BUILD_AOT EQUAL 1) if (WAMR_BUILD_AOT EQUAL 1)
add_definitions("-DWASM_ENABLE_JIT=1") add_definitions("-DWASM_ENABLE_JIT=1")
if (WAMR_BUILD_LAZY_JIT EQUAL 1)
add_definitions("-DWASM_ENABLE_LAZY_JIT=1")
endif ()
if (NOT DEFINED LLVM_DIR) if (NOT DEFINED LLVM_DIR)
set (LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm") set (LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm")
set (LLVM_BUILD_ROOT "${LLVM_SRC_ROOT}/build") set (LLVM_BUILD_ROOT "${LLVM_SRC_ROOT}/build")
@ -122,6 +125,11 @@ else ()
endif () endif ()
if (WAMR_BUILD_JIT EQUAL 1) if (WAMR_BUILD_JIT EQUAL 1)
message (" WAMR JIT enabled") message (" WAMR JIT enabled")
if (WAMR_BUILD_LAZY_JIT EQUAL 1)
message (" WAMR LazyJIT enabled")
else ()
message (" WAMR LazyJIT disabled")
endif ()
else () else ()
message (" WAMR JIT disabled") message (" WAMR JIT disabled")
endif () endif ()

View File

@ -75,10 +75,17 @@
#define WASM_ENABLE_JIT 0 #define WASM_ENABLE_JIT 0
#endif #endif
#ifndef WASM_ENABLE_LAZY_JIT
#define WASM_ENABLE_LAZY_JIT 0
#endif
#if (WASM_ENABLE_AOT == 0) && (WASM_ENABLE_JIT != 0) #if (WASM_ENABLE_AOT == 0) && (WASM_ENABLE_JIT != 0)
/* JIT can only be enabled when AOT is enabled */ /* LazyJIT or MCJIT can only be enabled when AOT is enabled */
#undef WASM_ENABLE_JIT #undef WASM_ENABLE_JIT
#define WASM_ENABLE_JIT 0 #define WASM_ENABLE_JIT 0
#undef WASM_ENABLE_LAZY_JIT
#define WASM_ENABLE_LAZY_JIT 0
#endif #endif
#ifndef WASM_ENABLE_WAMR_COMPILER #ifndef WASM_ENABLE_WAMR_COMPILER

View File

@ -2535,6 +2535,13 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
char func_name[32]; char func_name[32];
AOTModule *module; AOTModule *module;
#if WASM_ENABLE_LAZY_JIT != 0
LLVMOrcThreadSafeModuleRef ts_module;
LLVMOrcJITDylibRef main_dylib;
LLVMErrorRef error;
LLVMOrcJITTargetAddress func_addr = 0;
#endif
/* Allocate memory for module */ /* Allocate memory for module */
if (!(module = if (!(module =
loader_malloc(sizeof(AOTModule), error_buf, error_buf_size))) { loader_malloc(sizeof(AOTModule), error_buf, error_buf_size))) {
@ -2597,6 +2604,47 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
goto fail2; goto fail2;
} }
#if WASM_ENABLE_LAZY_JIT != 0
bh_assert(comp_ctx->lazy_orcjit);
main_dylib = LLVMOrcLLLazyJITGetMainJITDylib(comp_ctx->lazy_orcjit);
if (!main_dylib) {
set_error_buf(error_buf, error_buf_size,
"failed to get dynmaic library reference");
goto fail3;
}
ts_module = LLVMOrcCreateNewThreadSafeModule(comp_ctx->module,
comp_ctx->ts_context);
if (!ts_module) {
set_error_buf(error_buf, error_buf_size,
"failed to create thread safe module");
goto fail3;
}
if ((error = LLVMOrcLLLazyJITAddLLVMIRModule(comp_ctx->lazy_orcjit,
main_dylib, ts_module))) {
/*
* If adding the ThreadSafeModule fails then we need to clean it up
* ourselves. If adding it succeeds the JIT will manage the memory.
*/
aot_handle_llvm_errmsg(error_buf, error_buf_size,
"failed to addIRModule: ", error);
goto fail4;
}
for (i = 0; i < comp_data->func_count; i++) {
snprintf(func_name, sizeof(func_name), "%s%d", AOT_FUNC_PREFIX, i);
if ((error = LLVMOrcLLLazyJITLookup(comp_ctx->lazy_orcjit,
&func_addr, func_name))) {
aot_handle_llvm_errmsg(error_buf, error_buf_size,
"cannot lookup: ", error);
goto fail3;
}
module->func_ptrs[i] = (void *)func_addr;
func_addr = 0;
}
#else
/* Resolve function addresses */ /* Resolve function addresses */
bh_assert(comp_ctx->exec_engine); bh_assert(comp_ctx->exec_engine);
for (i = 0; i < comp_data->func_count; i++) { for (i = 0; i < comp_data->func_count; i++) {
@ -2609,6 +2657,7 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
goto fail3; goto fail3;
} }
} }
#endif /* WASM_ENABLE_LAZY_JIT != 0 */
/* Allocation memory for function type indexes */ /* Allocation memory for function type indexes */
size = (uint64)module->func_count * sizeof(uint32); size = (uint64)module->func_count * sizeof(uint32);
@ -2662,6 +2711,11 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
return module; return module;
#if WASM_ENABLE_LAZY_JIT != 0
fail4:
LLVMOrcDisposeThreadSafeModule(ts_module);
#endif
fail3: fail3:
if (module->func_ptrs) if (module->func_ptrs)
wasm_runtime_free(module->func_ptrs); wasm_runtime_free(module->func_ptrs);

View File

@ -1207,13 +1207,174 @@ WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM); void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM);
#if WASM_ENABLE_LAZY_JIT != 0
void
aot_handle_llvm_errmsg(char *error_buf,
uint32 error_buf_size,
const char *string,
LLVMErrorRef error)
{
char *err_msg = LLVMGetErrorMessage(error);
if (error_buf != NULL) {
snprintf(error_buf, error_buf_size,
"%s: %s", string, err_msg);
}
LLVMDisposeErrorMessage(err_msg);
}
static bool
llvm_orcjit_create(AOTCompContext *comp_ctx)
{
char *err_msg = NULL;
char *cpu = NULL;
char *features = NULL;
char *llvm_triple = NULL;
char buf[128] = {0};
LLVMErrorRef error;
LLVMTargetRef llvm_targetref = NULL;
LLVMTargetMachineRef tm_opt = NULL;
LLVMTargetMachineRef tm_opt2 = NULL;
LLVMOrcLLLazyJITRef lazy_orcjit = NULL;
LLVMOrcJITTargetMachineBuilderRef tm_builder = NULL;
LLVMOrcLLLazyJITBuilderRef lazy_orcjit_builder = NULL;
#if LLVM_VERSION_MAJOR < 12
LLVMOrcJITDylibDefinitionGeneratorRef main_gen = NULL;
#else
LLVMOrcDefinitionGeneratorRef main_gen = NULL;
#endif
llvm_triple = LLVMGetDefaultTargetTriple();
if (llvm_triple == NULL) {
snprintf(buf, sizeof(buf), "failed to get default target triple.");
goto fail;
}
if (LLVMGetTargetFromTriple(llvm_triple, &llvm_targetref, &err_msg) != 0) {
snprintf(buf, sizeof(buf),
"failed to get target reference from triple %s.", err_msg);
LLVMDisposeMessage(err_msg);
goto fail;
}
if (!LLVMTargetHasJIT(llvm_targetref)) {
snprintf(buf, sizeof(buf), "unspported JIT on this platform.");
goto fail;
}
cpu = LLVMGetHostCPUName();
if (cpu == NULL) {
snprintf(buf, sizeof(buf), "failed to get host cpu information.");
goto fail;
}
features = LLVMGetHostCPUFeatures();
if (features == NULL) {
snprintf(buf, sizeof(buf), "failed to get host cpu features.");
goto fail;
}
LOG_VERBOSE("LLVM ORCJIT detected CPU \"%s\", with features \"%s\"\n",
cpu, features);
tm_opt = LLVMCreateTargetMachine(llvm_targetref, llvm_triple,
cpu, features,
LLVMCodeGenLevelAggressive,
LLVMRelocDefault,
LLVMCodeModelJITDefault);
if (!tm_opt) {
snprintf(buf, sizeof(buf), "failed to create target machine.");
goto fail;
}
tm_opt2 = LLVMCreateTargetMachine(llvm_targetref, llvm_triple,
cpu, features,
LLVMCodeGenLevelAggressive,
LLVMRelocDefault,
LLVMCodeModelJITDefault);
if (!tm_opt2) {
snprintf(buf, sizeof(buf), "failed to create target machine2.");
goto fail;
}
/* if success, it will dispose tm_opt2 memory. */
tm_builder = LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(tm_opt2);
if (!tm_builder) {
snprintf(buf, sizeof(buf), "failed to create target machine builder.");
goto fail;
}
tm_opt2 = NULL;
lazy_orcjit_builder = LLVMOrcCreateLLLazyJITBuilder();
if (!lazy_orcjit_builder) {
snprintf(buf, sizeof(buf), "failed to create lazy jit builder.");
goto fail;
}
LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder(lazy_orcjit_builder,
tm_builder);
/* if success, it will dispose lazy_orcjit_builder memory */
error = LLVMOrcCreateLLLazyJIT(&lazy_orcjit, lazy_orcjit_builder);
if (error) {
aot_handle_llvm_errmsg(buf, sizeof(buf),
"failed to create llvm lazy orcjit instance",
error);
goto fail;
}
lazy_orcjit_builder = NULL;
error = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
&main_gen, LLVMOrcLLLazyJITGetGlobalPrefix(lazy_orcjit),
0, NULL);
if (error) {
aot_handle_llvm_errmsg(buf, sizeof(buf),
"failed to create dynmaic library search generator", error);
goto fail;
}
LLVMOrcJITDylibAddGenerator(LLVMOrcLLLazyJITGetMainJITDylib(lazy_orcjit),
main_gen);
comp_ctx->lazy_orcjit = lazy_orcjit;
comp_ctx->target_machine = tm_opt;
comp_ctx->tm_builder = tm_builder;
LLVMDisposeMessage(llvm_triple);
LLVMDisposeMessage(cpu);
LLVMDisposeMessage(features);
return true;
fail:
if (lazy_orcjit)
LLVMOrcDisposeLLLazyJIT(lazy_orcjit);
if (tm_builder)
LLVMOrcDisposeJITTargetMachineBuilder(tm_builder);
if (lazy_orcjit_builder)
LLVMOrcDisposeLLLazyJITBuilder(lazy_orcjit_builder);
if (tm_opt2)
LLVMDisposeTargetMachine(tm_opt2);
if (tm_opt)
LLVMDisposeTargetMachine(tm_opt);
if (features)
LLVMDisposeMessage(features);
if (cpu)
LLVMDisposeMessage(cpu);
if (llvm_triple)
LLVMDisposeMessage(llvm_triple);
aot_set_last_error(buf);
return false;
}
#endif /* WASM_ENABLE_LAZY_JIT != 0 */
AOTCompContext * AOTCompContext *
aot_create_comp_context(AOTCompData *comp_data, aot_create_comp_context(AOTCompData *comp_data,
aot_comp_option_t option) aot_comp_option_t option)
{ {
AOTCompContext *comp_ctx, *ret = NULL; AOTCompContext *comp_ctx, *ret = NULL;
/*LLVMTypeRef elem_types[8];*/ #if WASM_ENABLE_LAZY_JIT == 0
struct LLVMMCJITCompilerOptions jit_options; struct LLVMMCJITCompilerOptions jit_options;
#endif
LLVMTargetRef target; LLVMTargetRef target;
char *triple = NULL, *triple_norm, *arch, *abi; char *triple = NULL, *triple_norm, *arch, *abi;
char *cpu = NULL, *features, buf[128]; char *cpu = NULL, *features, buf[128];
@ -1225,11 +1386,18 @@ aot_create_comp_context(AOTCompData *comp_data,
LLVMTargetDataRef target_data_ref; LLVMTargetDataRef target_data_ref;
/* Initialize LLVM environment */ /* Initialize LLVM environment */
#if WASM_ENABLE_LAZY_JIT != 0
LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
#else
LLVMInitializeAllTargetInfos(); LLVMInitializeAllTargetInfos();
LLVMInitializeAllTargets(); LLVMInitializeAllTargets();
LLVMInitializeAllTargetMCs(); LLVMInitializeAllTargetMCs();
LLVMInitializeAllAsmPrinters(); LLVMInitializeAllAsmPrinters();
LLVMLinkInMCJIT(); LLVMLinkInMCJIT();
#endif
/* Allocate memory */ /* Allocate memory */
if (!(comp_ctx = wasm_runtime_malloc(sizeof(AOTCompContext)))) { if (!(comp_ctx = wasm_runtime_malloc(sizeof(AOTCompContext)))) {
@ -1241,10 +1409,24 @@ aot_create_comp_context(AOTCompData *comp_data,
comp_ctx->comp_data = comp_data; comp_ctx->comp_data = comp_data;
/* Create LLVM context, module and builder */ /* Create LLVM context, module and builder */
#if WASM_ENABLE_LAZY_JIT != 0
comp_ctx->ts_context = LLVMOrcCreateNewThreadSafeContext();
if (!comp_ctx->ts_context) {
aot_set_last_error("create LLVM ThreadSafeContext failed.");
return NULL;
}
/* Get a reference to the underlying LLVMContext */
if (!(comp_ctx->context =
LLVMOrcThreadSafeContextGetContext(comp_ctx->ts_context))) {
aot_set_last_error("get context from LLVM ThreadSafeContext failed.");
goto fail;
}
#else
if (!(comp_ctx->context = LLVMContextCreate())) { if (!(comp_ctx->context = LLVMContextCreate())) {
aot_set_last_error("create LLVM context failed."); aot_set_last_error("create LLVM context failed.");
goto fail; goto fail;
} }
#endif
if (!(comp_ctx->builder = LLVMCreateBuilderInContext(comp_ctx->context))) { if (!(comp_ctx->builder = LLVMCreateBuilderInContext(comp_ctx->context))) {
aot_set_last_error("create LLVM builder failed."); aot_set_last_error("create LLVM builder failed.");
@ -1288,6 +1470,14 @@ aot_create_comp_context(AOTCompData *comp_data,
if (option->is_jit_mode) { if (option->is_jit_mode) {
char *triple_jit = NULL; char *triple_jit = NULL;
#if WASM_ENABLE_LAZY_JIT != 0
/* Create LLLazyJIT Instance */
if (!llvm_orcjit_create(comp_ctx)) {
aot_set_last_error("create LLVM Lazy JIT Compiler failed.");
goto fail;
}
#else
/* Create LLVM execution engine */ /* Create LLVM execution engine */
LLVMInitializeMCJITCompilerOptions(&jit_options, sizeof(jit_options)); LLVMInitializeMCJITCompilerOptions(&jit_options, sizeof(jit_options));
jit_options.OptLevel = LLVMCodeGenLevelAggressive; jit_options.OptLevel = LLVMCodeGenLevelAggressive;
@ -1303,15 +1493,28 @@ aot_create_comp_context(AOTCompData *comp_data,
aot_set_last_error("create LLVM JIT compiler failed."); aot_set_last_error("create LLVM JIT compiler failed.");
goto fail; goto fail;
} }
comp_ctx->is_jit_mode = true;
comp_ctx->target_machine = comp_ctx->target_machine =
LLVMGetExecutionEngineTargetMachine(comp_ctx->exec_engine); LLVMGetExecutionEngineTargetMachine(comp_ctx->exec_engine);
#endif
comp_ctx->is_jit_mode = true;
#ifndef OS_ENABLE_HW_BOUND_CHECK #ifndef OS_ENABLE_HW_BOUND_CHECK
comp_ctx->enable_bound_check = true; comp_ctx->enable_bound_check = true;
#else #else
comp_ctx->enable_bound_check = false; comp_ctx->enable_bound_check = false;
#endif #endif
#if WASM_ENABLE_LAZY_JIT != 0
if (!(triple_jit =
(char *)LLVMOrcLLLazyJITGetTripleString(comp_ctx->lazy_orcjit))) {
aot_set_last_error("can not get triple from the target machine");
goto fail;
}
/* Save target arch */
get_target_arch_from_triple(triple_jit, comp_ctx->target_arch,
sizeof(comp_ctx->target_arch));
#else
if (!(triple_jit = if (!(triple_jit =
LLVMGetTargetMachineTriple(comp_ctx->target_machine))) { LLVMGetTargetMachineTriple(comp_ctx->target_machine))) {
aot_set_last_error("can not get triple from the target machine"); aot_set_last_error("can not get triple from the target machine");
@ -1322,6 +1525,7 @@ aot_create_comp_context(AOTCompData *comp_data,
get_target_arch_from_triple(triple_jit, comp_ctx->target_arch, get_target_arch_from_triple(triple_jit, comp_ctx->target_arch,
sizeof(comp_ctx->target_arch)); sizeof(comp_ctx->target_arch));
LLVMDisposeMessage(triple_jit); LLVMDisposeMessage(triple_jit);
#endif
} }
else { else {
/* Create LLVM target machine */ /* Create LLVM target machine */
@ -1706,9 +1910,29 @@ aot_destroy_comp_context(AOTCompContext *comp_ctx)
if (!comp_ctx) if (!comp_ctx)
return; return;
if (comp_ctx->pass_mgr) if (comp_ctx->pass_mgr) {
LLVMFinalizeFunctionPassManager(comp_ctx->pass_mgr);
LLVMDisposePassManager(comp_ctx->pass_mgr); LLVMDisposePassManager(comp_ctx->pass_mgr);
}
#if WASM_ENABLE_LAZY_JIT != 0
if (comp_ctx->target_machine && comp_ctx->is_jit_mode)
LLVMDisposeTargetMachine(comp_ctx->target_machine);
if (comp_ctx->builder)
LLVMDisposeBuilder(comp_ctx->builder);
if (comp_ctx->lazy_orcjit)
LLVMOrcDisposeLLLazyJIT(comp_ctx->lazy_orcjit);
if (comp_ctx->ts_context)
LLVMOrcDisposeThreadSafeContext(comp_ctx->ts_context);
if (comp_ctx->tm_builder)
LLVMOrcDisposeJITTargetMachineBuilder(comp_ctx->tm_builder);
LLVMShutdown();
#else
if (comp_ctx->target_machine && !comp_ctx->is_jit_mode) if (comp_ctx->target_machine && !comp_ctx->is_jit_mode)
LLVMDisposeTargetMachine(comp_ctx->target_machine); LLVMDisposeTargetMachine(comp_ctx->target_machine);
@ -1725,6 +1949,7 @@ aot_destroy_comp_context(AOTCompContext *comp_ctx)
if (comp_ctx->context) if (comp_ctx->context)
LLVMContextDispose(comp_ctx->context); LLVMContextDispose(comp_ctx->context);
#endif
if (comp_ctx->func_ctxes) if (comp_ctx->func_ctxes)
aot_destroy_func_contexts(comp_ctx->func_ctxes, aot_destroy_func_contexts(comp_ctx->func_ctxes,

View File

@ -18,6 +18,14 @@
#include "llvm-c/Transforms/Scalar.h" #include "llvm-c/Transforms/Scalar.h"
#include "llvm-c/Transforms/Vectorize.h" #include "llvm-c/Transforms/Vectorize.h"
#if WASM_ENABLE_LAZY_JIT != 0
#include "aot_llvm_lazyjit.h"
#include "llvm-c/Orc.h"
#include "llvm-c/Error.h"
#include "llvm-c/Initialization.h"
#include "llvm-c/Support.h"
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -227,7 +235,13 @@ typedef struct AOTCompContext {
uint64 flags[8]; uint64 flags[8];
/* LLVM execution engine required by JIT */ /* LLVM execution engine required by JIT */
#if WASM_ENABLE_LAZY_JIT != 0
LLVMOrcLLLazyJITRef lazy_orcjit;
LLVMOrcThreadSafeContextRef ts_context;
LLVMOrcJITTargetMachineBuilderRef tm_builder;
#else
LLVMExecutionEngineRef exec_engine; LLVMExecutionEngineRef exec_engine;
#endif
bool is_jit_mode; bool is_jit_mode;
/* AOT indirect mode flag & symbol list */ /* AOT indirect mode flag & symbol list */
@ -403,6 +417,14 @@ aot_get_func_from_table(const AOTCompContext *comp_ctx,
bool bool
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str); aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
#if WASM_ENABLE_LAZY_JIT != 0
void
aot_handle_llvm_errmsg(char *error_buf,
uint32 error_buf_size,
const char *string,
LLVMErrorRef error);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #endif

View File

@ -0,0 +1,128 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "aot_llvm_lazyjit.h"
LLVMOrcJITTargetMachineBuilderRef
LLVMOrcJITTargetMachineBuilderFromTargetMachine(LLVMTargetMachineRef TM);
LLVMOrcLLJITBuilderRef
LLVMOrcCreateLLJITBuilder(void);
void
LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder);
LLVMErrorRef
LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
LLVMOrcLLJITBuilderRef Builder);
LLVMErrorRef
LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J);
LLVMOrcJITDylibRef
LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J);
const char *
LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J);
char
LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J);
LLVMErrorRef
LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
LLVMOrcJITDylibRef JD,
LLVMOrcThreadSafeModuleRef TSM);
LLVMErrorRef
LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
LLVMOrcJITTargetAddress *Result,
const char *Name);
const char *
LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J);
void
LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
LLVMOrcLLJITBuilderRef Builder,
LLVMOrcJITTargetMachineBuilderRef JTMB);
char
LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J);
#if LLVM_VERSION_MAJOR < 12
LLVMOrcJITTargetMachineBuilderRef
LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM)
{
return LLVMOrcJITTargetMachineBuilderFromTargetMachine(TM);
}
#endif
LLVMOrcJITDylibRef
LLVMOrcLLLazyJITGetMainJITDylib(LLVMOrcLLLazyJITRef J)
{
return LLVMOrcLLJITGetMainJITDylib(J);
}
LLVMOrcLLLazyJITBuilderRef
LLVMOrcCreateLLLazyJITBuilder(void)
{
return LLVMOrcCreateLLJITBuilder();
}
void
LLVMOrcDisposeLLLazyJITBuilder(LLVMOrcLLLazyJITBuilderRef Builder)
{
return LLVMOrcDisposeLLJITBuilder(Builder);
}
LLVMErrorRef
LLVMOrcCreateLLLazyJIT(LLVMOrcLLLazyJITRef *Result,
LLVMOrcLLLazyJITBuilderRef Builder)
{
return LLVMOrcCreateLLJIT(Result, Builder);
}
LLVMErrorRef
LLVMOrcDisposeLLLazyJIT(LLVMOrcLLLazyJITRef J)
{
return LLVMOrcDisposeLLJIT(J);
}
LLVMErrorRef
LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J,
LLVMOrcJITDylibRef JD,
LLVMOrcThreadSafeModuleRef TSM)
{
return LLVMOrcLLJITAddLLVMIRModule(J, JD, TSM);
}
LLVMErrorRef
LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J,
LLVMOrcJITTargetAddress *Result,
const char *Name)
{
return LLVMOrcLLJITLookup(J, Result, Name);
}
const char *
LLVMOrcLLLazyJITGetTripleString(LLVMOrcLLLazyJITRef J)
{
return LLVMOrcLLJITGetTripleString(J);
}
void
LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder(
LLVMOrcLLLazyJITBuilderRef Builder,
LLVMOrcJITTargetMachineBuilderRef JTMB)
{
return LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(Builder, JTMB);
}
char
LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J)
{
return LLVMOrcLLJITGetGlobalPrefix(J);
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef AOT_LLVM_LAZYJIT_H
#define AOT_LLVM_LAZYJIT_H
#include "llvm-c/Error.h"
#include "llvm-c/Orc.h"
#include "llvm-c/TargetMachine.h"
#include "llvm-c/Types.h"
#if LLVM_VERSION_MAJOR >= 12
#include "llvm-c/LLJIT.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef LLVMOrcLLJITBuilderRef LLVMOrcLLLazyJITBuilderRef;
typedef LLVMOrcLLJITRef LLVMOrcLLLazyJITRef;
LLVMOrcJITTargetMachineBuilderRef
LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM);
LLVMOrcLLLazyJITBuilderRef
LLVMOrcCreateLLLazyJITBuilder(void);
void
LLVMOrcDisposeLLLazyJITBuilder(LLVMOrcLLLazyJITBuilderRef Builder);
LLVMErrorRef
LLVMOrcCreateLLLazyJIT(LLVMOrcLLLazyJITRef *Result,
LLVMOrcLLLazyJITBuilderRef Builder);
LLVMErrorRef
LLVMOrcDisposeLLLazyJIT(LLVMOrcLLLazyJITRef J);
LLVMOrcJITDylibRef
LLVMOrcLLLazyJITGetMainJITDylib(LLVMOrcLLLazyJITRef J);
const char *
LLVMOrcLLLazyJITGetTripleString(LLVMOrcLLLazyJITRef J);
char
LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J);
LLVMErrorRef
LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J,
LLVMOrcJITDylibRef JD,
LLVMOrcThreadSafeModuleRef TSM);
LLVMErrorRef
LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J,
LLVMOrcJITTargetAddress *Result,
const char *Name);
const char *
LLVMOrcLLLazyJITGetTripleString(LLVMOrcLLLazyJITRef J);
void
LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder(
LLVMOrcLLLazyJITBuilderRef Builder,
LLVMOrcJITTargetMachineBuilderRef JTMB);
char
LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J);
#ifdef __cplusplus
}
#endif
#endif /* end of AOT_LLVM_LAZYJIT_H */

View File

@ -41,6 +41,7 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM
- **WAMR_BUILD_AOT**=1/0, default to enable if not set - **WAMR_BUILD_AOT**=1/0, default to enable if not set
- **WAMR_BUILD_JIT**=1/0, default to disable if not set - **WAMR_BUILD_JIT**=1/0, default to disable if not set
- **WAMR_BUILD_LAZY_JIT**=1/0, default to disable if not set
#### **Configure LIBC** #### **Configure LIBC**
@ -198,8 +199,8 @@ make
``` ```
By default in Linux, the interpreter, AOT and WASI are enabled, and JIT is disabled. And the build target is By default in Linux, the interpreter, AOT and WASI are enabled, and JIT and LazyJIT are disabled.
set to X86_64 or X86_32 depending on the platform's bitwidth. And the build target is set to X86_64 or X86_32 depending on the platform's bitwidth.
To enable WASM JIT, firstly we should build LLVM: To enable WASM JIT, firstly we should build LLVM:
@ -217,6 +218,11 @@ cmake .. -DWAMR_BUILD_JIT=1
make make
``` ```
Moreover, pass arguments `-DWAMR_BUILD_JIT=1` and `-DWAMR_BUILD_LAZY_JIT=1` together to cmake to enable WASM Lazy JIT.
If Lazy JIT is enabled, then jit function bodies in the module will not be compiled until they are first called,
so compile time reduces significantly.
Linux SGX (Intel Software Guard Extension) Linux SGX (Intel Software Guard Extension)
------------------------- -------------------------

View File

@ -5,6 +5,8 @@
rm -fr build && mkdir build rm -fr build && mkdir build
cd build cd build
# Build With LazyJIT
# cmake .. -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=1
cmake .. -DWAMR_BUILD_JIT=1 cmake .. -DWAMR_BUILD_JIT=1
make make
cd .. cd ..