12
12
#endif
13
13
#include "../aot/aot_runtime.h"
14
14
#include "../interpreter/wasm_loader.h"
15
+ #include "../common/wasm_loader_common.h"
15
16
16
17
#if WASM_ENABLE_DEBUG_AOT != 0
17
18
#include "debug/dwarf_extractor.h"
@@ -87,6 +88,15 @@ format_block_name(char *name, uint32 name_size, uint32 block_index,
87
88
} \
88
89
} while (0)
89
90
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
+
90
100
#define SET_BUILDER_POS (llvm_block ) \
91
101
LLVMPositionBuilderAtEnd(comp_ctx->builder, llvm_block)
92
102
@@ -255,6 +265,36 @@ restore_frame_sp_for_op_end(AOTBlock *block, AOTCompFrame *aot_frame)
255
265
aot_frame -> sp = block -> frame_sp_begin ;
256
266
}
257
267
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
+
258
298
static bool
259
299
handle_next_reachable_block (AOTCompContext * comp_ctx , AOTFuncContext * func_ctx ,
260
300
uint8 * * p_frame_ip )
@@ -673,13 +713,31 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
673
713
MOVE_BLOCK_AFTER (block -> llvm_else_block ,
674
714
block -> llvm_entry_block );
675
715
/* 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
676
724
BUILD_COND_BR (value , block -> llvm_entry_block ,
677
725
block -> llvm_else_block );
726
+ #endif
678
727
}
679
728
else {
680
729
/* 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
681
738
BUILD_COND_BR (value , block -> llvm_entry_block ,
682
739
block -> llvm_end_block );
740
+ #endif
683
741
block -> is_reachable = true;
684
742
}
685
743
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,
1026
1084
1027
1085
static bool
1028
1086
aot_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 )
1031
1088
{
1032
1089
AOTBlock * block_dst ;
1033
1090
LLVMValueRef value , * values = NULL ;
@@ -1036,6 +1093,17 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
1036
1093
uint32 i , param_index , result_index ;
1037
1094
uint64 size ;
1038
1095
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
+
1039
1107
if (!(block_dst = get_target_block (func_ctx , br_depth ))) {
1040
1108
return false;
1041
1109
}
@@ -1108,8 +1176,15 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
1108
1176
values = NULL ;
1109
1177
}
1110
1178
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
1111
1185
BUILD_COND_BR (value_cmp , block_dst -> llvm_entry_block ,
1112
1186
llvm_else_block );
1187
+ #endif
1113
1188
1114
1189
/* Move builder to else block */
1115
1190
SET_BUILDER_POS (llvm_else_block );
@@ -1152,9 +1227,15 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
1152
1227
}
1153
1228
1154
1229
/* 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
1155
1236
BUILD_COND_BR (value_cmp , block_dst -> llvm_end_block ,
1156
1237
llvm_else_block );
1157
-
1238
+ #endif
1158
1239
/* Move builder to else block */
1159
1240
SET_BUILDER_POS (llvm_else_block );
1160
1241
}
@@ -1178,13 +1259,13 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
1178
1259
1179
1260
bool
1180
1261
aot_compile_op_br_if (AOTCompContext * comp_ctx , AOTFuncContext * func_ctx ,
1181
- uint32 br_depth , uint8 * * p_frame_ip )
1262
+ uint8 * * p_frame_ip )
1182
1263
{
1183
1264
LLVMValueRef value_cmp ;
1184
1265
1185
1266
POP_COND (value_cmp );
1186
1267
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 ,
1188
1269
p_frame_ip );
1189
1270
fail :
1190
1271
return false;
0 commit comments