Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ if (NOT DEFINED WAMR_BUILD_REF_TYPES)
set (WAMR_BUILD_REF_TYPES 1)
endif ()

if (NOT DEFINED WAMR_BUILD_BRANCH_HINTS)
# Enable branch hints by default
set (WAMR_BUILD_BRANCH_HINTS 1)
endif ()

set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})

include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
Expand Down
4 changes: 4 additions & 0 deletions build-scripts/SConscript_config
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ if GetDepend(['WAMR_BUILD_REF_TYPES']):
CPPDEFINES += ['WASM_ENABLE_REF_TYPES=1']
print('[WAMR] enable ref types')

if GetDepend(['WAMR_BUILD_BRANCH_HINTS']):
CPPDEFINES += ['WASM_ENABLE_BRANCH_HINTS=1']
print('[WAMR] enable branch hints')

CPPDEFINES += ['BH_MALLOC=wasm_runtime_malloc']
CPPDEFINES += ['BH_FREE=wasm_runtime_free']

Expand Down
12 changes: 11 additions & 1 deletion build-scripts/config_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ if (NOT DEFINED WAMR_BUILD_EXTENDED_CONST_EXPR)
set (WAMR_BUILD_EXTENDED_CONST_EXPR 0)
endif ()

if (NOT DEFINED WAMR_BUILD_BRANCH_HINTS)
set (WAMR_BUILD_BRANCH_HINTS 1)
endif ()

