@@ -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 */
116167static bool
117168check_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
20822132bool
20832133aot_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 ))
0 commit comments