Skip to content

Commit

Permalink
Generate jitdump to support linux perf for LLVM JIT (bytecodealliance…
Browse files Browse the repository at this point in the history
  • Loading branch information
lum1n0us authored Nov 27, 2023
1 parent d760869 commit 8aa813f
Show file tree
Hide file tree
Showing 14 changed files with 165 additions and 14 deletions.
8 changes: 4 additions & 4 deletions build-scripts/build_llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ def build_llvm(llvm_dir, platform, backends, projects, use_clang=False, extra_fl
"-DLLVM_INCLUDE_EXAMPLES:BOOL=OFF",
"-DLLVM_INCLUDE_UTILS:BOOL=OFF",
"-DLLVM_INCLUDE_TESTS:BOOL=OFF",
"-DLLVM_BUILD_TESTS:BOOL=OFF",
"-DLLVM_OPTIMIZED_TABLEGEN:BOOL=ON",
"-DLLVM_USE_PERF:BOOL=ON",
]

# use clang/clang++/lld. but macos doesn't support lld
Expand Down Expand Up @@ -255,7 +255,7 @@ def main():
"branch": "release/15.x",
},
"xtensa": {
"repo": "https://github.com/espressif/llvm-project.git",
"repo": "https://github.com/espressif/llvm-project.git",
"repo_ssh": "git@github.com:espressif/llvm-project.git",
"branch": "xtensa_release_15.x",
},
Expand All @@ -281,13 +281,13 @@ def main():
commit_hash = query_llvm_version(llvm_info)
print(commit_hash)
return commit_hash is not None

repo_addr = llvm_info["repo"]
if os.environ.get('USE_GIT_SSH') == "true":
repo_addr = llvm_info["repo_ssh"]
else:
print("To use ssh for git clone, run: export USE_GIT_SSH=true")

