Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion core/iwasm/aot/aot_intrinsic.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ static const aot_intrinsic g_intrinsic_mapping[] = {
{ "f64_convert_i64_u", "aot_intrinsic_u64_to_f64", AOT_INTRINSIC_FLAG_U64_TO_F64 },
{ "f32_convert_i64_s", "aot_intrinsic_i64_to_f32", AOT_INTRINSIC_FLAG_I64_TO_F32 },
{ "f32_convert_i64_u", "aot_intrinsic_u64_to_f32", AOT_INTRINSIC_FLAG_U64_TO_F32 },
{ "i32_trunc_f64_u", "aot_intrinsic_f64_to_u32", AOT_INTRINSIC_FLAG_I32_TO_F64 },
{ "i32_trunc_f64_u", "aot_intrinsic_f64_to_u32", AOT_INTRINSIC_FLAG_F64_TO_U32 },
{ "i32_trunc_f64_s", "aot_intrinsic_f64_to_i32", AOT_INTRINSIC_FLAG_F64_TO_I32 },
{ "f32_demote_f64", "aot_intrinsic_f64_to_f32", AOT_INTRINSIC_FLAG_F64_TO_F32 },
{ "f64_promote_f32", "aot_intrinsic_f32_to_f64", AOT_INTRINSIC_FLAG_F32_TO_F64 },
{ "f32_cmp", "aot_intrinsic_f32_cmp", AOT_INTRINSIC_FLAG_F32_CMP },
Expand Down
1 change: 1 addition & 0 deletions core/iwasm/aot/aot_reloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ typedef struct {
REG_SYM(aot_intrinsic_i64_to_f64), \
REG_SYM(aot_intrinsic_u64_to_f64), \
REG_SYM(aot_intrinsic_f64_to_f32), \
REG_SYM(aot_intrinsic_f64_to_i32), \
REG_SYM(aot_intrinsic_f64_to_u32), \
REG_SYM(aot_intrinsic_f32_to_f64), \
REG_SYM(aot_intrinsic_f32_cmp), \
Expand Down
54 changes: 54 additions & 0 deletions core/iwasm/compilation/aot_compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -2538,6 +2538,39 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
return false;
}

/* Check whether the target supports hardware atomic instructions */
static bool
aot_require_lower_atomic_pass(AOTCompContext *comp_ctx)
{
bool ret = false;
if (!strncmp(comp_ctx->target_arch, "riscv", 5)) {
char *feature =
LLVMGetTargetMachineFeatureString(comp_ctx->target_machine);

if (feature) {
if (!strstr(feature, "+a")) {
ret = true;
}
LLVMDisposeMessage(feature);
}
}
return ret;
}

/* Check whether the target needs to expand switch to if/else */
static bool
aot_require_lower_switch_pass(AOTCompContext *comp_ctx)
{
bool ret = false;

/* IR switch/case will cause .rodata relocation on riscv */
if (!strncmp(comp_ctx->target_arch, "riscv", 5)) {
ret = true;
}

return ret;
}

bool
aot_compile_wasm(AOTCompContext *comp_ctx)
{
Expand Down Expand Up @@ -2625,6 +2658,27 @@ aot_compile_wasm(AOTCompContext *comp_ctx)
LLVMPassManagerBuilderDispose(pass_mgr_builder);
}

if (comp_ctx->optimize && comp_ctx->is_indirect_mode) {
LLVMPassManagerRef common_pass_mgr = NULL;

if (!(common_pass_mgr = LLVMCreatePassManager())) {
aot_set_last_error("create pass manager failed");
return false;
}

aot_add_expand_memory_op_pass(common_pass_mgr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should check return value


if (aot_require_lower_atomic_pass(comp_ctx))
LLVMAddLowerAtomicPass(common_pass_mgr);

if (aot_require_lower_switch_pass(comp_ctx))
LLVMAddLowerSwitchPass(common_pass_mgr);

LLVMRunPassManager(common_pass_mgr, comp_ctx->module);

LLVMDisposePassManager(common_pass_mgr);
}

return true;
}

Expand Down
134 changes: 119 additions & 15 deletions core/iwasm/compilation/aot_emit_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "aot_emit_memory.h"
#include "aot_emit_exception.h"
#include "../aot/aot_runtime.h"
#include "aot_intrinsic.h"

#define BUILD_ICMP(op, left, right, res, name) \
do { \
Expand Down Expand Up @@ -951,13 +952,66 @@ aot_compile_op_memory_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
if (!(dst_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
return false;

/* TODO: lookup func ptr of "memmove" to call for XIP mode */
if (comp_ctx->is_indirect_mode) {
LLVMTypeRef param_types[3], ret_type, func_type, func_ptr_type;
LLVMValueRef func, params[3];
int32 func_idx;

if (!(res = LLVMBuildMemMove(comp_ctx->builder, dst_addr, 1, src_addr, 1,
len))) {
aot_set_last_error("llvm build memmove failed.");
return false;
if (!(dst_addr =
LLVMBuildBitCast(comp_ctx->builder, dst_addr, INT32_PTR_TYPE,
"memmove dst addr cast type"))) {
aot_set_last_error("llvm cast memmove dst addr type failed.");
return false;
}

if (!(src_addr =
LLVMBuildBitCast(comp_ctx->builder, src_addr, INT32_PTR_TYPE,
"memmove src addr cast type"))) {
aot_set_last_error("llvm cast memmove src addr type failed.");
return false;
}

param_types[0] = INT32_PTR_TYPE;
param_types[1] = INT32_PTR_TYPE;
param_types[2] = I32_TYPE;
ret_type = INT32_PTR_TYPE;

if (!(func_type = LLVMFunctionType(ret_type, param_types, 3, false))) {
aot_set_last_error("create LLVM function type failed.");
return false;
}

if (!(func_ptr_type = LLVMPointerType(func_type, 0))) {
aot_set_last_error("create LLVM function pointer type failed.");
return false;
}

func_idx = aot_get_native_symbol_index(comp_ctx, "memmove");
if (func_idx < 0) {
return false;
}
if (!(func = aot_get_func_from_table(comp_ctx, func_ctx->native_symbol,
func_ptr_type, func_idx))) {
return false;
}

params[0] = dst_addr;
params[1] = src_addr;
params[2] = len;
if (!(res = LLVMBuildCall(comp_ctx->builder, func, params, 3,
"call memmove"))) {
aot_set_last_error("llvm build memmove failed.");
return false;
}
}
else {
if (!(res = LLVMBuildMemMove(comp_ctx->builder, dst_addr, 1, src_addr,
1, len))) {
aot_set_last_error("llvm build memmove failed.");
return false;
}
}

return true;
fail:
return false;
Expand All @@ -981,11 +1035,57 @@ aot_compile_op_memory_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
return false;
}

/* TODO: lookup func ptr of "memset" to call for XIP mode */
if (comp_ctx->is_indirect_mode) {
LLVMTypeRef param_types[3], ret_type, func_type, func_ptr_type;
LLVMValueRef func, params[3];
int32 func_idx;

if (!(res = LLVMBuildMemSet(comp_ctx->builder, dst_addr, val, len, 1))) {
aot_set_last_error("llvm build memset failed.");
return false;
if (!(dst_addr =
LLVMBuildBitCast(comp_ctx->builder, dst_addr, INT32_PTR_TYPE,
"memset dst addr cast type"))) {
aot_set_last_error("llvm cast memset dst addr type failed.");
return false;
}

param_types[0] = INT32_PTR_TYPE;
param_types[1] = INT8_TYPE;
param_types[2] = I32_TYPE;
ret_type = INT32_PTR_TYPE;

if (!(func_type = LLVMFunctionType(ret_type, param_types, 3, false))) {
aot_set_last_error("create LLVM function type failed.");
return false;
}

if (!(func_ptr_type = LLVMPointerType(func_type, 0))) {
aot_set_last_error("create LLVM function pointer type failed.");
return false;
}

func_idx = aot_get_native_symbol_index(comp_ctx, "memset");
if (func_idx < 0) {
return false;
}
if (!(func = aot_get_func_from_table(comp_ctx, func_ctx->native_symbol,
func_ptr_type, func_idx))) {
return false;
}

params[0] = dst_addr;
params[1] = val;
params[2] = len;
if (!(res = LLVMBuildCall(comp_ctx->builder, func, params, 3,
"call memset"))) {
aot_set_last_error("llvm build memset failed.");
return false;
}
}
else {
if (!(res =
LLVMBuildMemSet(comp_ctx->builder, dst_addr, val, len, 1))) {
aot_set_last_error("llvm build memset failed.");
return false;
}
}
return true;
fail:
Expand Down Expand Up @@ -1127,16 +1227,20 @@ aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
}

if (op_type == VALUE_TYPE_I32) {
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE,
"result_i32"))) {
goto fail;
if (LLVMTypeOf(result) != I32_TYPE) {
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE,
"result_i32"))) {
goto fail;
}
}
PUSH_I32(result);
}
else {
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I64_TYPE,
"result_i64"))) {
goto fail;
if (LLVMTypeOf(result) != I64_TYPE) {
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I64_TYPE,
"result_i64"))) {
goto fail;
}
}
PUSH_I64(result);
}
Expand Down
3 changes: 3 additions & 0 deletions core/iwasm/compilation/aot_llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,9 @@ aot_get_func_from_table(const AOTCompContext *comp_ctx, LLVMValueRef base,
bool
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);

void
aot_add_expand_memory_op_pass(LLVMPassManagerRef pass);

#if WASM_ENABLE_LAZY_JIT != 0
void
aot_handle_llvm_errmsg(char *error_buf, uint32 error_buf_size,
Expand Down
Loading