From 9ea7ff60f19f1424adbffd8ba25563ba5540471c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=B6llerer?= Date: Tue, 17 Jun 2025 09:59:38 +0200 Subject: [PATCH 1/5] Add support for metadata.code.branch_hint section --- CMakeLists.txt | 5 ++ build-scripts/SConscript_config | 4 + build-scripts/config_common.cmake | 12 ++- core/config.h | 4 + core/iwasm/aot/aot_loader.c | 7 ++ core/iwasm/aot/aot_runtime.h | 2 + core/iwasm/compilation/aot.c | 8 ++ core/iwasm/compilation/aot.h | 8 ++ core/iwasm/compilation/aot_compiler.c | 9 +- core/iwasm/compilation/aot_emit_aot_file.c | 3 + core/iwasm/compilation/aot_emit_control.c | 85 ++++++++++++++++++- core/iwasm/compilation/aot_emit_control.h | 2 +- core/iwasm/compilation/aot_llvm.c | 10 +++ core/iwasm/compilation/aot_llvm.h | 6 ++ core/iwasm/include/aot_comp_option.h | 1 + core/iwasm/interpreter/wasm.h | 25 ++++++ core/iwasm/interpreter/wasm_loader.c | 98 ++++++++++++++++++++++ wamr-compiler/CMakeLists.txt | 1 + 18 files changed, 283 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b28fa89c1..b16fbc8ad1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/build-scripts/SConscript_config b/build-scripts/SConscript_config index 246bd0aaab..61d6c493e8 100644 --- a/build-scripts/SConscript_config +++ b/build-scripts/SConscript_config @@ -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'] diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 8cdce4a017..ed994b5a43 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -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 ######################################## @@ -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") @@ -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" diff --git a/core/config.h b/core/config.h index 38af3b029e..7c2b0570a4 100644 --- a/core/config.h +++ b/core/config.h @@ -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 diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 358ec5d1d8..01bbc4c745 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -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, diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index d06cd10812..baf4c74975 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -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, @@ -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 { diff --git a/core/iwasm/compilation/aot.c b/core/iwasm/compilation/aot.c index 81fdb1284f..153989cd8c 100644 --- a/core/iwasm/compilation/aot.c +++ b/core/iwasm/compilation/aot.c @@ -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++) { @@ -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++) { @@ -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; diff --git a/core/iwasm/compilation/aot.h b/core/iwasm/compilation/aot.h index 973d198caa..1dd3ff69bd 100644 --- a/core/iwasm/compilation/aot.h +++ b/core/iwasm/compilation/aot.h @@ -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; @@ -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 { @@ -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 { diff --git a/core/iwasm/compilation/aot_compiler.c b/core/iwasm/compilation/aot_compiler.c index 5d9664ee8e..69535e5e19 100644 --- a/core/iwasm/compilation/aot_compiler.c +++ b/core/iwasm/compilation/aot_compiler.c @@ -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; } diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index db1c04d88a..f2e0826700 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -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; } diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 80e379513c..a50321c504 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -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) @@ -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) @@ -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, @@ -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; @@ -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); @@ -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); } @@ -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; } diff --git a/core/iwasm/compilation/aot_emit_control.h b/core/iwasm/compilation/aot_emit_control.h index fd538495d6..f925988fbd 100644 --- a/core/iwasm/compilation/aot_emit_control.h +++ b/core/iwasm/compilation/aot_emit_control.h @@ -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, diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index 5190a39d4b..951f7eb9c0 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -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: @@ -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; diff --git a/core/iwasm/compilation/aot_llvm.h b/core/iwasm/compilation/aot_llvm.h index 9f62f66162..6a4f30b99a 100644 --- a/core/iwasm/compilation/aot_llvm.h +++ b/core/iwasm/compilation/aot_llvm.h @@ -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; @@ -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; diff --git a/core/iwasm/include/aot_comp_option.h b/core/iwasm/include/aot_comp_option.h index 069ceab319..113bef917d 100644 --- a/core/iwasm/include/aot_comp_option.h +++ b/core/iwasm/include/aot_comp_option.h @@ -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; diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 0dd73958eb..20513d502d 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -751,6 +751,10 @@ struct WASMFunction { void *call_to_fast_jit_from_llvm_jit; #endif #endif + +#if WASM_ENABLE_BRANCH_HINTS != 0 + uint8 *code_body_begin; +#endif }; #if WASM_ENABLE_TAGS != 0 @@ -761,6 +765,23 @@ struct WASMTag { }; #endif +#if WASM_ENABLE_BRANCH_HINTS != 0 +enum WASMCompilationHintType { + DUMMY = 0, + WASM_COMPILATION_BRANCH_HINT = 0, +}; +struct WASMCompilationHint { + struct WASMCompilationHint *next; + enum WASMCompilationHintType type; +}; +struct WASMCompilationHintBranchHint { + void *next; + enum WASMCompilationHintType type; + uint32 offset; + bool is_likely; +}; +#endif + struct WASMGlobal { WASMGlobalType type; #if WASM_ENABLE_GC != 0 @@ -1049,6 +1070,10 @@ struct WASMModule { const uint8 *name_section_buf_end; #endif +#if WASM_ENABLE_BRANCH_HINTS != 0 + struct WASMCompilationHint **function_hints; +#endif + #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 WASMCustomSection *custom_section_list; #endif diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 12e68c06ee..5c2ccd4a69 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -3865,6 +3865,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, /* Resolve local set count */ p_code_end = p_code + code_size; +#if WASM_ENABLE_BRANCH_HINTS != 0 + uint8 *p_body_start = (uint8 *)p_code; +#endif local_count = 0; read_leb_uint32(p_code, buf_code_end, local_set_count); p_code_save = p_code; @@ -3940,6 +3943,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, if (local_count > 0) func->local_types = (uint8 *)func + sizeof(WASMFunction); func->code_size = code_size; +#if WASM_ENABLE_BRANCH_HINTS != 0 + func->code_body_begin = p_body_start; +#endif /* * we shall make a copy of code body [p_code, p_code + code_size] * when we are worrying about inappropriate releasing behaviour. @@ -5512,6 +5518,87 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } #endif +#if WASM_ENABLE_BRANCH_HINTS != 0 +static bool +handle_branch_hint_section(const uint8 *buf, const uint8 *buf_end, + WASMModule *module, char *error_buf, + uint32 error_buf_size) +{ + if (module->function_hints == NULL) { + module->function_hints = loader_malloc( + sizeof(struct WASMCompilationHint) * module->function_count, + error_buf, error_buf_size); + } + uint32 numFunctionHints = 0; + read_leb_uint32(buf, buf_end, numFunctionHints); + for (uint32 i = 0; i < numFunctionHints; ++i) { + uint32 func_idx; + read_leb_uint32(buf, buf_end, func_idx); + if (!check_function_index(module, func_idx, error_buf, + error_buf_size)) { + goto fail; + } + if (func_idx < module->import_function_count) { + set_error_buf(error_buf, error_buf_size, + "branch hint for imported function is not allowed"); + goto fail; + } + + struct WASMCompilationHintBranchHint *current_hint = + (struct WASMCompilationHintBranchHint *)&module + ->function_hints[func_idx - module->import_function_count]; + while (current_hint->next != NULL) { + current_hint = current_hint->next; + } + + uint32 num_hints; + read_leb_uint32(buf, buf_end, num_hints); + for (uint32 j = 0; j < num_hints; ++j) { + struct WASMCompilationHintBranchHint *new_hint = + loader_malloc(sizeof(struct WASMCompilationHintBranchHint), + error_buf, error_buf_size); + new_hint->next = NULL; + new_hint->type = WASM_COMPILATION_BRANCH_HINT; + read_leb_uint32(buf, buf_end, new_hint->offset); + + uint32 size; + read_leb_uint32(buf, buf_end, size); + if (size != 1) { + set_error_buf_v(error_buf, error_buf_size, + "invalid branch hint size, expected 1, got %d.", + size); + wasm_runtime_free(new_hint); + goto fail; + } + + uint8 data = *buf++; + if (data == 0x00) + new_hint->is_likely = false; + else if (data == 0x01) + new_hint->is_likely = true; + else { + set_error_buf_v(error_buf, error_buf_size, + "invalid branch hint, expected 0 or 1, got %d", + data); + wasm_runtime_free(new_hint); + goto fail; + } + + current_hint->next = new_hint; + current_hint = new_hint; + } + } + if (buf != buf_end) { + set_error_buf(error_buf, error_buf_size, + "invalid branch hint section, not filled until end"); + goto fail; + } + return true; +fail: + return false; +} +#endif + static bool load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, bool is_load_from_file_buf, char *error_buf, @@ -5561,6 +5648,17 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } #endif +#if WASM_ENABLE_BRANCH_HINTS != 0 + if (name_len == 25 && memcmp(p, "metadata.code.branch_hint", 25) == 0) { + p += name_len; + if (!handle_branch_hint_section(p, p_end, module, error_buf, + error_buf_size)) { + return false; + } + LOG_VERBOSE("Load branch hint section success."); + } +#endif + #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 { WASMCustomSection *section = diff --git a/wamr-compiler/CMakeLists.txt b/wamr-compiler/CMakeLists.txt index 8ee61cab4d..7356ba3c12 100644 --- a/wamr-compiler/CMakeLists.txt +++ b/wamr-compiler/CMakeLists.txt @@ -46,6 +46,7 @@ add_definitions(-DWASM_ENABLE_SHARED_MEMORY=1) add_definitions(-DWASM_ENABLE_THREAD_MGR=1) add_definitions(-DWASM_ENABLE_TAIL_CALL=1) add_definitions(-DWASM_ENABLE_REF_TYPES=1) +add_definitions(-DWASM_ENABLE_BRANCH_HINTS=1) add_definitions(-DWASM_ENABLE_CUSTOM_NAME_SECTION=1) add_definitions(-DWASM_ENABLE_AOT_STACK_FRAME=1) add_definitions(-DWASM_ENABLE_DUMP_CALL_STACK=1) From d13a52f04ae8a9c4f8a600a8709c02f16dc1a9ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=B6llerer?= Date: Thu, 10 Jul 2025 16:35:14 +0200 Subject: [PATCH 2/5] Fixes from first review --- CMakeLists.txt | 5 -- build-scripts/SConscript_config | 4 -- build-scripts/config_common.cmake | 11 ---- core/iwasm/aot/aot_loader.c | 7 --- core/iwasm/aot/aot_runtime.h | 1 - core/iwasm/compilation/aot.c | 1 - core/iwasm/compilation/aot.h | 1 - core/iwasm/compilation/aot_compiler.c | 11 +--- core/iwasm/compilation/aot_emit_aot_file.c | 2 +- core/iwasm/compilation/aot_emit_control.c | 68 ++++++++++++---------- core/iwasm/compilation/aot_emit_control.h | 2 +- core/iwasm/include/aot_comp_option.h | 1 - core/iwasm/interpreter/wasm.h | 2 +- core/iwasm/interpreter/wasm_loader.c | 34 ++++++++--- 14 files changed, 65 insertions(+), 85 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b16fbc8ad1..4b28fa89c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,11 +119,6 @@ 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) diff --git a/build-scripts/SConscript_config b/build-scripts/SConscript_config index 61d6c493e8..246bd0aaab 100644 --- a/build-scripts/SConscript_config +++ b/build-scripts/SConscript_config @@ -128,10 +128,6 @@ 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'] diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index ed994b5a43..d8123b319a 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -215,10 +215,6 @@ 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 ######################################## @@ -423,12 +419,6 @@ 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") @@ -718,7 +708,6 @@ 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" " \"Custom Annotation Syntax in the Text Format\"\n" " \"Exception handling\"\n" diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 01bbc4c745..358ec5d1d8 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -505,13 +505,6 @@ 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, diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index baf4c74975..e8521865b2 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -58,7 +58,6 @@ 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 { diff --git a/core/iwasm/compilation/aot.c b/core/iwasm/compilation/aot.c index 153989cd8c..7293ca1793 100644 --- a/core/iwasm/compilation/aot.c +++ b/core/iwasm/compilation/aot.c @@ -392,7 +392,6 @@ 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++) { diff --git a/core/iwasm/compilation/aot.h b/core/iwasm/compilation/aot.h index 1dd3ff69bd..f1ecccfb37 100644 --- a/core/iwasm/compilation/aot.h +++ b/core/iwasm/compilation/aot.h @@ -207,7 +207,6 @@ 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; diff --git a/core/iwasm/compilation/aot_compiler.c b/core/iwasm/compilation/aot_compiler.c index 69535e5e19..8c682cd5ec 100644 --- a/core/iwasm/compilation/aot_compiler.c +++ b/core/iwasm/compilation/aot_compiler.c @@ -1158,16 +1158,7 @@ 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, instr_offset)) + if (!aot_compile_op_br_if(comp_ctx, func_ctx, &frame_ip)) return false; break; } diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index f2e0826700..fcd605c612 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -1905,7 +1905,7 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset, { WASMArrayType *array_type = NULL; - bh_assert(expr->u.array_new_default.type_index + bh_assert(expr->u.unary.v.array_new_default.type_index < module->type_count); array_type = (WASMArrayType *) diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index a50321c504..16af3e8749 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -12,6 +12,7 @@ #endif #include "../aot/aot_runtime.h" #include "../interpreter/wasm_loader.h" +#include "../common/wasm_loader_common.h" #if WASM_ENABLE_DEBUG_AOT != 0 #include "debug/dwarf_extractor.h" @@ -87,11 +88,10 @@ 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) { \ +#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))) { \ aot_set_last_error("llvm build cond br failed."); \ goto fail; \ } \ @@ -267,34 +267,30 @@ restore_frame_sp_for_op_end(AOTBlock *block, AOTCompFrame *aot_frame) #if WASM_ENABLE_BRANCH_HINTS != 0 static void -aot_emit_branch_hint(LLVMContextRef ctxt, AOTFuncContext *func_ctx, +aot_emit_branch_hint(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 offset, LLVMValueRef br_if_instr) { - struct WASMCompilationHintBranchHint *hint = - (struct WASMCompilationHintBranchHint *)func_ctx->function_hints; + struct WASMCompilationHint *hint = func_ctx->function_hints; while (hint != NULL) { if (hint->type == WASM_COMPILATION_BRANCH_HINT - && hint->offset == offset) { + && ((struct WASMCompilationHintBranchHint *)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); + aot_set_cond_br_weights( + comp_ctx, br_if_instr, + ((struct WASMCompilationHintBranchHint *)hint)->is_likely + ? likely_weight + : unlikely_weight, + ((struct WASMCompilationHintBranchHint *)hint)->is_likely + ? unlikely_weight + : likely_weight); } } #endif @@ -723,8 +719,7 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, 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); + aot_emit_branch_hint(comp_ctx, func_ctx, off, br_if_val); #else BUILD_COND_BR(value, block->llvm_entry_block, block->llvm_else_block); @@ -738,8 +733,7 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, 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); + aot_emit_branch_hint(comp_ctx, func_ctx, off, br_if_val); #else BUILD_COND_BR(value, block->llvm_entry_block, block->llvm_end_block); @@ -1090,8 +1084,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, uint32 off) + LLVMValueRef value_cmp, uint8 **p_frame_ip) { AOTBlock *block_dst; LLVMValueRef value, *values = NULL; @@ -1100,6 +1093,17 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 i, param_index, result_index; uint64 size; + // ip is advanced by one byte for the opcode +#if WASM_ENABLE_BRANCH_HINTS != 0 + uint32 instr_offset = + (*p_frame_ip - 0x1) - (func_ctx->aot_func->code_body_begin); +#else + uint32 instr_offset = 0; +#endif + uint64 br_depth; + if (!read_leb(p_frame_ip, *p_frame_ip + 5, 32, false, &br_depth, NULL, 0)) + return false; + if (!(block_dst = get_target_block(func_ctx, br_depth))) { return false; } @@ -1176,7 +1180,7 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, 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); + aot_emit_branch_hint(comp_ctx, func_ctx, instr_offset, br_if_val); #else BUILD_COND_BR(value_cmp, block_dst->llvm_entry_block, llvm_else_block); @@ -1227,7 +1231,7 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, 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); + aot_emit_branch_hint(comp_ctx, func_ctx, instr_offset, br_if_val); #else BUILD_COND_BR(value_cmp, block_dst->llvm_end_block, llvm_else_block); @@ -1255,14 +1259,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 off) + uint8 **p_frame_ip) { LLVMValueRef value_cmp; POP_COND(value_cmp); - return aot_compile_conditional_br(comp_ctx, func_ctx, br_depth, value_cmp, - p_frame_ip, off); + return aot_compile_conditional_br(comp_ctx, func_ctx, value_cmp, + p_frame_ip); fail: return false; } diff --git a/core/iwasm/compilation/aot_emit_control.h b/core/iwasm/compilation/aot_emit_control.h index f925988fbd..7ea527a20c 100644 --- a/core/iwasm/compilation/aot_emit_control.h +++ b/core/iwasm/compilation/aot_emit_control.h @@ -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 offset); + uint8 **p_frame_ip); bool aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, diff --git a/core/iwasm/include/aot_comp_option.h b/core/iwasm/include/aot_comp_option.h index 113bef917d..069ceab319 100644 --- a/core/iwasm/include/aot_comp_option.h +++ b/core/iwasm/include/aot_comp_option.h @@ -66,7 +66,6 @@ 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; diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 20513d502d..87552455e6 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -775,7 +775,7 @@ struct WASMCompilationHint { enum WASMCompilationHintType type; }; struct WASMCompilationHintBranchHint { - void *next; + struct WASMCompilationHint *next; enum WASMCompilationHintType type; uint32 offset; bool is_likely; diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 5c2ccd4a69..3fb20cfcb1 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -5544,8 +5544,8 @@ handle_branch_hint_section(const uint8 *buf, const uint8 *buf_end, goto fail; } - struct WASMCompilationHintBranchHint *current_hint = - (struct WASMCompilationHintBranchHint *)&module + struct WASMCompilationHint *current_hint = + (struct WASMCompilationHint *)&module ->function_hints[func_idx - module->import_function_count]; while (current_hint->next != NULL) { current_hint = current_hint->next; @@ -5553,10 +5553,11 @@ handle_branch_hint_section(const uint8 *buf, const uint8 *buf_end, uint32 num_hints; read_leb_uint32(buf, buf_end, num_hints); + struct WASMCompilationHintBranchHint *new_hints = loader_malloc( + sizeof(struct WASMCompilationHintBranchHint) * num_hints, error_buf, + error_buf_size); for (uint32 j = 0; j < num_hints; ++j) { - struct WASMCompilationHintBranchHint *new_hint = - loader_malloc(sizeof(struct WASMCompilationHintBranchHint), - error_buf, error_buf_size); + struct WASMCompilationHintBranchHint *new_hint = &new_hints[j]; new_hint->next = NULL; new_hint->type = WASM_COMPILATION_BRANCH_HINT; read_leb_uint32(buf, buf_end, new_hint->offset); @@ -5584,8 +5585,8 @@ handle_branch_hint_section(const uint8 *buf, const uint8 *buf_end, goto fail; } - current_hint->next = new_hint; - current_hint = new_hint; + current_hint->next = (struct WASMCompilationHint *)new_hint; + current_hint = (struct WASMCompilationHint *)new_hint; } } if (buf != buf_end) { @@ -5649,7 +5650,8 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, #endif #if WASM_ENABLE_BRANCH_HINTS != 0 - if (name_len == 25 && memcmp(p, "metadata.code.branch_hint", 25) == 0) { + if (name_len == 25 + && strncmp((const char *)p, "metadata.code.branch_hint", 25) == 0) { p += name_len; if (!handle_branch_hint_section(p, p_end, module, error_buf, error_buf_size)) { @@ -5657,6 +5659,12 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } LOG_VERBOSE("Load branch hint section success."); } +#else + if (name_len == 25 + && strncmp((const char *)p, "metadata.code.branch_hint", 25) == 0) { + LOG_VERBOSE("Found branch hint section, but branch hints are disabled " + "in this build, skipping."); + } #endif #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 @@ -7446,7 +7454,15 @@ wasm_loader_unload(WASMModule *module) } #endif #endif - +#if WASM_ENABLE_BRANCH_HINTS != 0 + for (size_t i = 0; i < module->function_count; i++) { + // be carefull when adding more hints. This only works as long as + // the hint structs have been allocated all at once as an array. + // With only branch-hints at the moment, this is the case. + wasm_runtime_free(module->function_hints[i]); + } + wasm_runtime_free(module->function_hints); +#endif wasm_runtime_free(module); } From 8845a2cfaff43abed41c71077233fc89cade03ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=B6llerer?= Date: Thu, 10 Jul 2025 17:34:53 +0200 Subject: [PATCH 3/5] Formatting --- core/iwasm/compilation/aot_emit_control.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 16af3e8749..6817295f86 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -92,9 +92,9 @@ format_block_name(char *name, uint32 name_size, uint32 block_index, do { \ if (!(instr = LLVMBuildCondBr(comp_ctx->builder, value_if, block_then, \ block_else))) { \ - aot_set_last_error("llvm build cond br failed."); \ - goto fail; \ - } \ + aot_set_last_error("llvm build cond br failed."); \ + goto fail; \ + } \ } while (0) #define SET_BUILDER_POS(llvm_block) \ From f1dbe4a450a51c22992ddf9bbc15a503be717b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=B6llerer?= Date: Thu, 10 Jul 2025 17:36:49 +0200 Subject: [PATCH 4/5] Remove branch hint flags since they are not required --- core/iwasm/aot/aot_runtime.h | 1 - core/iwasm/compilation/aot_emit_aot_file.c | 3 --- core/iwasm/compilation/aot_llvm.c | 3 --- core/iwasm/compilation/aot_llvm.h | 3 --- 4 files changed, 10 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index e8521865b2..d06cd10812 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -35,7 +35,6 @@ 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, diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index fcd605c612..12749305b7 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -4501,9 +4501,6 @@ 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; } diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index 951f7eb9c0..ed36749be4 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -2740,9 +2740,6 @@ 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; diff --git a/core/iwasm/compilation/aot_llvm.h b/core/iwasm/compilation/aot_llvm.h index 6a4f30b99a..a83fddb49a 100644 --- a/core/iwasm/compilation/aot_llvm.h +++ b/core/iwasm/compilation/aot_llvm.h @@ -452,9 +452,6 @@ typedef struct AOTCompContext { /* Reference Types */ bool enable_ref_types; - /* Branch Hinting */ - bool enable_branch_hints; - /* Disable LLVM built-in intrinsics */ bool disable_llvm_intrinsics; From fbb5e21e98be2a962dfc722779b56ba62fdc9886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=B6llerer?= Date: Thu, 10 Jul 2025 17:38:57 +0200 Subject: [PATCH 5/5] Fix free(NULL) calls --- core/iwasm/interpreter/wasm_loader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 3fb20cfcb1..0e13612bb5 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -7459,7 +7459,8 @@ wasm_loader_unload(WASMModule *module) // be carefull when adding more hints. This only works as long as // the hint structs have been allocated all at once as an array. // With only branch-hints at the moment, this is the case. - wasm_runtime_free(module->function_hints[i]); + if (module->function_hints[i] != NULL) + wasm_runtime_free(module->function_hints[i]); } wasm_runtime_free(module->function_hints); #endif