aot compiler: Place precheck wrapper before the corresponding wrapped function (#3141)

This increases the chance to use "short" calls.

Assumptions:
- LLVM preserves the order of functions in a module
- The wrapper function are smaller than the wrapped functions
- The target CPU has "short" PC-relative variation of call/jmp instructions
  and they are preferrable over the "long" ones.

A motivation:
- To avoid some relocations for XIP, I want to use xtensa PC-relative
  call instructions, which can only reach ~512KB.
This commit is contained in:
YAMAMOTO Takashi 2024-02-06 16:05:32 +09:00 committed by GitHub
parent 6e547baf46
commit 5931aaacbe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -263,12 +263,11 @@ get_inst_extra_offset(AOTCompContext *comp_ctx)
* - update native_stack_top_min if necessary * - update native_stack_top_min if necessary
* - stack overflow check (if it does, trap) * - stack overflow check (if it does, trap)
*/ */
static LLVMValueRef static bool
aot_add_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module, aot_build_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
uint32 func_index, uint32 orig_param_count, LLVMValueRef precheck_func, uint32 func_index,
LLVMTypeRef func_type, LLVMValueRef wrapped_func) LLVMTypeRef func_type, LLVMValueRef wrapped_func)
{ {
LLVMValueRef precheck_func;
LLVMBasicBlockRef begin = NULL; LLVMBasicBlockRef begin = NULL;
LLVMBasicBlockRef check_top_block = NULL; LLVMBasicBlockRef check_top_block = NULL;
LLVMBasicBlockRef update_top_block = NULL; LLVMBasicBlockRef update_top_block = NULL;
@ -276,12 +275,6 @@ aot_add_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
LLVMBasicBlockRef call_wrapped_func_block = NULL; LLVMBasicBlockRef call_wrapped_func_block = NULL;
LLVMValueRef *params = NULL; LLVMValueRef *params = NULL;
precheck_func =
aot_add_llvm_func1(comp_ctx, module, func_index, orig_param_count,
func_type, AOT_FUNC_PREFIX);
if (!precheck_func) {
goto fail;
}
begin = LLVMAppendBasicBlockInContext(comp_ctx->context, precheck_func, begin = LLVMAppendBasicBlockInContext(comp_ctx->context, precheck_func,
"begin"); "begin");
check_top_block = LLVMAppendBasicBlockInContext( check_top_block = LLVMAppendBasicBlockInContext(
@ -550,13 +543,13 @@ aot_add_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
} }
} }
return precheck_func; return true;
fail: fail:
if (params != NULL) { if (params != NULL) {
wasm_runtime_free(params); wasm_runtime_free(params);
} }
aot_set_last_error("failed to build precheck wrapper function."); aot_set_last_error("failed to build precheck wrapper function.");
return NULL; return false;
} }
/** /**
@ -626,7 +619,14 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
const char *prefix = AOT_FUNC_PREFIX; const char *prefix = AOT_FUNC_PREFIX;
const bool need_precheck = const bool need_precheck =
comp_ctx->enable_stack_bound_check || comp_ctx->enable_stack_estimation; comp_ctx->enable_stack_bound_check || comp_ctx->enable_stack_estimation;
LLVMValueRef precheck_func;
if (need_precheck) { if (need_precheck) {
precheck_func = aot_add_llvm_func1(comp_ctx, module, func_index,
aot_func_type->param_count,
func_type, AOT_FUNC_PREFIX);
if (!precheck_func) {
goto fail;
}
/* /*
* REVISIT: probably this breaks windows hw bound check * REVISIT: probably this breaks windows hw bound check
* (the RtlAddFunctionTable stuff) * (the RtlAddFunctionTable stuff)
@ -671,10 +671,8 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
LLVMAddAttributeAtIndex(func, LLVMAttributeFunctionIndex, LLVMAddAttributeAtIndex(func, LLVMAttributeFunctionIndex,
attr_noinline); attr_noinline);
LLVMValueRef precheck_func = aot_add_precheck_function( if (!aot_build_precheck_function(comp_ctx, module, precheck_func,
comp_ctx, module, func_index, aot_func_type->param_count, func_type, func_index, func_type, func))
func);
if (!precheck_func)
goto fail; goto fail;
LLVMAddAttributeAtIndex(precheck_func, LLVMAttributeFunctionIndex, LLVMAddAttributeAtIndex(precheck_func, LLVMAttributeFunctionIndex,
attr_noinline); attr_noinline);