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
* - stack overflow check (if it does, trap)
*/
static LLVMValueRef
aot_add_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
uint32 func_index, uint32 orig_param_count,
LLVMTypeRef func_type, LLVMValueRef wrapped_func)
static bool
aot_build_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
LLVMValueRef precheck_func, uint32 func_index,
LLVMTypeRef func_type, LLVMValueRef wrapped_func)
{
LLVMValueRef precheck_func;
LLVMBasicBlockRef begin = NULL;
LLVMBasicBlockRef check_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;
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");
check_top_block = LLVMAppendBasicBlockInContext(
@ -550,13 +543,13 @@ aot_add_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
}
}
return precheck_func;
return true;
fail:
if (params != NULL) {
wasm_runtime_free(params);
}
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 bool need_precheck =
comp_ctx->enable_stack_bound_check || comp_ctx->enable_stack_estimation;
LLVMValueRef precheck_func;
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
* (the RtlAddFunctionTable stuff)
@ -671,10 +671,8 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
LLVMAddAttributeAtIndex(func, LLVMAttributeFunctionIndex,
attr_noinline);
LLVMValueRef precheck_func = aot_add_precheck_function(
comp_ctx, module, func_index, aot_func_type->param_count, func_type,
func);
if (!precheck_func)
if (!aot_build_precheck_function(comp_ctx, module, precheck_func,
func_index, func_type, func))
goto fail;
LLVMAddAttributeAtIndex(precheck_func, LLVMAttributeFunctionIndex,
attr_noinline);