llvm_dir = clone_llvm(deps_dir, repo_addr, llvm_info["branch"])
if (
build_llvm(
Expand Down
7 changes: 6 additions & 1 deletion core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ static JitCompOptions jit_options = { 0 };
#endif

#if WASM_ENABLE_JIT != 0
static LLVMJITOptions llvm_jit_options = { 3, 3, 0 };
static LLVMJITOptions llvm_jit_options = { 3, 3, 0, false };
#endif

static RunningMode runtime_running_mode = Mode_Default;
Expand Down Expand Up @@ -662,9 +662,14 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
#endif

#if WASM_ENABLE_JIT != 0
LOG_DEBUG("Start LLVM_JIT, opt_sz=%u, opt_lvl=%u, segue=%s, linux_perf=%s",
init_args->llvm_jit_size_level, init_args->llvm_jit_opt_level,
init_args->segue_flags ? "Yes" : "No",
init_args->linux_perf_support ? "Yes" : "No");
llvm_jit_options.size_level = init_args->llvm_jit_size_level;
llvm_jit_options.opt_level = init_args->llvm_jit_opt_level;
llvm_jit_options.segue_flags = init_args->segue_flags;
llvm_jit_options.linux_perf_support = init_args->linux_perf_support;
#endif

if (!wasm_runtime_env_init()) {
Expand Down
1 change: 1 addition & 0 deletions core/iwasm/common/wasm_runtime_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ typedef struct LLVMJITOptions {
uint32 opt_level;
uint32 size_level;
uint32 segue_flags;
bool linux_perf_support;
} LLVMJITOptions;
#endif

Expand Down
36 changes: 34 additions & 2 deletions core/iwasm/compilation/aot_llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,19 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
attr_no_jump_tables);
}

/* spread fp.all to every function */
if (comp_ctx->emit_frame_pointer) {
const char *key = "frame-pointer";
const char *val = "all";
LLVMAttributeRef no_omit_fp = LLVMCreateStringAttribute(
comp_ctx->context, key, strlen(key), val, strlen(val));
if (!no_omit_fp) {
aot_set_last_error("create LLVM attribute (frame-pointer) failed.");
goto fail;
}
LLVMAddAttributeAtIndex(func, LLVMAttributeFunctionIndex, no_omit_fp);
}

if (need_precheck) {
if (!comp_ctx->is_jit_mode)
LLVMSetLinkage(func, LLVMInternalLinkage);
Expand Down Expand Up @@ -2160,7 +2173,7 @@ jit_stack_size_callback(void *user_data, const char *name, size_t namelen,
}

static bool
orc_jit_create(AOTCompContext *comp_ctx)
orc_jit_create(AOTCompContext *comp_ctx, bool linux_perf_support)
{
LLVMErrorRef err;
LLVMOrcLLLazyJITRef orc_jit = NULL;
Expand Down Expand Up @@ -2200,6 +2213,14 @@ orc_jit_create(AOTCompContext *comp_ctx)
/* Ownership transfer: LLVMOrcLLJITBuilderRef -> LLVMOrcLLJITRef */
builder = NULL;

if (linux_perf_support) {
LOG_DEBUG("Enable linux perf support");
LLVMOrcObjectLayerRef obj_linking_layer =
(LLVMOrcObjectLayerRef)LLVMOrcLLLazyJITGetObjLinkingLayer(orc_jit);
LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(
obj_linking_layer, LLVMCreatePerfJITEventListener());
}

/* Ownership transfer: local -> AOTCompContext */
comp_ctx->orc_jit = orc_jit;
orc_jit = NULL;
Expand Down Expand Up @@ -2298,6 +2319,17 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
goto fail;
}

if (option->linux_perf_support) {
/* FramePointerKind.All */
LLVMMetadataRef val =
LLVMValueAsMetadata(LLVMConstInt(LLVMInt32Type(), 2, false));
const char *key = "frame-pointer";
LLVMAddModuleFlag(comp_ctx->module, LLVMModuleFlagBehaviorWarning, key,
strlen(key), val);

comp_ctx->emit_frame_pointer = true;
}

if (BH_LIST_ERROR == bh_list_init(&comp_ctx->native_symbols)) {
goto fail;
}
Expand Down Expand Up @@ -2401,7 +2433,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
goto fail;

/* Create LLJIT Instance */
if (!orc_jit_create(comp_ctx))
if (!orc_jit_create(comp_ctx, option->linux_perf_support))
goto fail;
}
else {
Expand Down
5 changes: 5 additions & 0 deletions core/iwasm/compilation/aot_llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "llvm-c/Target.h"
#include "llvm-c/Core.h"
#include "llvm-c/Object.h"
#include "llvm-c/OrcEE.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm-c/Analysis.h"
#include "llvm-c/BitWriter.h"
Expand Down Expand Up @@ -422,6 +423,8 @@ typedef struct AOTCompContext {
char stack_usage_temp_file[64];
const char *llvm_passes;
const char *builtin_intrinsics;

bool emit_frame_pointer;
} AOTCompContext;

enum {
Expand All @@ -431,6 +434,7 @@ enum {
AOT_LLVMIR_OPT_FILE,
};

/* always sync it with AOTCompOption in aot_export.h */
typedef struct AOTCompOption {
bool is_jit_mode;
bool is_indirect_mode;
Expand All @@ -457,6 +461,7 @@ typedef struct AOTCompOption {
uint32 bounds_checks;
uint32 stack_bounds_checks;
uint32 segue_flags;
bool linux_perf_support;
char **custom_sections;
uint32 custom_sections_count;
const char *stack_usage_file;
Expand Down
11 changes: 10 additions & 1 deletion core/iwasm/compilation/aot_orc_extra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#endif
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/Support/CBindingWrapping.h"

Expand Down Expand Up @@ -108,6 +110,7 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectTransformLayer,
LLVMOrcObjectTransformLayerRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry,
LLVMOrcSymbolStringPoolEntryRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectLayer, LLVMOrcObjectLayerRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef)

Expand Down Expand Up @@ -322,3 +325,9 @@ LLVMOrcLLLazyJITGetObjTransformLayer(LLVMOrcLLLazyJITRef J)
{
return wrap(&unwrap(J)->getObjTransformLayer());
}

LLVMOrcObjectLayerRef
LLVMOrcLLLazyJITGetObjLinkingLayer(LLVMOrcLLLazyJITRef J)
{
return wrap(&unwrap(J)->getObjLinkingLayer());
}
3 changes: 3 additions & 0 deletions core/iwasm/compilation/aot_orc_extra.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,8 @@ LLVMOrcLLJITBuilderSetCompileFuncitonCreatorWithStackSizesCallback(
LLVMOrcLLLazyJITBuilderRef Builder,
void (*cb)(void *, const char *, size_t, size_t), void *cb_data);

LLVMOrcObjectLayerRef
LLVMOrcLLLazyJITGetObjLinkingLayer(LLVMOrcLLLazyJITRef J);

LLVM_C_EXTERN_C_END
#endif
1 change: 1 addition & 0 deletions core/iwasm/fast-jit/jit_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ typedef struct JitInterpSwitchInfo {
typedef struct JitCompOptions {
uint32 code_cache_size;
uint32 opt_level;
bool linux_perf_support;
} JitCompOptions;

bool
Expand Down
2 changes: 2 additions & 0 deletions core/iwasm/include/aot_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ enum {
AOT_LLVMIR_OPT_FILE,
};

/* always sync it with AOTCompOption in compilation/aot_llvm.h */
typedef struct AOTCompOption {
bool is_jit_mode;
bool is_indirect_mode;
Expand All @@ -64,6 +65,7 @@ typedef struct AOTCompOption {
uint32_t bounds_checks;
uint32_t stack_bounds_checks;
uint32_t segue_flags;
bool linux_perf_support;
char **custom_sections;
uint32_t custom_sections_count;
const char *stack_usage_file;
Expand Down
14 changes: 11 additions & 3 deletions core/iwasm/include/wasm_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ typedef struct RuntimeInitArgs {
uint32_t llvm_jit_size_level;
/* Segue optimization flags for LLVM JIT */
uint32_t segue_flags;
/**
* If enabled
* - llvm-jit will output a jitdump file for `perf inject`
* - aot. TBD
* - fast-jit. TBD
* - multi-tier-jit. TBD
* - interpreter. TBD
*/
bool linux_perf_support;
} RuntimeInitArgs;

#ifndef WASM_VALKIND_T_DEFINED
Expand Down Expand Up @@ -945,7 +954,7 @@ wasm_runtime_get_custom_data(wasm_module_inst_t module_inst);

/**
* Set the memory bounds checks flag of a WASM module instance.
*
*
* @param module_inst the WASM module instance
* @param enable the flag to enable/disable the memory bounds checks
*/
Expand All @@ -954,9 +963,8 @@ wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst,
bool enable);
/**
* Check if the memory bounds checks flag is enabled for a WASM module instance.
*
* @param module_inst the WASM module instance
*
* @param module_inst the WASM module instance
* @return true if the memory bounds checks flag is enabled, false otherwise
*/
WASM_RUNTIME_API_EXTERN bool
Expand Down
1 change: 1 addition & 0 deletions core/iwasm/interpreter/wasm_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -2878,6 +2878,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
option.opt_level = llvm_jit_options.opt_level;
option.size_level = llvm_jit_options.size_level;
option.segue_flags = llvm_jit_options.segue_flags;
option.linux_perf_support = llvm_jit_options.linux_perf_support;

#if WASM_ENABLE_BULK_MEMORY != 0
option.enable_bulk_memory = true;
Expand Down
1 change: 1 addition & 0 deletions core/iwasm/interpreter/wasm_mini_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,7 @@ init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
option.opt_level = llvm_jit_options.opt_level;
option.size_level = llvm_jit_options.size_level;
option.segue_flags = llvm_jit_options.segue_flags;
option.linux_perf_support = llvm_jit_options.linux_perf_support;

#if WASM_ENABLE_BULK_MEMORY != 0
option.enable_bulk_memory = true;
Expand Down
Loading

0 comments on commit 8aa813f

Please sign in to comment.