########################################
# Compilation options to marco
########################################
Expand Down Expand Up @@ -419,6 +423,12 @@ endif ()
if (WAMR_BUILD_REF_TYPES EQUAL 1)
add_definitions (-DWASM_ENABLE_REF_TYPES=1)
endif ()
if (WAMR_BUILD_BRANCH_HINTS EQUAL 1)
add_definitions (-DWASM_ENABLE_BRANCH_HINTS=1)
message (" branch hints enabled")
else ()
message (" branch hints disabled")
endif ()
if (WAMR_BUILD_GC EQUAL 1)
if (WAMR_TEST_GC EQUAL 1)
message(" GC testing enabled")
Expand Down Expand Up @@ -708,8 +718,8 @@ message (
" \"Tail call\" via WAMR_BUILD_TAIL_CALL: ${WAMR_BUILD_TAIL_CALL}\n"
" \"Threads\" via WAMR_BUILD_SHARED_MEMORY: ${WAMR_BUILD_SHARED_MEMORY}\n"
" \"Typed Function References\" via WAMR_BUILD_GC: ${WAMR_BUILD_GC}\n"
" \"Branch Hinting\" via WAMR_BUILD_BRANCH_HINTS: ${WAMR_BUILD_BRANCH_HINTS}\n"
" Unsupported (>= Phase4):\n"
" \"Branch Hinting\"\n"
" \"Custom Annotation Syntax in the Text Format\"\n"
" \"Exception handling\"\n"
" \"Import/Export of Mutable Globals\"\n"
Expand Down
4 changes: 4 additions & 0 deletions core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,10 @@ unless used elsewhere */
#define WASM_ENABLE_REF_TYPES 0
#endif

#ifndef WASM_ENABLE_BRANCH_HINTS
#define WASM_ENABLE_BRANCH_HINTS 0
#endif

#ifndef WASM_ENABLE_GC
#define WASM_ENABLE_GC 0
#endif
Expand Down
7 changes: 7 additions & 0 deletions core/iwasm/aot/aot_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,13 @@ check_feature_flags(char *error_buf, uint32 error_buf_size,
}
#endif

#if WASM_ENABLE_BRANCH_HINTS == 0
if (feature_flags & WASM_ENABLE_BRANCH_HINTS) {
LOG_WARNING(
"branch hints not enabled, but wasm file contains branch hints");
}
#endif

#if WASM_ENABLE_GC == 0
if (feature_flags & WASM_FEATURE_GARBAGE_COLLECTION) {
set_error_buf(error_buf, error_buf_size,
Expand Down
2 changes: 2 additions & 0 deletions core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extern "C" {
* and not at the beginning of each function call */
#define WASM_FEATURE_FRAME_PER_FUNCTION (1 << 12)
#define WASM_FEATURE_FRAME_NO_FUNC_IDX (1 << 13)
#define WASM_FEATURE_BRANCH_HINTS (1 << 14)

typedef enum AOTSectionType {
AOT_SECTION_TYPE_TARGET_INFO = 0,
Expand All @@ -57,6 +58,7 @@ typedef enum AOTCustomSectionType {
AOT_CUSTOM_SECTION_ACCESS_CONTROL = 2,
AOT_CUSTOM_SECTION_NAME = 3,
AOT_CUSTOM_SECTION_STRING_LITERAL = 4,
AOT_CUSTOM_SECTION_CODE_METADATA = 5,
} AOTCustomSectionType;

typedef struct AOTObjectDataSection {
Expand Down
8 changes: 8 additions & 0 deletions core/iwasm/compilation/aot.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ aot_create_funcs(const WASMModule *module, uint32 pointer_size)
memset(aot_func, 0, sizeof(AOTFunc));

func_type = aot_func->func_type = func->func_type;
aot_func->func_index = i + module->import_function_count;

/* Resolve function type index */
for (j = 0; j < module->type_count; j++) {
Expand All @@ -416,6 +417,9 @@ aot_create_funcs(const WASMModule *module, uint32 pointer_size)
aot_func->local_types_wp = func->local_types;
aot_func->code = func->code;
aot_func->code_size = func->code_size;
#if WASM_ENABLE_BRANCH_HINTS != 0
aot_func->code_body_begin = func->code_body_begin;
#endif

/* Resolve local offsets */
for (j = 0; j < func_type->param_count; j++) {
Expand Down Expand Up @@ -872,6 +876,10 @@ aot_create_comp_data(WASMModule *module, const char *target_arch,
comp_data->name_section_buf_end = module->name_section_buf_end;
#endif

#if WASM_ENABLE_BRANCH_HINTS != 0
comp_data->function_hints = module->function_hints;
#endif

aot_init_aux_data(comp_data, module);

comp_data->wasm_module = module;
Expand Down
8 changes: 8 additions & 0 deletions core/iwasm/compilation/aot.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ typedef struct AOTImportFunc {
typedef struct AOTFunc {
AOTFuncType *func_type;
uint32 func_type_index;
uint32 func_index;
uint32 local_count;
uint8 *local_types_wp;
uint16 param_cell_num;
Expand All @@ -217,6 +218,9 @@ typedef struct AOTFunc {
/* offset of each local, including function parameters
and local variables */
uint16 *local_offsets;
#if WASM_ENABLE_BRANCH_HINTS != 0
uint8 *code_body_begin;
#endif
} AOTFunc;

typedef struct AOTCompData {
Expand Down Expand Up @@ -296,6 +300,10 @@ typedef struct AOTCompData {
#if WASM_ENABLE_DEBUG_AOT != 0
dwarf_extractor_handle_t extractor;
#endif

#if WASM_ENABLE_BRANCH_HINTS != 0
struct WASMCompilationHint **function_hints;
#endif
} AOTCompData;

typedef struct AOTNativeSymbol {
Expand Down
9 changes: 8 additions & 1 deletion core/iwasm/compilation/aot_compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1158,9 +1158,16 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)

case WASM_OP_BR_IF:
{
// ip is advanced by one byte for the opcode
#if WASM_ENABLE_BRANCH_HINTS != 0
uint32 instr_offset =
(frame_ip - 0x1) - (func_ctx->aot_func->code_body_begin);
#else
uint32 instr_offset = 0;
#endif
read_leb_uint32(frame_ip, frame_ip_end, br_depth);
if (!aot_compile_op_br_if(comp_ctx, func_ctx, br_depth,
&frame_ip))
&frame_ip, instr_offset))
return false;
break;
}
Expand Down
3 changes: 3 additions & 0 deletions core/iwasm/compilation/aot_emit_aot_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -4501,6 +4501,9 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
if (comp_ctx->enable_ref_types) {
obj_data->target_info.feature_flags |= WASM_FEATURE_REF_TYPES;
}
if (comp_ctx->enable_branch_hints) {
obj_data->target_info.feature_flags |= WASM_FEATURE_BRANCH_HINTS;
}
if (comp_ctx->enable_gc) {
obj_data->target_info.feature_flags |= WASM_FEATURE_GARBAGE_COLLECTION;
}
Expand Down
85 changes: 81 additions & 4 deletions core/iwasm/compilation/aot_emit_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ format_block_name(char *name, uint32 name_size, uint32 block_index,
} \
} while (0)

#define BUILD_COND_BR_V(value_if, block_then, block_else, instr) \
do { \
if (instr = LLVMBuildCondBr(comp_ctx->builder, value_if, block_then, \
block_else), \
!instr) { \
aot_set_last_error("llvm build cond br failed."); \
goto fail; \
} \
} while (0)

#define SET_BUILDER_POS(llvm_block) \
LLVMPositionBuilderAtEnd(comp_ctx->builder, llvm_block)

Expand Down Expand Up @@ -255,6 +265,40 @@ restore_frame_sp_for_op_end(AOTBlock *block, AOTCompFrame *aot_frame)
aot_frame->sp = block->frame_sp_begin;
}

#if WASM_ENABLE_BRANCH_HINTS != 0
static void
aot_emit_branch_hint(LLVMContextRef ctxt, AOTFuncContext *func_ctx,
uint32 offset, LLVMValueRef br_if_instr)
{
struct WASMCompilationHintBranchHint *hint =
(struct WASMCompilationHintBranchHint *)func_ctx->function_hints;
while (hint != NULL) {
if (hint->type == WASM_COMPILATION_BRANCH_HINT
&& hint->offset == offset) {
break;
}
hint = hint->next;
}
if (hint != NULL) {
LLVMMetadataRef header = LLVMMDStringInContext2(
ctxt, "branch_weights", 14 /* strlen("branch_hint") */);
// same weight llvm MDBuilder::createLikelyBranchWeights assigns
const uint32_t likely_weight = (1U << 20) - 1;
const uint32_t unlikely_weight = 1;
LLVMMetadataRef true_w = LLVMValueAsMetadata(LLVMConstInt(
LLVMInt32TypeInContext(ctxt),
hint->is_likely ? likely_weight : unlikely_weight, false));
LLVMMetadataRef false_w = LLVMValueAsMetadata(LLVMConstInt(
LLVMInt32TypeInContext(ctxt),
hint->is_likely ? unlikely_weight : likely_weight, false));
LLVMMetadataRef mds[] = { header, true_w, false_w };
LLVMMetadataRef md = LLVMMDNodeInContext2(ctxt, mds, 3);
LLVMValueRef md_val = LLVMMetadataAsValue(ctxt, md);
LLVMSetMetadata(br_if_instr, LLVMGetMDKindID("prof", 4), md_val);
}
}
#endif

static bool
handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint8 **p_frame_ip)
Expand Down Expand Up @@ -673,13 +717,33 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
MOVE_BLOCK_AFTER(block->llvm_else_block,
block->llvm_entry_block);
/* Create condition br IR */
#if WASM_ENABLE_BRANCH_HINTS != 0
LLVMValueRef br_if_val = NULL;
BUILD_COND_BR_V(value, block->llvm_entry_block,
block->llvm_else_block, br_if_val);
const uint32 off =
*p_frame_ip - func_ctx->aot_func->code_body_begin;
aot_emit_branch_hint(comp_ctx->context, func_ctx, off,
br_if_val);
#else
BUILD_COND_BR(value, block->llvm_entry_block,
block->llvm_else_block);
#endif
}
else {
/* Create condition br IR */
#if WASM_ENABLE_BRANCH_HINTS != 0
LLVMValueRef br_if_val = NULL;
BUILD_COND_BR_V(value, block->llvm_entry_block,
block->llvm_end_block, br_if_val);
const uint32 off =
*p_frame_ip - func_ctx->aot_func->code_body_begin;
aot_emit_branch_hint(comp_ctx->context, func_ctx, off,
br_if_val);
#else
BUILD_COND_BR(value, block->llvm_entry_block,
block->llvm_end_block);
#endif
block->is_reachable = true;
}
if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx,
Expand Down Expand Up @@ -1027,7 +1091,7 @@ aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
static bool
aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 br_depth, LLVMValueRef value_cmp,
uint8 **p_frame_ip)
uint8 **p_frame_ip, uint32 off)
{
AOTBlock *block_dst;
LLVMValueRef value, *values = NULL;
Expand Down Expand Up @@ -1108,8 +1172,15 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
values = NULL;
}

#if WASM_ENABLE_BRANCH_HINTS != 0
LLVMValueRef br_if_val = NULL;
BUILD_COND_BR_V(value_cmp, block_dst->llvm_entry_block,
llvm_else_block, br_if_val);
aot_emit_branch_hint(comp_ctx->context, func_ctx, off, br_if_val);
#else
BUILD_COND_BR(value_cmp, block_dst->llvm_entry_block,
llvm_else_block);
#endif

/* Move builder to else block */
SET_BUILDER_POS(llvm_else_block);
Expand Down Expand Up @@ -1152,9 +1223,15 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}

/* Condition jump to end block */
#if WASM_ENABLE_BRANCH_HINTS != 0
LLVMValueRef br_if_val = NULL;
BUILD_COND_BR_V(value_cmp, block_dst->llvm_end_block,
llvm_else_block, br_if_val);
aot_emit_branch_hint(comp_ctx->context, func_ctx, off, br_if_val);
#else
BUILD_COND_BR(value_cmp, block_dst->llvm_end_block,
llvm_else_block);

#endif
/* Move builder to else block */
SET_BUILDER_POS(llvm_else_block);
}
Expand All @@ -1178,14 +1255,14 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,

bool
aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 br_depth, uint8 **p_frame_ip)
uint32 br_depth, uint8 **p_frame_ip, uint32 off)
{
LLVMValueRef value_cmp;

POP_COND(value_cmp);

return aot_compile_conditional_br(comp_ctx, func_ctx, br_depth, value_cmp,
p_frame_ip);
p_frame_ip, off);
fail:
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion core/iwasm/compilation/aot_emit_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,

