Skip to content

Commit ed551fe

Browse files
committed
Add support for metadata.code.call_targets section
1 parent 95f506a commit ed551fe

16 files changed

Lines changed: 309 additions & 62 deletions

File tree

build-scripts/config_common.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ message (
778778
" \"Sign-extension Operators\"\n"
779779
" \"WebAssembly C and C++ API\"\n"
780780
" \"Branch Hinting\"\n"
781+
" \"Compilation Hints\"\n"
781782
" Configurable. 0 is OFF. 1 is ON:\n"
782783
" \"Bulk Memory Operation\" via WAMR_BUILD_BULK_MEMORY: ${WAMR_BUILD_BULK_MEMORY}\n"
783784
" \"Bulk-memory-opt\" via WAMR_BUILD_BULK_MEMORY_OPT: ${WAMR_BUILD_BULK_MEMORY_OPT}\n"

core/config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,10 @@ unless used elsewhere */
591591
#define WASM_ENABLE_BRANCH_HINTS 0
592592
#endif
593593

594+
#ifndef WASM_ENABLE_COMPILATION_HINTS
595+
#define WASM_ENABLE_COMPILATION_HINTS 0
596+
#endif
597+
594598
#ifndef WASM_ENABLE_GC
595599
#define WASM_ENABLE_GC 0
596600
#endif

core/iwasm/compilation/aot.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ 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
419+
#if WASM_ENABLE_BRANCH_HINTS != 0 || WASM_ENABLE_COMPILATION_HINTS != 0
420420
aot_func->code_body_begin = func->code_body_begin;
421421
#endif
422422

@@ -875,7 +875,7 @@ aot_create_comp_data(WASMModule *module, const char *target_arch,
875875
comp_data->name_section_buf_end = module->name_section_buf_end;
876876
#endif
877877

878-
#if WASM_ENABLE_BRANCH_HINTS != 0
878+
#if WASM_ENABLE_BRANCH_HINTS != 0 || WASM_ENABLE_COMPILATION_HINTS != 0
879879
comp_data->function_hints = module->function_hints;
880880
#endif
881881

core/iwasm/compilation/aot.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ 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
220+
#if WASM_ENABLE_BRANCH_HINTS != 0 || WASM_ENABLE_COMPILATION_HINTS != 0
221221
uint8 *code_body_begin;
222222
#endif
223223
} AOTFunc;
@@ -300,7 +300,7 @@ typedef struct AOTCompData {
300300
dwarf_extractor_handle_t extractor;
301301
#endif
302302

303-
#if WASM_ENABLE_BRANCH_HINTS != 0
303+
#if WASM_ENABLE_BRANCH_HINTS != 0 || WASM_ENABLE_COMPILATION_HINTS != 0
304304
struct WASMCompilationHint **function_hints;
305305
#endif
306306
} AOTCompData;

core/iwasm/compilation/aot_compiler.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,12 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
12331233

12341234
case WASM_OP_CALL_INDIRECT:
12351235
{
1236+
#if WASM_ENABLE_COMPILATION_HINTS != 0
1237+
const uint32 instr_offset =
1238+
(frame_ip - 0x1) - (func_ctx->aot_func->code_body_begin);
1239+
#else
1240+
const uint32 instr_offset = 0;
1241+
#endif
12361242
uint32 tbl_idx;
12371243

12381244
read_leb_uint32(frame_ip, frame_ip_end, type_idx);
@@ -1246,7 +1252,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
12461252
}
12471253

12481254
if (!aot_compile_op_call_indirect(comp_ctx, func_ctx, type_idx,
1249-
tbl_idx))
1255+
tbl_idx, instr_offset))
12501256
return false;
12511257
break;
12521258
}
@@ -1269,6 +1275,12 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
12691275

12701276
case WASM_OP_RETURN_CALL_INDIRECT:
12711277
{
1278+
#if WASM_ENABLE_COMPILATION_HINTS != 0
1279+
const uint32 instr_offset =
1280+
(frame_ip - 0x1) - (func_ctx->aot_func->code_body_begin);
1281+
#else
1282+
const uint32 instr_offset = 0;
1283+
#endif
12721284
uint32 tbl_idx;
12731285

12741286
if (!comp_ctx->enable_tail_call) {
@@ -1286,7 +1298,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
12861298
}
12871299

12881300
if (!aot_compile_op_call_indirect(comp_ctx, func_ctx, type_idx,
1289-
tbl_idx))
1301+
tbl_idx, instr_offset))
12901302
return false;
12911303
if (!aot_compile_op_return(comp_ctx, func_ctx, &frame_ip))
12921304
return false;

