Skip to content

Commit 0d3b5ca

Browse files
authored
Add support for metadata.code.branch_hint section (#4460)
Add support for metadata.code.branch_hint section
1 parent b71a6bf commit 0d3b5ca

File tree

14 files changed

+272
-24
lines changed

14 files changed

+272
-24
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (Wasm)
4747
- [128-bit SIMD](https://github.com/WebAssembly/simd), ref to [samples/workload](samples/workload)
4848
- [Reference Types](https://github.com/WebAssembly/reference-types), ref to [document](doc/ref_types.md) and [sample](samples/ref-types)
4949
- [Bulk memory operations](https://github.com/WebAssembly/bulk-memory-operations), [Shared memory](https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md#shared-linear-memory), [Memory64](https://github.com/WebAssembly/memory64)
50-
- [Tail-call](https://github.com/WebAssembly/tail-call), [Garbage Collection](https://github.com/WebAssembly/gc), [Exception Handling](https://github.com/WebAssembly/exception-handling)
50+
- [Tail-call](https://github.com/WebAssembly/tail-call), [Garbage Collection](https://github.com/WebAssembly/gc), [Exception Handling](https://github.com/WebAssembly/exception-handling), [Branch Hinting](https://github.com/WebAssembly/branch-hinting)
5151
- [Extended Constant Expressions](https://github.com/WebAssembly/extended-const)
5252

5353
### Supported architectures and platforms
@@ -117,4 +117,3 @@ Any contributions you make will be under the same license.
117117
- [WAMR Blogs](https://bytecodealliance.github.io/wamr.dev/blog/)
118118
- [Community news and events](https://bytecodealliance.github.io/wamr.dev/events/)
119119
- [WAMR TSC meetings](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/TSC-meeting-notes)
120-

build-scripts/config_common.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,7 @@ message (
739739
" \"Non-trapping float-to-int Conversions\"\n"
740740
" \"Sign-extension Operators\"\n"
741741
" \"WebAssembly C and C++ API\"\n"
742+
" \"Branch Hinting\"\n"
742743
" Configurable. 0 is OFF. 1 is ON:\n"
743744
" \"Bulk Memory Operation\" via WAMR_BUILD_BULK_MEMORY: ${WAMR_BUILD_BULK_MEMORY}\n"
744745
" \"Extended Constant Expressions\" via WAMR_BUILD_EXTENDED_CONST_EXPR: ${WAMR_BUILD_EXTENDED_CONST_EXPR}\n"
@@ -753,7 +754,6 @@ message (
753754
" \"Threads\" via WAMR_BUILD_SHARED_MEMORY: ${WAMR_BUILD_SHARED_MEMORY}\n"
754755
" \"Typed Function References\" via WAMR_BUILD_GC: ${WAMR_BUILD_GC}\n"
755756
" Unsupported (>= Phase4):\n"
756-
" \"Branch Hinting\"\n"
757757
" \"Custom Annotation Syntax in the Text Format\"\n"
758758
" \"Exception Handling\"\n"
759759
" \"JS String Builtins\"\n"

core/config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,10 @@ unless used elsewhere */
579579
#define WASM_ENABLE_REF_TYPES 0
580580
#endif
581581

582+
#ifndef WASM_ENABLE_BRANCH_HINTS
583+
#define WASM_ENABLE_BRANCH_HINTS 0
584+
#endif
585+
582586
#ifndef WASM_ENABLE_GC
583587
#define WASM_ENABLE_GC 0
584588
#endif

core/iwasm/compilation/aot.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,9 @@ aot_create_funcs(const WASMModule *module, uint32 pointer_size)
416416
aot_func->local_types_wp = func->local_types;
417417
aot_func->code = func->code;
418418
aot_func->code_size = func->code_size;
419+
#if WASM_ENABLE_BRANCH_HINTS != 0
420+
aot_func->code_body_begin = func->code_body_begin;
421+
#endif
419422

420423
/* Resolve local offsets */
421424
for (j = 0; j < func_type->param_count; j++) {
@@ -872,6 +875,10 @@ aot_create_comp_data(WASMModule *module, const char *target_arch,
872875
comp_data->name_section_buf_end = module->name_section_buf_end;
873876
#endif
874877

878+
#if WASM_ENABLE_BRANCH_HINTS != 0
879+
comp_data->function_hints = module->function_hints;
880+
#endif
881+
875882
aot_init_aux_data(comp_data, module);
876883

877884
comp_data->wasm_module = module;

core/iwasm/compilation/aot.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ typedef struct AOTFunc {
217217
/* offset of each local, including function parameters
218218
and local variables */
219219
uint16 *local_offsets;
220+
#if WASM_ENABLE_BRANCH_HINTS != 0
221+
uint8 *code_body_begin;
222+
#endif
220223
} AOTFunc;
221224

222225
typedef struct AOTCompData {
@@ -296,6 +299,10 @@ typedef struct AOTCompData {
296299
#if WASM_ENABLE_DEBUG_AOT != 0
297300
dwarf_extractor_handle_t extractor;
298301
#endif
302+
303+
#if WASM_ENABLE_BRANCH_HINTS != 0
304+
struct WASMCompilationHint **function_hints;
305+
#endif
299306
} AOTCompData;
300307

301308
typedef struct AOTNativeSymbol {

core/iwasm/compilation/aot_compiler.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,9 +1158,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
11581158

11591159
case WASM_OP_BR_IF:
11601160
{
1161-
read_leb_uint32(frame_ip, frame_ip_end, br_depth);
1162-
if (!aot_compile_op_br_if(comp_ctx, func_ctx, br_depth,
1163-
&frame_ip))
1161+
if (!aot_compile_op_br_if(comp_ctx, func_ctx, &frame_ip))
11641162
return false;
11651163
break;
11661164
}

core/iwasm/compilation/aot_emit_control.c

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
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+
258298
static bool
259299
handle_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

10271085
static bool
10281086
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)
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

11791260
bool
11801261
aot_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);
11891270
fail:
11901271
return false;

core/iwasm/compilation/aot_emit_control.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
3232

3333
bool
3434
aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
35-
uint32 br_depth, uint8 **p_frame_ip);
35+
uint8 **p_frame_ip);
3636

3737
bool
3838
aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,

core/iwasm/compilation/aot_llvm.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,13 @@ aot_create_func_context(const AOTCompData *comp_data, AOTCompContext *comp_ctx,
19631963
goto fail;
19641964
}
19651965

1966+
#if WASM_ENABLE_BRANCH_HINTS != 0
1967+
func_ctx->function_hints =
1968+
comp_ctx->comp_data->function_hints
1969+
? comp_ctx->comp_data->function_hints[func_index]
1970+
: NULL;
1971+
#endif
1972+
19661973
return func_ctx;
19671974

19681975
fail:

core/iwasm/compilation/aot_llvm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ typedef struct AOTFuncContext {
270270
#if WASM_ENABLE_DEBUG_AOT != 0
271271
LLVMMetadataRef debug_func;
272272
#endif
273+
#if WASM_ENABLE_BRANCH_HINTS != 0
274+
struct WASMCompilationHint *function_hints;
275+
#endif
273276

274277
unsigned int stack_consumption_for_func_call;
275278

0 commit comments

Comments
 (0)