1212#endif
1313#include "../aot/aot_runtime.h"
1414#include "../interpreter/wasm_loader.h"
15+ #include "../common/wasm_loader_common.h"
1516
1617#if WASM_ENABLE_DEBUG_AOT != 0
1718#include "debug/dwarf_extractor.h"
@@ -87,6 +88,15 @@ format_block_name(char *name, uint32 name_size, uint32 block_index,
8788 } \
8889 } while (0)
8990
91+ #define BUILD_COND_BR_V (value_if , block_then , block_else , instr ) \
92+ do { \
93+ if (!(instr = LLVMBuildCondBr(comp_ctx->builder, value_if, block_then, \
94+ block_else))) { \
95+ aot_set_last_error("llvm build cond br failed."); \
96+ goto fail; \
97+ } \
98+ } while (0)
99+
90100#define SET_BUILDER_POS (llvm_block ) \
91101 LLVMPositionBuilderAtEnd(comp_ctx->builder, llvm_block)
92102
@@ -255,6 +265,36 @@ restore_frame_sp_for_op_end(AOTBlock *block, AOTCompFrame *aot_frame)
255265 aot_frame -> sp = block -> frame_sp_begin ;
256266}
257267
268+ #if WASM_ENABLE_BRANCH_HINTS != 0
269+ static void
270+ aot_emit_branch_hint (AOTCompContext * comp_ctx , AOTFuncContext * func_ctx ,
271+ uint32 offset , LLVMValueRef br_if_instr )
272+ {
273+ struct WASMCompilationHint * hint = func_ctx -> function_hints ;
274+ while (hint != NULL ) {
275+ if (hint -> type == WASM_COMPILATION_BRANCH_HINT
276+ && ((struct WASMCompilationHintBranchHint * )hint )-> offset
277+ == offset ) {
278+ break ;
279+ }
280+ hint = hint -> next ;
281+ }
282+ if (hint != NULL ) {
283+ // same weight llvm MDBuilder::createLikelyBranchWeights assigns
284+ const uint32_t likely_weight = (1U << 20 ) - 1 ;
285+ const uint32_t unlikely_weight = 1 ;
286+ aot_set_cond_br_weights (
287+ comp_ctx , br_if_instr ,
288+ ((struct WASMCompilationHintBranchHint * )hint )-> is_likely
289+ ? likely_weight
290+ : unlikely_weight ,
291+ ((struct WASMCompilationHintBranchHint * )hint )-> is_likely
292+ ? unlikely_weight
293+ : likely_weight );
294+ }
295+ }
296+ #endif
297+
258298static bool
259299handle_next_reachable_block (AOTCompContext * comp_ctx , AOTFuncContext * func_ctx ,
260300 uint8 * * p_frame_ip )
@@ -673,13 +713,31 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
673713 MOVE_BLOCK_AFTER (block -> llvm_else_block ,
674714 block -> llvm_entry_block );
675715 /* Create condition br IR */
716+ #if WASM_ENABLE_BRANCH_HINTS != 0
717+ LLVMValueRef br_if_val = NULL ;
718+ BUILD_COND_BR_V (value , block -> llvm_entry_block ,
719+ block -> llvm_else_block , br_if_val );
720+ const uint32 off =
721+ * p_frame_ip - func_ctx -> aot_func -> code_body_begin ;
722+ aot_emit_branch_hint (comp_ctx , func_ctx , off , br_if_val );
723+ #else
676724 BUILD_COND_BR (value , block -> llvm_entry_block ,
677725 block -> llvm_else_block );
726+ #endif
678727 }
679728 else {
680729 /* Create condition br IR */
730+ #if WASM_ENABLE_BRANCH_HINTS != 0
731+ LLVMValueRef br_if_val = NULL ;
732+ BUILD_COND_BR_V (value , block -> llvm_entry_block ,
733+ block -> llvm_end_block , br_if_val );
734+ const uint32 off =
735+ * p_frame_ip - func_ctx -> aot_func -> code_body_begin ;
736+ aot_emit_branch_hint (comp_ctx , func_ctx , off , br_if_val );
737+ #else
681738 BUILD_COND_BR (value , block -> llvm_entry_block ,
682739 block -> llvm_end_block );
740+ #endif
683741 block -> is_reachable = true;
684742 }
685743 if (!push_aot_block_to_stack_and_pass_params (comp_ctx , func_ctx ,
@@ -1026,8 +1084,7 @@ aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
10261084
10271085static bool
10281086aot_compile_conditional_br (AOTCompContext * comp_ctx , AOTFuncContext * func_ctx ,
1029- uint32 br_depth , LLVMValueRef value_cmp ,
1030- uint8 * * p_frame_ip )
1087+ LLVMValueRef value_cmp , uint8 * * p_frame_ip )
10311088{
10321089 AOTBlock * block_dst ;
10331090 LLVMValueRef value , * values = NULL ;
@@ -1036,6 +1093,17 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
10361093 uint32 i , param_index , result_index ;
10371094 uint64 size ;
10381095
1096+ // ip is advanced by one byte for the opcode
1097+ #if WASM_ENABLE_BRANCH_HINTS != 0
1098+ uint32 instr_offset =
1099+ (* p_frame_ip - 0x1 ) - (func_ctx -> aot_func -> code_body_begin );
1100+ #else
1101+ uint32 instr_offset = 0 ;
1102+ #endif
1103+ uint64 br_depth ;
1104+ if (!read_leb (p_frame_ip , * p_frame_ip + 5 , 32 , false, & br_depth , NULL , 0 ))
1105+ return false;
1106+
10391107 if (!(block_dst = get_target_block (func_ctx , br_depth ))) {
10401108 return false;
10411109 }
@@ -1108,8 +1176,15 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
11081176 values = NULL ;
11091177 }
11101178
1179+ #if WASM_ENABLE_BRANCH_HINTS != 0
1180+ LLVMValueRef br_if_val = NULL ;
1181+ BUILD_COND_BR_V (value_cmp , block_dst -> llvm_entry_block ,
1182+ llvm_else_block , br_if_val );
1183+ aot_emit_branch_hint (comp_ctx , func_ctx , instr_offset , br_if_val );
1184+ #else
11111185 BUILD_COND_BR (value_cmp , block_dst -> llvm_entry_block ,
11121186 llvm_else_block );
1187+ #endif
11131188
11141189 /* Move builder to else block */
11151190 SET_BUILDER_POS (llvm_else_block );
@@ -1152,9 +1227,15 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
11521227 }
11531228
11541229 /* Condition jump to end block */
1230+ #if WASM_ENABLE_BRANCH_HINTS != 0
1231+ LLVMValueRef br_if_val = NULL ;
1232+ BUILD_COND_BR_V (value_cmp , block_dst -> llvm_end_block ,
1233+ llvm_else_block , br_if_val );
1234+ aot_emit_branch_hint (comp_ctx , func_ctx , instr_offset , br_if_val );
1235+ #else
11551236 BUILD_COND_BR (value_cmp , block_dst -> llvm_end_block ,
11561237 llvm_else_block );
1157-
1238+ #endif
11581239 /* Move builder to else block */
11591240 SET_BUILDER_POS (llvm_else_block );
11601241 }
@@ -1178,13 +1259,13 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
11781259
11791260bool
11801261aot_compile_op_br_if (AOTCompContext * comp_ctx , AOTFuncContext * func_ctx ,
1181- uint32 br_depth , uint8 * * p_frame_ip )
1262+ uint8 * * p_frame_ip )
11821263{
11831264 LLVMValueRef value_cmp ;
11841265
11851266 POP_COND (value_cmp );
11861267
1187- return aot_compile_conditional_br (comp_ctx , func_ctx , br_depth , value_cmp ,
1268+ return aot_compile_conditional_br (comp_ctx , func_ctx , value_cmp ,
11881269 p_frame_ip );
11891270fail :
11901271 return false;
0 commit comments