core/iwasm/compilation/aot_emit_control.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,14 +272,14 @@ aot_emit_branch_hint(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
272272
{
273273
struct WASMCompilationHint *hint = func_ctx->function_hints;
274274
while (hint != NULL) {
275-
if (hint->type == WASM_COMPILATION_BRANCH_HINT
276-
&& ((struct WASMCompilationHintBranchHint *)hint)->offset
277-
== offset) {
275+
if (hint->type == WASM_COMPILATION_HINT_BRANCH
276+
&& hint->offset == offset) {
278277
break;
279278
}
280279
hint = hint->next;
281280
}
282281
if (hint != NULL) {
282+
((struct WASMCompilationHintBranchHint *)hint)->used = true;
283283
// same weight llvm MDBuilder::createLikelyBranchWeights assigns
284284
const uint32_t likely_weight = (1U << 20) - 1;
285285
const uint32_t unlikely_weight = 1;
@@ -1094,11 +1094,11 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
10941094
uint64 size;
10951095

10961096
// ip is advanced by one byte for the opcode
1097-
#if WASM_ENABLE_BRANCH_HINTS != 0
1098-
uint32 instr_offset =
1097+
#if WASM_ENABLE_BRANCH_HINTS != 0 || WASM_ENABLE_COMPILATION_HINTS != 0
1098+
const uint32 instr_offset =
10991099
(*p_frame_ip - 0x1) - (func_ctx->aot_func->code_body_begin);
11001100
#else
1101-
uint32 instr_offset = 0;
1101+
const uint32 instr_offset = 0;
11021102
#endif
11031103
uint64 br_depth;
11041104
if (!read_leb(p_frame_ip, *p_frame_ip + 5, 32, false, &br_depth, NULL, 0))

core/iwasm/compilation/aot_emit_function.c

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,57 @@ check_exception_thrown(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
112112
return true;
113113
}
114114

115+
#if WASM_ENABLE_COMPILATION_HINTS != 0
116+
static void
117+
aot_emit_call_target_hint(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
118+
uint32 offset, LLVMValueRef call_instr)
119+
{
120+
struct WASMCompilationHint *hint = func_ctx->function_hints;
121+
while (hint != NULL) {
122+
if (hint->type == WASM_COMPILATION_HINT_CALL_TARGETS
123+
&& ((struct WASMCompilationHintCallTargets *)hint)->offset
124+
== offset) {
125+
break;
126+
}
127+
hint = hint->next;
128+
}
129+
if (hint != NULL) {
130+
hint->used = true;
131+
struct WASMCompilationHintCallTargets *ct_hint =
132+
(struct WASMCompilationHintCallTargets *)hint;
133+
unsigned md_node_cnt = ct_hint->target_count * 2 + 3;
134+
LLVMMetadataRef md_nodes[md_node_cnt];
135+
md_nodes[0] =
136+
LLVMMDStringInContext2(comp_ctx->context, "VP", strlen("VP"));
137+
md_nodes[1] = LLVMValueAsMetadata(I32_CONST(0));
138+
// since wasm encodes a call frequency in full percent, we forward this
139+
// to llvm as 100 calls to match the percentages
140+
// (could be enhanced with the instruction frequency hints)
141+
md_nodes[2] = LLVMValueAsMetadata(I64_CONST(100));
142+
143+
for (size_t i = 0; i < ct_hint->target_count; ++i) {
144+
struct WASMCompilationHintCallTargetsHint *target =
145+
&ct_hint->hints[i];
146+
char target_func_name[48];
147+
snprintf(target_func_name, sizeof(target_func_name), "%s%d",
148+
AOT_FUNC_PREFIX,
149+
target->func_idx - comp_ctx->comp_data->import_func_count);
150+
const uint64_t func_name_hash =
151+
aot_func_name_hash(target_func_name);
152+
md_nodes[i * 2 + 3] =
153+
LLVMValueAsMetadata(I64_CONST(func_name_hash));
154+
md_nodes[i * 2 + 3 + 1] =
155+
LLVMValueAsMetadata(I64_CONST(target->call_frequency));
156+
}
157+
LLVMMetadataRef meta_data =
158+
LLVMMDNodeInContext2(comp_ctx->context, md_nodes, md_node_cnt);
159+
LLVMValueRef meta_data_as_value =
160+
LLVMMetadataAsValue(comp_ctx->context, meta_data);
161+
LLVMSetMetadata(call_instr, 2, meta_data_as_value);
162+
}
163+
}
164+
#endif
165+
115166
/* Check whether there was exception thrown, if yes, return directly */
116167
static bool
117168
check_call_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
@@ -1929,7 +1980,7 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
19291980
LLVMValueRef *param_values, uint32 param_count,
19301981
uint32 param_cell_num, uint32 result_count,
19311982
uint8 *wasm_ret_types, LLVMValueRef *value_rets,
1932-
LLVMValueRef *p_res)
1983+
LLVMValueRef *p_res, uint32 instr_offset)
19331984
{
19341985
LLVMTypeRef func_type, func_ptr_type, func_param_types[6];
19351986
LLVMTypeRef ret_type, ret_ptr_type, elem_ptr_type;
@@ -2074,14 +2125,14 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
20742125
cell_num += wasm_value_type_cell_num_internal(wasm_ret_types[i],
20752126
comp_ctx->pointer_size);
20762127
}
2077-
20782128
*p_res = res;
20792129
return true;
20802130
}
20812131

20822132
bool
20832133
aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
2084-
uint32 type_idx, uint32 tbl_idx)
2134+
uint32 type_idx, uint32 tbl_idx,
2135+
uint32 instr_offset)
20852136
{
20862137
AOTFuncType *func_type;
20872138
LLVMValueRef tbl_idx_value, elem_idx, func_idx;
@@ -2620,7 +2671,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
26202671
if (!call_aot_call_indirect_func(
26212672
comp_ctx, func_ctx, func_type, ftype_idx, tbl_idx_value, elem_idx,
26222673
param_types + 1, param_values + 1, func_param_count, param_cell_num,
2623-
func_result_count, wasm_ret_types, value_rets, &res))
2674+
func_result_count, wasm_ret_types, value_rets, &res, instr_offset))
26242675
goto fail;
26252676