bool
aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 br_depth, uint8 **p_frame_ip);
uint32 br_depth, uint8 **p_frame_ip, uint32 offset);

bool
aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
Expand Down
10 changes: 10 additions & 0 deletions core/iwasm/compilation/aot_llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,13 @@ aot_create_func_context(const AOTCompData *comp_data, AOTCompContext *comp_ctx,
goto fail;
}

#if WASM_ENABLE_BRANCH_HINTS != 0
func_ctx->function_hints =
comp_ctx->comp_data->function_hints
? comp_ctx->comp_data->function_hints[func_index]
: NULL;
#endif

return func_ctx;

fail:
Expand Down Expand Up @@ -2733,6 +2740,9 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
if (option->enable_ref_types)
comp_ctx->enable_ref_types = true;

if (option->enable_branch_hints)
comp_ctx->enable_branch_hints = true;

comp_ctx->aux_stack_frame_type = option->aux_stack_frame_type;
comp_ctx->call_stack_features = option->call_stack_features;

Expand Down
6 changes: 6 additions & 0 deletions core/iwasm/compilation/aot_llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ typedef struct AOTFuncContext {
#if WASM_ENABLE_DEBUG_AOT != 0
LLVMMetadataRef debug_func;
#endif
#if WASM_ENABLE_BRANCH_HINTS != 0
struct WASMCompilationHint *function_hints;
#endif

unsigned int stack_consumption_for_func_call;

Expand Down Expand Up @@ -449,6 +452,9 @@ typedef struct AOTCompContext {
/* Reference Types */
bool enable_ref_types;

/* Branch Hinting */
bool enable_branch_hints;

/* Disable LLVM built-in intrinsics */
bool disable_llvm_intrinsics;

Expand Down
1 change: 1 addition & 0 deletions core/iwasm/include/aot_comp_option.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ typedef struct AOTCompOption {
bool enable_tail_call;
bool enable_simd;
bool enable_ref_types;
bool enable_branch_hints;
bool enable_gc;
bool enable_aux_stack_check;
bool enable_extended_const;
Expand Down
Loading
Loading