Compare commits

...

9 Commits

Author SHA1 Message Date
jia xiang
f802f6bd90
Merge d9325b2549 into d053f5534a 2025-05-06 21:30:06 +08:00
dependabot[bot]
d053f5534a
build(deps): Bump github/codeql-action from 3.28.15 to 3.28.17 (#4243)
Some checks are pending
compilation on SGX / build_iwasm (-DWAMR_DISABLE_HW_BOUND_CHECK=1, $FAST_INTERP_BUILD_OPTIONS, ubuntu-22.04, linux-sgx) (push) Waiting to run
compilation on SGX / build_iwasm (-DWAMR_DISABLE_HW_BOUND_CHECK=1, $FAST_JIT_BUILD_OPTIONS, ubuntu-22.04, linux-sgx) (push) Waiting to run
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $AOT_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Blocked by required conditions
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $CLASSIC_INTERP_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Blocked by required conditions
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $FAST_INTERP_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Blocked by required conditions
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $FAST_JIT_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Blocked by required conditions
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, aot, $DEFAULT_TEST_OPTIONS) (push) Blocked by required conditions
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, aot, $SIMD_TEST_OPTIONS) (push) Blocked by required conditions
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, aot, $XIP_TEST_OPTIONS) (push) Blocked by required conditions
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, classic-interp, $DEFAULT_TEST_OPTIONS) (push) Blocked by required conditions
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, fast-jit, $DEFAULT_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / build (-DWAMR_BUILD_AOT=0) (push) Waiting to run
compilation on windows-latest / build (-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_INTERP=0) (push) Waiting to run
compilation on windows-latest / build (-DWAMR_BUILD_CUSTOM_NAME_SECTION=1) (push) Waiting to run
compilation on windows-latest / build (-DWAMR_BUILD_DEBUG_INTERP=1) (push) Waiting to run
compilation on windows-latest / build (-DWAMR_BUILD_LIBC_UVWASI=0 -DWAMR_BUILD_LIBC_WASI=1) (push) Waiting to run
compilation on windows-latest / build (-DWAMR_BUILD_LIB_PTHREAD=1) (push) Waiting to run
compilation on windows-latest / build (-DWAMR_BUILD_LIB_WASI_THREADS=1) (push) Waiting to run
compilation on windows-latest / build (-DWAMR_BUILD_REF_TYPES=1) (push) Waiting to run
compilation on windows-latest / build (-DWAMR_BUILD_SIMD=1) (push) Waiting to run
compilation on windows-latest / build (-DWAMR_BUILD_TAIL_CALL=1) (push) Waiting to run
compilation on windows-latest / build (-DWAMR_DISABLE_HW_BOUND_CHECK=1) (push) Waiting to run
compilation on windows-latest / test (classic-interp, $DEFAULT_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (classic-interp, $MULTI_MODULES_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (classic-interp, $THREADS_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (classic-interp, $WASI_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (fast-interp, $DEFAULT_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (fast-interp, $MULTI_MODULES_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (fast-interp, $THREADS_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (fast-interp, $WASI_TEST_OPTIONS) (push) Blocked by required conditions
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.15 to 3.28.17.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Commits](https://github.com/github/codeql-action/compare/v3.28.15...v3.28.17)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-06 11:16:45 +08:00
YAMAMOTO Takashi
4735956eeb
fix return types of our 64-bit clz/ctz/popcount intrinsics (#4238)
the corresponding LLVM intrinsics' return types are same as
their first argument. eg. i64 for llvm.cttz.i64.
cf. https://llvm.org/docs/LangRef.html#llvm-cttz-intrinsic

this commit changes the return types of our versions of the
intrinsics to match llvm versions as our aot compiler,
specifically __call_llvm_intrinsic, assumes.

strictly speaking, this is a potential AOT ABI change.
however, I suppose it isn't a problem for many of 64-bit ABIs
out there, where (lower half of) a 64-bit register is used to
return a 32-bit value anyway.  (for such ABIs, this commit
would fix the upper 32-bit value of the register.)
2025-05-06 10:15:00 +08:00
liang.he
5910e5cd21
Use --target to pass a triple in wamrc (#4199)
Provide a triple string in the format of <arch>-<vendor>-<os>-<abi>
via --target.
2025-05-06 06:56:06 +08:00
Huang Qi
5bdbba0dbe
platform/nuttx: Fix dcache operation in os_dcache_flush (#4225)
Replace up_invalidate_dcache_all() with up_flush_dcache_all() in
os_dcache_flush() to properly flush the data cache instead of just
invalidating it. This ensures that any modified data in the cache
is written back to memory before execution.

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
2025-05-06 06:55:53 +08:00
YAMAMOTO Takashi
382aa9e6c3
run_clang_format_diff: mention homebrew for clang-format installation (#4237) 2025-05-06 06:55:42 +08:00
YAMAMOTO Takashi
3232bdf2f7
teach aot emitter/loader about .srodata and .srodata.cst* sections (#4240)
LLVM 19 and later started to use srodata ("small read only data")
sections for RISCV.  cf. https://github.com/llvm/llvm-project/pull/82214
this commit makes our aot emitter/loader deal with those sections.

an alternative would be to disable small data sections completely by
setting the "SmallDataLimit" module attribute to zero. however, i feel
this commit is more straightforward and consisitent as we are already
dealing with sdata sections.
2025-05-06 06:55:35 +08:00
xiangjia.xj
d9325b2549 refactor: remove the intermediate addresses in AOTMemInfo 2025-03-10 17:26:16 +08:00
xiangjia.xj
e3dcf4f8ac feature: better memory information restore mechanism 2025-02-25 20:56:33 +08:00
14 changed files with 369 additions and 277 deletions

View File

@ -53,7 +53,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v3.28.15 uses: github/codeql-action/init@v3.28.17
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
@ -70,7 +70,7 @@ jobs:
- run: | - run: |
./.github/scripts/codeql_buildscript.sh ./.github/scripts/codeql_buildscript.sh
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3.28.15 uses: github/codeql-action/analyze@v3.28.17
with: with:
category: "/language:${{matrix.language}}" category: "/language:${{matrix.language}}"
upload: false upload: false
@ -99,7 +99,7 @@ jobs:
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
- name: Upload CodeQL results to code scanning - name: Upload CodeQL results to code scanning
uses: github/codeql-action/upload-sarif@v3.28.15 uses: github/codeql-action/upload-sarif@v3.28.17
with: with:
sarif_file: ${{ steps.step1.outputs.sarif-output }} sarif_file: ${{ steps.step1.outputs.sarif-output }}
category: "/language:${{matrix.language}}" category: "/language:${{matrix.language}}"

View File

@ -60,6 +60,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard. # Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning" - name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 uses: github/codeql-action/upload-sarif@5eb3ed6614230b1931d5c08df9e096e4ba524f21
with: with:
sarif_file: results.sarif sarif_file: results.sarif

View File

@ -98,9 +98,19 @@ def run_clang_format_diff(root: Path, commits: str) -> bool:
code before committing the PR, or it might fail to pass the CI check: code before committing the PR, or it might fail to pass the CI check:
1. Install clang-format-14.0.0 1. Install clang-format-14.0.0
Normally we can install it by `sudo apt-get install clang-format-14`,
or download the package from https://github.com/llvm/llvm-project/releases You can download the package from
and install it https://github.com/llvm/llvm-project/releases
and install it.
For Debian/Ubuntu, we can probably use
`sudo apt-get install clang-format-14`.
Homebrew has it as a part of llvm@14.
```shell
brew install llvm@14
/usr/local/opt/llvm@14/bin/clang-format
```
2. Format the C/C++ source file 2. Format the C/C++ source file
``` shell ``` shell

View File

@ -194,7 +194,7 @@ aot_intrinsic_clz_i32(uint32 type)
return num; return num;
} }
uint32 uint64
aot_intrinsic_clz_i64(uint64 type) aot_intrinsic_clz_i64(uint64 type)
{ {
uint32 num = 0; uint32 num = 0;
@ -220,7 +220,7 @@ aot_intrinsic_ctz_i32(uint32 type)
return num; return num;
} }
uint32 uint64
aot_intrinsic_ctz_i64(uint64 type) aot_intrinsic_ctz_i64(uint64 type)
{ {
uint32 num = 0; uint32 num = 0;
@ -244,7 +244,7 @@ aot_intrinsic_popcnt_i32(uint32 u)
return ret; return ret;
} }
uint32 uint64
aot_intrinsic_popcnt_i64(uint64 u) aot_intrinsic_popcnt_i64(uint64 u)
{ {
uint32 ret = 0; uint32 ret = 0;

View File

@ -186,19 +186,19 @@ aot_intrinsic_fmax_f64(float64 a, float64 b);
uint32 uint32
aot_intrinsic_clz_i32(uint32 type); aot_intrinsic_clz_i32(uint32 type);
uint32 uint64
aot_intrinsic_clz_i64(uint64 type); aot_intrinsic_clz_i64(uint64 type);
uint32 uint32
aot_intrinsic_ctz_i32(uint32 type); aot_intrinsic_ctz_i32(uint32 type);
uint32 uint64
aot_intrinsic_ctz_i64(uint64 type); aot_intrinsic_ctz_i64(uint64 type);
uint32 uint32
aot_intrinsic_popcnt_i32(uint32 u); aot_intrinsic_popcnt_i32(uint32 u);
uint32 uint64
aot_intrinsic_popcnt_i64(uint64 u); aot_intrinsic_popcnt_i64(uint64 u);
float32 float32

View File

@ -3189,10 +3189,12 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
symbol_addr = module->code; symbol_addr = module->code;
} }
else if (!strcmp(symbol, ".data") || !strcmp(symbol, ".sdata") else if (!strcmp(symbol, ".data") || !strcmp(symbol, ".sdata")
|| !strcmp(symbol, ".rdata") || !strcmp(symbol, ".rdata") || !strcmp(symbol, ".rodata")
|| !strcmp(symbol, ".rodata") || !strcmp(symbol, ".srodata")
/* ".rodata.cst4/8/16/.." */ /* ".rodata.cst4/8/16/.." */
|| !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst")) || !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))
/* ".srodata.cst4/8/16/.." */
|| !strncmp(symbol, ".srodata.cst", strlen(".srodata.cst"))
/* ".rodata.strn.m" */ /* ".rodata.strn.m" */
|| !strncmp(symbol, ".rodata.str", strlen(".rodata.str")) || !strncmp(symbol, ".rodata.str", strlen(".rodata.str"))
|| !strcmp(symbol, AOT_STACK_SIZES_SECTION_NAME) || !strcmp(symbol, AOT_STACK_SIZES_SECTION_NAME)

View File

@ -999,6 +999,7 @@ static bool
aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index) aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
{ {
AOTFuncContext *func_ctx = comp_ctx->func_ctxes[func_index]; AOTFuncContext *func_ctx = comp_ctx->func_ctxes[func_index];
WASMModule *module = comp_ctx->comp_data->wasm_module;
LLVMValueRef func_index_ref; LLVMValueRef func_index_ref;
uint8 *frame_ip = func_ctx->aot_func->code, opcode, *p_f32, *p_f64; uint8 *frame_ip = func_ctx->aot_func->code, opcode, *p_f32, *p_f64;
uint8 *frame_ip_end = frame_ip + func_ctx->aot_func->code_size; uint8 *frame_ip_end = frame_ip + func_ctx->aot_func->code_size;
@ -1230,6 +1231,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
read_leb_uint32(frame_ip, frame_ip_end, func_idx); read_leb_uint32(frame_ip, frame_ip_end, func_idx);
if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, false)) if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, false))
return false; return false;
if (module->functions[func_index]->has_memory_operations)
restore_memory_info(comp_ctx, func_ctx);
break; break;
} }
@ -1250,6 +1253,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
if (!aot_compile_op_call_indirect(comp_ctx, func_ctx, type_idx, if (!aot_compile_op_call_indirect(comp_ctx, func_ctx, type_idx,
tbl_idx)) tbl_idx))
return false; return false;
if (module->functions[func_index]->has_memory_operations)
restore_memory_info(comp_ctx, func_ctx);
break; break;
} }
@ -1420,6 +1425,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
if (!aot_compile_op_call_ref(comp_ctx, func_ctx, type_idx, if (!aot_compile_op_call_ref(comp_ctx, func_ctx, type_idx,
false)) false))
return false; return false;
if (module->functions[func_index]->has_memory_operations)
restore_memory_info(comp_ctx, func_ctx);
break; break;
} }
@ -2092,6 +2099,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
read_leb_uint32(frame_ip, frame_ip_end, mem_idx); read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
if (!aot_compile_op_memory_grow(comp_ctx, func_ctx)) if (!aot_compile_op_memory_grow(comp_ctx, func_ctx))
return false; return false;
if (module->functions[func_index]->has_memory_operations)
restore_memory_info(comp_ctx, func_ctx);
break; break;
case WASM_OP_I32_CONST: case WASM_OP_I32_CONST:

View File

@ -648,6 +648,7 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type)
#define SIZE_T_TYPE comp_ctx->basic_types.size_t_type #define SIZE_T_TYPE comp_ctx->basic_types.size_t_type
#define MD_TYPE comp_ctx->basic_types.meta_data_type #define MD_TYPE comp_ctx->basic_types.meta_data_type
#define INT8_PTR_TYPE comp_ctx->basic_types.int8_ptr_type #define INT8_PTR_TYPE comp_ctx->basic_types.int8_ptr_type
#define INT8_PPTR_TYPE comp_ctx->basic_types.int8_pptr_type
#define INT16_PTR_TYPE comp_ctx->basic_types.int16_ptr_type #define INT16_PTR_TYPE comp_ctx->basic_types.int16_ptr_type
#define INT32_PTR_TYPE comp_ctx->basic_types.int32_ptr_type #define INT32_PTR_TYPE comp_ctx->basic_types.int32_ptr_type
#define INT64_PTR_TYPE comp_ctx->basic_types.int64_ptr_type #define INT64_PTR_TYPE comp_ctx->basic_types.int64_ptr_type

View File

@ -3270,8 +3270,17 @@ is_data_section(AOTObjectData *obj_data, LLVMSectionIteratorRef sec_itr,
return (!strcmp(section_name, ".data") || !strcmp(section_name, ".sdata") return (!strcmp(section_name, ".data") || !strcmp(section_name, ".sdata")
|| !strcmp(section_name, ".rodata") || !strcmp(section_name, ".rodata")
#if LLVM_VERSION_MAJOR >= 19
/* https://github.com/llvm/llvm-project/pull/82214 */
|| !strcmp(section_name, ".srodata")
#endif
/* ".rodata.cst4/8/16/.." */ /* ".rodata.cst4/8/16/.." */
|| !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst")) || !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst"))
#if LLVM_VERSION_MAJOR >= 19
/* https://github.com/llvm/llvm-project/pull/82214
* ".srodata.cst4/8/16/.." */
|| !strncmp(section_name, ".srodata.cst", strlen(".srodata.cst"))
#endif
/* ".rodata.strn.m" */ /* ".rodata.strn.m" */
|| !strncmp(section_name, ".rodata.str", strlen(".rodata.str")) || !strncmp(section_name, ".rodata.str", strlen(".rodata.str"))
|| (!strcmp(section_name, ".rdata") || (!strcmp(section_name, ".rdata")

View File

@ -78,9 +78,6 @@ get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return NULL; return NULL;
} }
if (func_ctx->mem_space_unchanged)
return mem_check_bound;
if (!(mem_check_bound = LLVMBuildLoad2( if (!(mem_check_bound = LLVMBuildLoad2(
comp_ctx->builder, comp_ctx->builder,
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE : I32_TYPE, (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE : I32_TYPE,
@ -164,17 +161,15 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* Get memory base address and memory data size */ /* Get memory base address and memory data size */
if (func_ctx->mem_space_unchanged
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
|| is_shared_memory if (is_shared_memory)
#endif
) {
mem_base_addr = func_ctx->mem_info[0].mem_base_addr; mem_base_addr = func_ctx->mem_info[0].mem_base_addr;
} else
else { #endif
{
if (!(mem_base_addr = LLVMBuildLoad2( if (!(mem_base_addr = LLVMBuildLoad2(
comp_ctx->builder, OPQ_PTR_TYPE, comp_ctx->builder, OPQ_PTR_TYPE,
func_ctx->mem_info[0].mem_base_addr, "mem_base"))) { func_ctx->mem_info[0].mem_base_addr, "mem_base_addr"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
goto fail; goto fail;
} }
@ -1015,16 +1010,11 @@ get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{ {
LLVMValueRef mem_size; LLVMValueRef mem_size;
if (func_ctx->mem_space_unchanged) { if (!(mem_size = LLVMBuildLoad2(
mem_size = func_ctx->mem_info[0].mem_cur_page_count_addr; comp_ctx->builder, I32_TYPE,
} func_ctx->mem_info[0].mem_cur_page_count, "mem_size"))) {
else { aot_set_last_error("llvm build load failed.");
if (!(mem_size = LLVMBuildLoad2( goto fail;
comp_ctx->builder, I32_TYPE,
func_ctx->mem_info[0].mem_cur_page_count_addr, "mem_size"))) {
aot_set_last_error("llvm build load failed.");
goto fail;
}
} }
return LLVMBuildIntCast(comp_ctx->builder, mem_size, return LLVMBuildIntCast(comp_ctx->builder, mem_size,
@ -1165,16 +1155,14 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
bool is_shared_memory = comp_ctx->comp_data->memories[0].flags & 0x02; bool is_shared_memory = comp_ctx->comp_data->memories[0].flags & 0x02;
if (func_ctx->mem_space_unchanged || is_shared_memory) { if (is_shared_memory)
#else
if (func_ctx->mem_space_unchanged) {
#endif
mem_base_addr = func_ctx->mem_info[0].mem_base_addr; mem_base_addr = func_ctx->mem_info[0].mem_base_addr;
} else
else { #endif
{
if (!(mem_base_addr = LLVMBuildLoad2( if (!(mem_base_addr = LLVMBuildLoad2(
comp_ctx->builder, OPQ_PTR_TYPE, comp_ctx->builder, OPQ_PTR_TYPE,
func_ctx->mem_info[0].mem_base_addr, "mem_base"))) { func_ctx->mem_info[0].mem_base_addr, "mem_base_addr"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
goto fail; goto fail;
} }
@ -1206,16 +1194,11 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
} }
if (func_ctx->mem_space_unchanged) { if (!(mem_size = LLVMBuildLoad2(
mem_size = func_ctx->mem_info[0].mem_data_size_addr; comp_ctx->builder, I64_TYPE,
} func_ctx->mem_info[0].mem_data_size, "mem_size"))) {
else { aot_set_last_error("llvm build load failed.");
if (!(mem_size = LLVMBuildLoad2( goto fail;
comp_ctx->builder, I64_TYPE,
func_ctx->mem_info[0].mem_data_size_addr, "mem_size"))) {
aot_set_last_error("llvm build load failed.");
goto fail;
}
} }
ADD_BASIC_BLOCK(check_succ, "check_succ"); ADD_BASIC_BLOCK(check_succ, "check_succ");

View File

@ -1186,83 +1186,86 @@ create_local_variables(const AOTCompData *comp_data,
} }
static bool static bool
create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, restore_from_addr(const AOTCompContext *comp_ctx, const char *name,
LLVMTypeRef int8_ptr_type, uint32 func_index) LLVMTypeRef type, LLVMValueRef src, LLVMValueRef dest)
{ {
LLVMValueRef offset, mem_info_base; LLVMValueRef item;
uint32 memory_count; if (!(item = LLVMBuildLoad2(comp_ctx->builder, type, src, name))) {
WASMModule *module = comp_ctx->comp_data->wasm_module; aot_set_last_error("llvm build load failed");
WASMFunction *func = module->functions[func_index];
LLVMTypeRef bound_check_type;
bool mem_space_unchanged =
(!func->has_op_memory_grow && !func->has_op_func_call)
|| (!module->possible_memory_grow);
#if WASM_ENABLE_SHARED_MEMORY != 0
bool is_shared_memory;
#endif
func_ctx->mem_space_unchanged = mem_space_unchanged;
memory_count = module->memory_count + module->import_memory_count;
/* If the module doesn't have memory, reserve
one mem_info space with empty content */
if (memory_count == 0)
memory_count = 1;
if (!(func_ctx->mem_info =
wasm_runtime_malloc(sizeof(AOTMemInfo) * memory_count))) {
return false; return false;
} }
memset(func_ctx->mem_info, 0, sizeof(AOTMemInfo)); if (!LLVMBuildStore(comp_ctx->builder, item, dest)) {
aot_set_last_error("llvm build store failed");
return false;
}
return true;
}
/* Currently we only create memory info for memory 0 */
/* Load memory base address */
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
is_shared_memory = static LLVMValueRef
comp_ctx->comp_data->memories[0].flags & 0x02 ? true : false; aot_get_shared_mem_addr(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{
LLVMValueRef offset, shared_mem_addr;
offset = I32_CONST(offsetof(AOTModuleInstance, memories));
if (!offset) {
aot_set_last_error("create llvm const failed.");
return NULL;
}
/* aot_inst->memories */
if (!(shared_mem_addr = LLVMBuildInBoundsGEP2(
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
"shared_mem_addr_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return NULL;
}
if (!(shared_mem_addr =
LLVMBuildBitCast(comp_ctx->builder, shared_mem_addr,
INT8_PPTR_TYPE, "shared_mem_addr_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return NULL;
}
/* aot_inst->memories[0] */
if (!(shared_mem_addr =
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
shared_mem_addr, "shared_mem_addr"))) {
aot_set_last_error("llvm build load failed");
return NULL;
}
if (!(shared_mem_addr =
LLVMBuildBitCast(comp_ctx->builder, shared_mem_addr,
INT8_PPTR_TYPE, "shared_mem_addr_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return NULL;
}
if (!(shared_mem_addr =
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
shared_mem_addr, "shared_mem_addr"))) {
aot_set_last_error("llvm build load failed");
return NULL;
}
return shared_mem_addr;
}
#endif
bool
restore_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{
LLVMValueRef offset, mem_info_base, mem_base_addr_addr,
mem_cur_page_count_addr, mem_data_size_addr, bound_check_addr;
LLVMTypeRef bound_check_type, bound_check_ptr_type;
#if WASM_ENABLE_SHARED_MEMORY != 0
bool is_shared_memory =
comp_ctx->comp_data->memories[0].flags & 0x02 ? true : false;
if (is_shared_memory) { if (is_shared_memory) {
LLVMValueRef shared_mem_addr; LLVMValueRef shared_mem_addr;
offset = I32_CONST(offsetof(AOTModuleInstance, memories)); if (!(shared_mem_addr = aot_get_shared_mem_addr(comp_ctx, func_ctx)))
if (!offset) {
aot_set_last_error("create llvm const failed.");
return false; return false;
}
/* aot_inst->memories */
if (!(shared_mem_addr = LLVMBuildInBoundsGEP2(
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
"shared_mem_addr_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(shared_mem_addr =
LLVMBuildBitCast(comp_ctx->builder, shared_mem_addr,
int8_ptr_type, "shared_mem_addr_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
/* aot_inst->memories[0] */
if (!(shared_mem_addr =
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
shared_mem_addr, "shared_mem_addr"))) {
aot_set_last_error("llvm build load failed");
return false;
}
if (!(shared_mem_addr =
LLVMBuildBitCast(comp_ctx->builder, shared_mem_addr,
int8_ptr_type, "shared_mem_addr_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (!(shared_mem_addr =
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
shared_mem_addr, "shared_mem_addr"))) {
aot_set_last_error("llvm build load failed");
return false;
}
/* memories[0]->memory_data */ /* memories[0]->memory_data */
offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data)); offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data));
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildInBoundsGEP2( if (!(mem_base_addr_addr = LLVMBuildInBoundsGEP2(
comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1, comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1,
"mem_base_addr_offset"))) { "mem_base_addr_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
@ -1270,16 +1273,15 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* memories[0]->cur_page_count */ /* memories[0]->cur_page_count */
offset = I32_CONST(offsetof(AOTMemoryInstance, cur_page_count)); offset = I32_CONST(offsetof(AOTMemoryInstance, cur_page_count));
if (!(func_ctx->mem_info[0].mem_cur_page_count_addr = if (!(mem_cur_page_count_addr = LLVMBuildInBoundsGEP2(
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1,
shared_mem_addr, &offset, 1, "mem_cur_page_count_offset"))) {
"mem_cur_page_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
return false; return false;
} }
/* memories[0]->memory_data_size */ /* memories[0]->memory_data_size */
offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data_size)); offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data_size));
if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildInBoundsGEP2( if (!(mem_data_size_addr = LLVMBuildInBoundsGEP2(
comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1, comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1,
"mem_data_size_offset"))) { "mem_data_size_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
@ -1300,7 +1302,7 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
offset = I32_CONST(offset_of_global_table_data offset = I32_CONST(offset_of_global_table_data
+ offsetof(AOTMemoryInstance, memory_data)); + offsetof(AOTMemoryInstance, memory_data));
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildInBoundsGEP2( if (!(mem_base_addr_addr = LLVMBuildInBoundsGEP2(
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1, comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
"mem_base_addr_offset"))) { "mem_base_addr_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
@ -1308,16 +1310,15 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
offset = I32_CONST(offset_of_global_table_data offset = I32_CONST(offset_of_global_table_data
+ offsetof(AOTMemoryInstance, cur_page_count)); + offsetof(AOTMemoryInstance, cur_page_count));
if (!(func_ctx->mem_info[0].mem_cur_page_count_addr = if (!(mem_cur_page_count_addr = LLVMBuildInBoundsGEP2(
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
func_ctx->aot_inst, &offset, 1, "mem_cur_page_count_offset"))) {
"mem_cur_page_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
return false; return false;
} }
offset = I32_CONST(offset_of_global_table_data offset = I32_CONST(offset_of_global_table_data
+ offsetof(AOTMemoryInstance, memory_data_size)); + offsetof(AOTMemoryInstance, memory_data_size));
if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildInBoundsGEP2( if (!(mem_data_size_addr = LLVMBuildInBoundsGEP2(
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1, comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
"mem_data_size_offset"))) { "mem_data_size_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
@ -1325,196 +1326,260 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
} }
/* Store mem info base address before cast */ /* Store mem info base address before cast */
mem_info_base = func_ctx->mem_info[0].mem_base_addr; mem_info_base = mem_base_addr_addr;
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildBitCast(
comp_ctx->builder, func_ctx->mem_info[0].mem_base_addr,
int8_ptr_type, "mem_base_addr_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (!(func_ctx->mem_info[0].mem_cur_page_count_addr = LLVMBuildBitCast(
comp_ctx->builder, func_ctx->mem_info[0].mem_cur_page_count_addr,
INT32_PTR_TYPE, "mem_cur_page_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildBitCast(
comp_ctx->builder, func_ctx->mem_info[0].mem_data_size_addr,
INT64_PTR_TYPE, "mem_data_size_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (mem_space_unchanged) {
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad2(
comp_ctx->builder, OPQ_PTR_TYPE,
func_ctx->mem_info[0].mem_base_addr, "mem_base_addr"))) {
aot_set_last_error("llvm build load failed");
return false;
}
if (!(func_ctx->mem_info[0].mem_cur_page_count_addr =
LLVMBuildLoad2(comp_ctx->builder, I32_TYPE,
func_ctx->mem_info[0].mem_cur_page_count_addr,
"mem_cur_page_count"))) {
aot_set_last_error("llvm build load failed");
return false;
}
if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildLoad2(
comp_ctx->builder, I64_TYPE,
func_ctx->mem_info[0].mem_data_size_addr, "mem_data_size"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
else if (is_shared_memory) { if (is_shared_memory) {
/* The base address for shared memory will never changed, /* The base address for shared memory will never changed */
we can load the value here */ }
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad2( else
comp_ctx->builder, OPQ_PTR_TYPE, #endif
func_ctx->mem_info[0].mem_base_addr, "mem_base_addr"))) { {
aot_set_last_error("llvm build load failed"); /* Store mem_info[0].mem_base_addr */
if (!(mem_base_addr_addr = LLVMBuildBitCast(
comp_ctx->builder, mem_base_addr_addr, INT8_PPTR_TYPE,
"mem_base_addr_addr"))) {
aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (!restore_from_addr(
comp_ctx, "mem_base_addr", OPQ_PTR_TYPE, mem_base_addr_addr,
func_ctx->mem_info[0].mem_base_addr))
return false;
} }
#endif
bound_check_type = (comp_ctx->pointer_size == sizeof(uint64)) /* Store mem_info[0].mem_cur_page_count */
? INT64_PTR_TYPE if (!(mem_cur_page_count_addr = LLVMBuildBitCast(
: INT32_PTR_TYPE; comp_ctx->builder, mem_cur_page_count_addr, INT32_PTR_TYPE,
"mem_cur_page_count_addr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (!restore_from_addr(
comp_ctx, "mem_cur_page_count", I32_TYPE, mem_cur_page_count_addr,
func_ctx->mem_info[0].mem_cur_page_count))
return false;
/* Load memory bound check constants */ /* Store mem_info[0].mem_data_size */
if (!(mem_data_size_addr = LLVMBuildBitCast(
comp_ctx->builder, mem_data_size_addr, INT64_PTR_TYPE,
"mem_data_size_addr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (!restore_from_addr(
comp_ctx, "mem_data_size", I64_TYPE, mem_data_size_addr,
func_ctx->mem_info[0].mem_data_size))
return false;
/* Store memory bound check constants */
bound_check_type = (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE
: I32_TYPE;
bound_check_ptr_type = (comp_ctx->pointer_size == sizeof(uint64))
? INT64_PTR_TYPE
: INT32_PTR_TYPE;
/* Store mem_info[0].mem_bound_check_1byte */
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_1byte) offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_1byte)
- offsetof(AOTMemoryInstance, memory_data)); - offsetof(AOTMemoryInstance, memory_data));
if (!(func_ctx->mem_info[0].mem_bound_check_1byte = if (!(bound_check_addr = LLVMBuildInBoundsGEP2(
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base, comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
&offset, 1, "bound_check_1byte_offset"))) { "bound_check_1byte_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
return false; return false;
} }
if (!(func_ctx->mem_info[0].mem_bound_check_1byte = LLVMBuildBitCast( if (!(bound_check_addr = LLVMBuildBitCast(
comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_1byte, comp_ctx->builder, bound_check_addr, bound_check_ptr_type,
bound_check_type, "bound_check_1byte_ptr"))) { "bound_check_1byte_addr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (mem_space_unchanged) { if (!restore_from_addr(
if (!(func_ctx->mem_info[0].mem_bound_check_1byte = LLVMBuildLoad2( comp_ctx, "mem_bound_check_1byte", bound_check_type,
comp_ctx->builder, bound_check_addr, func_ctx->mem_info[0].mem_bound_check_1byte))
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE return false;
: I32_TYPE,
func_ctx->mem_info[0].mem_bound_check_1byte,
"bound_check_1byte"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
/* Store mem_info[0].mem_bound_check_2bytes */
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_2bytes) offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_2bytes)
- offsetof(AOTMemoryInstance, memory_data)); - offsetof(AOTMemoryInstance, memory_data));
if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = if (!(bound_check_addr = LLVMBuildInBoundsGEP2(
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base, comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
&offset, 1, "bound_check_2bytes_offset"))) { "bound_check_2bytes_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
return false; return false;
} }
if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = LLVMBuildBitCast( if (!(bound_check_addr = LLVMBuildBitCast(
comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_2bytes, comp_ctx->builder, bound_check_addr, bound_check_ptr_type,
bound_check_type, "bound_check_2bytes_ptr"))) { "bound_check_2bytes_addr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (mem_space_unchanged) { if (!restore_from_addr(
if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = LLVMBuildLoad2( comp_ctx, "mem_bound_check_2bytes", bound_check_type,
comp_ctx->builder, bound_check_addr, func_ctx->mem_info[0].mem_bound_check_2bytes))
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE return false;
: I32_TYPE,
func_ctx->mem_info[0].mem_bound_check_2bytes,
"bound_check_2bytes"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
/* Store mem_info[0].mem_bound_check_4bytes */
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_4bytes) offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_4bytes)
- offsetof(AOTMemoryInstance, memory_data)); - offsetof(AOTMemoryInstance, memory_data));
if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = if (!(bound_check_addr = LLVMBuildInBoundsGEP2(
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base, comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
&offset, 1, "bound_check_4bytes_offset"))) { "bound_check_4bytes_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
return false; return false;
} }
if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = LLVMBuildBitCast( if (!(bound_check_addr = LLVMBuildBitCast(
comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_4bytes, comp_ctx->builder, bound_check_addr, bound_check_ptr_type,
bound_check_type, "bound_check_4bytes_ptr"))) { "bound_check_4bytes_addr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (mem_space_unchanged) { if (!restore_from_addr(
if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = LLVMBuildLoad2( comp_ctx, "mem_bound_check_4bytes", bound_check_type,
comp_ctx->builder, bound_check_addr, func_ctx->mem_info[0].mem_bound_check_4bytes))
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE return false;
: I32_TYPE,
func_ctx->mem_info[0].mem_bound_check_4bytes,
"bound_check_4bytes"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
/* Store mem_info[0].mem_bound_check_8bytes */
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_8bytes) offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_8bytes)
- offsetof(AOTMemoryInstance, memory_data)); - offsetof(AOTMemoryInstance, memory_data));
if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = if (!(bound_check_addr = LLVMBuildInBoundsGEP2(
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base, comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
&offset, 1, "bound_check_8bytes_offset"))) { "bound_check_8bytes_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
return false; return false;
} }
if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = LLVMBuildBitCast( if (!(bound_check_addr = LLVMBuildBitCast(
comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_8bytes, comp_ctx->builder, bound_check_addr, bound_check_ptr_type,
bound_check_type, "bound_check_8bytes_ptr"))) { "bound_check_8bytes_addr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (mem_space_unchanged) { if (!restore_from_addr(
if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = LLVMBuildLoad2( comp_ctx, "mem_bound_check_8bytes", bound_check_type,
comp_ctx->builder, bound_check_addr, func_ctx->mem_info[0].mem_bound_check_8bytes))
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE return false;
: I32_TYPE,
func_ctx->mem_info[0].mem_bound_check_8bytes,
"bound_check_8bytes"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
/* Store mem_info[0].mem_bound_check_16bytes */
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_16bytes) offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_16bytes)
- offsetof(AOTMemoryInstance, memory_data)); - offsetof(AOTMemoryInstance, memory_data));
if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildInBoundsGEP2( if (!(bound_check_addr = LLVMBuildInBoundsGEP2(
comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1, comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
"bound_check_16bytes_offset"))) { "bound_check_16bytes_offset"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
return false; return false;
} }
if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildBitCast( if (!(bound_check_addr = LLVMBuildBitCast(
comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_16bytes, comp_ctx->builder, bound_check_addr, bound_check_ptr_type,
bound_check_type, "bound_check_16bytes_ptr"))) { "bound_check_16bytes_addr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (mem_space_unchanged) { if (!restore_from_addr(
if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildLoad2( comp_ctx, "mem_bound_check_16bytes", bound_check_type,
comp_ctx->builder, bound_check_addr, func_ctx->mem_info[0].mem_bound_check_16bytes))
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE return false;
: I32_TYPE,
func_ctx->mem_info[0].mem_bound_check_16bytes, return true;
"bound_check_16bytes"))) { }
static bool
create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 func_index)
{
LLVMValueRef offset;
uint32 memory_count;
WASMModule *module = comp_ctx->comp_data->wasm_module;
LLVMTypeRef bound_check_type;
#if WASM_ENABLE_SHARED_MEMORY != 0
bool is_shared_memory;
#endif
memory_count = module->memory_count + module->import_memory_count;
/* If the module doesn't have memory, reserve
one mem_info space with empty content */
if (memory_count == 0)
memory_count = 1;
if (!(func_ctx->mem_info =
wasm_runtime_malloc(sizeof(AOTMemInfo) * memory_count))) {
return false;
}
memset(func_ctx->mem_info, 0, sizeof(AOTMemInfo));
/* Currently we only create memory info for memory 0 */
/* Load memory base address */
#if WASM_ENABLE_SHARED_MEMORY != 0
is_shared_memory =
comp_ctx->comp_data->memories[0].flags & 0x02 ? true : false;
if (is_shared_memory) {
LLVMValueRef shared_mem_addr, mem_base_addr_addr;
if (!(shared_mem_addr = aot_get_shared_mem_addr(comp_ctx, func_ctx)))
return false;
/* memories[0]->memory_data */
offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data));
if (!(mem_base_addr_addr = LLVMBuildInBoundsGEP2(
comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1,
"mem_base_addr_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
/* The base address for shared memory will never changed,
we can load the value here */
if (!(func_ctx->mem_info[0].mem_base_addr =
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
mem_base_addr_addr, "mem_base_addr"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
return false; return false;
} }
} }
else
#endif
{
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildAlloca(
comp_ctx->builder, OPQ_PTR_TYPE, "mem_base_addr"))) {
aot_set_last_error("llvm build alloca failed.");
return false;
}
}
if (!(func_ctx->mem_info[0].mem_data_size = LLVMBuildAlloca(
comp_ctx->builder, I64_TYPE, "mem_data_size"))) {
aot_set_last_error("llvm build alloca failed.");
return false;
}
if (!(func_ctx->mem_info[0].mem_cur_page_count = LLVMBuildAlloca(
comp_ctx->builder, I32_TYPE, "mem_cur_page_count"))) {
aot_set_last_error("llvm build alloca failed.");
return false;
}
bound_check_type = (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE
: I32_TYPE;
if (!(func_ctx->mem_info[0].mem_bound_check_1byte = LLVMBuildAlloca(
comp_ctx->builder, bound_check_type, "mem_bound_check_1byte"))) {
aot_set_last_error("llvm build alloca failed.");
return false;
}
if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = LLVMBuildAlloca(
comp_ctx->builder, bound_check_type, "mem_bound_check_2bytes"))) {
aot_set_last_error("llvm build alloca failed.");
return false;
}
if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = LLVMBuildAlloca(
comp_ctx->builder, bound_check_type, "mem_bound_check_4bytes"))) {
aot_set_last_error("llvm build alloca failed.");
return false;
}
if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = LLVMBuildAlloca(
comp_ctx->builder, bound_check_type, "mem_bound_check_8bytes"))) {
aot_set_last_error("llvm build alloca failed.");
return false;
}
if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildAlloca(
comp_ctx->builder, bound_check_type, "mem_bound_check_16bytes"))) {
aot_set_last_error("llvm build alloca failed.");
return false;
}
return true; return restore_memory_info(comp_ctx, func_ctx);
} }
static bool static bool
@ -1785,7 +1850,6 @@ aot_create_func_context(const AOTCompData *comp_data, AOTCompContext *comp_ctx,
WASMModule *module = comp_ctx->comp_data->wasm_module; WASMModule *module = comp_ctx->comp_data->wasm_module;
WASMFunction *wasm_func = module->functions[func_index]; WASMFunction *wasm_func = module->functions[func_index];
AOTBlock *aot_block; AOTBlock *aot_block;
LLVMTypeRef int8_ptr_type;
uint64 size; uint64 size;
/* Allocate memory for the function context */ /* Allocate memory for the function context */
@ -1849,14 +1913,9 @@ aot_create_func_context(const AOTCompData *comp_data, AOTCompContext *comp_ctx,
goto fail; goto fail;
} }
if (!(int8_ptr_type = LLVMPointerType(INT8_PTR_TYPE, 0))) {
aot_set_last_error("llvm add pointer type failed.");
goto fail;
}
/* Create base addr, end addr, data size of mem, heap */ /* Create base addr, end addr, data size of mem, heap */
if (wasm_func->has_memory_operations if (wasm_func->has_memory_operations
&& !create_memory_info(comp_ctx, func_ctx, int8_ptr_type, func_index)) { && !create_memory_info(comp_ctx, func_ctx, func_index)) {
goto fail; goto fail;
} }
@ -2742,10 +2801,23 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
} }
else { else {
/* Create LLVM target machine */ /* Create LLVM target machine */
arch = option->target_arch; if (!option->target_arch || !strstr(option->target_arch, "-")) {
abi = option->target_abi; /* Retrieve the target triple based on user input */
cpu = option->target_cpu; triple = NULL;
features = option->cpu_features; arch = option->target_arch;
abi = option->target_abi;
cpu = option->target_cpu;
features = option->cpu_features;
}
else {
/* Form a target triple */
triple = option->target_arch;
arch = NULL;
abi = NULL;
cpu = NULL;
features = NULL;
}
opt_level = option->opt_level; opt_level = option->opt_level;
size_level = option->size_level; size_level = option->size_level;
@ -2986,6 +3058,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
aot_set_last_error(buf); aot_set_last_error(buf);
goto fail; goto fail;
} }
LOG_VERBOSE("triple: %s => normailized: %s", triple, triple_norm);
if (!cpu) if (!cpu)
cpu = ""; cpu = "";
} }

View File

@ -215,8 +215,8 @@ typedef struct AOTCheckedAddr {
typedef struct AOTMemInfo { typedef struct AOTMemInfo {
LLVMValueRef mem_base_addr; LLVMValueRef mem_base_addr;
LLVMValueRef mem_data_size_addr; LLVMValueRef mem_data_size;
LLVMValueRef mem_cur_page_count_addr; LLVMValueRef mem_cur_page_count;
LLVMValueRef mem_bound_check_1byte; LLVMValueRef mem_bound_check_1byte;
LLVMValueRef mem_bound_check_2bytes; LLVMValueRef mem_bound_check_2bytes;
LLVMValueRef mem_bound_check_4bytes; LLVMValueRef mem_bound_check_4bytes;
@ -251,7 +251,6 @@ typedef struct AOTFuncContext {
LLVMValueRef wasm_stack_top_bound; LLVMValueRef wasm_stack_top_bound;
LLVMValueRef wasm_stack_top_ptr; LLVMValueRef wasm_stack_top_ptr;
bool mem_space_unchanged;
AOTCheckedAddrList checked_addr_list; AOTCheckedAddrList checked_addr_list;
LLVMValueRef shared_heap_base_addr_adj; LLVMValueRef shared_heap_base_addr_adj;
@ -656,6 +655,9 @@ unsigned int
aot_estimate_stack_usage_for_function_call(const AOTCompContext *comp_ctx, aot_estimate_stack_usage_for_function_call(const AOTCompContext *comp_ctx,
const AOTFuncType *callee_func_type); const AOTFuncType *callee_func_type);
bool
restore_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #endif

View File

@ -118,7 +118,7 @@ os_dcache_flush()
up_textheap_data_sync(); up_textheap_data_sync();
#endif #endif
#ifndef CONFIG_BUILD_KERNEL #ifndef CONFIG_BUILD_KERNEL
up_invalidate_dcache_all(); up_flush_dcache_all();
#endif #endif
} }

View File

@ -116,6 +116,9 @@ print_help()
printf(" Default is host arch, e.g. x86_64\n"); printf(" Default is host arch, e.g. x86_64\n");
printf(" <sub> = for ex. on arm or thumb: v5, v6m, v7a, v7m, etc.\n"); printf(" <sub> = for ex. on arm or thumb: v5, v6m, v7a, v7m, etc.\n");
printf(" Use --target=help to list supported targets\n"); printf(" Use --target=help to list supported targets\n");
printf(" Or, provide a triple in the format of <arch>-<vendor>-<os>-<abi>.\n");
printf(" By doing this, --target-abi, --cpu, and --cpu-features will be ignored.\n");
printf(" The triple will only be normalized without any further verification.\n");
printf(" --target-abi=<abi> Set the target ABI, e.g. gnu, eabi, gnueabihf, msvc, etc.\n"); printf(" --target-abi=<abi> Set the target ABI, e.g. gnu, eabi, gnueabihf, msvc, etc.\n");
printf(" Default is gnu if target isn't riscv64 or riscv32\n"); printf(" Default is gnu if target isn't riscv64 or riscv32\n");
printf(" For target riscv64 and riscv32, default is lp64d and ilp32d\n"); printf(" For target riscv64 and riscv32, default is lp64d and ilp32d\n");