26262677
/* Check whether exception was thrown when executing the function */
@@ -2681,6 +2732,10 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
26812732
goto fail;
26822733
}
26832734

2735+
#if WASM_ENABLE_COMPILATION_HINTS != 0
2736+
aot_emit_call_target_hint(comp_ctx, func_ctx, instr_offset, value_ret);
2737+
#endif
2738+
26842739
/* Check whether exception was thrown when executing the function */
26852740
if ((comp_ctx->enable_bound_check || is_win_platform(comp_ctx))
26862741
&& !check_exception_thrown(comp_ctx, func_ctx))

core/iwasm/compilation/aot_emit_function.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
1818

1919
bool
2020
aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
21-
uint32 type_idx, uint32 tbl_idx);
21+
uint32 type_idx, uint32 tbl_idx,
22+
uint32 instr_offset);
2223

2324
bool
2425
aot_compile_op_ref_null(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);

core/iwasm/compilation/aot_llvm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1963,7 +1963,7 @@ aot_create_func_context(const AOTCompData *comp_data, AOTCompContext *comp_ctx,
19631963
goto fail;
19641964
}
19651965

1966-
#if WASM_ENABLE_BRANCH_HINTS != 0
1966+
#if WASM_ENABLE_BRANCH_HINTS != 0 || WASM_ENABLE_COMPILATION_HINTS != 0
19671967
func_ctx->function_hints =
19681968
comp_ctx->comp_data->function_hints
19691969
? comp_ctx->comp_data->function_hints[func_index]

core/iwasm/compilation/aot_llvm.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ typedef struct AOTFuncContext {
270270
#if WASM_ENABLE_DEBUG_AOT != 0
271271
LLVMMetadataRef debug_func;
272272
#endif
273-
#if WASM_ENABLE_BRANCH_HINTS != 0
273+
#if WASM_ENABLE_BRANCH_HINTS != 0 || WASM_ENABLE_COMPILATION_HINTS != 0
274274
struct WASMCompilationHint *function_hints;
275275
#endif
276276

@@ -674,6 +674,9 @@ unsigned int
674674
aot_estimate_stack_usage_for_function_call(const AOTCompContext *comp_ctx,
675675
const AOTFuncType *callee_func_type);
676676

677+
uint64_t
678+
aot_func_name_hash(const char *name);
679+
677680
#ifdef __cplusplus
678681
} /* end of extern "C" */
679682
#endif

0 commit comments

Comments
 (0)