Make heap and linear memory contiguous to refine compilation time and footprint (#233)

Use FastISel for JIT mode
Use united aot version in aot file and aot runtime
Disable check signature failed warning for wamrc
Fix fast interpreter x86_32 float issue
Remove unused empty lvgl folder
This commit is contained in:
wenyongh
2020-04-13 10:49:40 +08:00
committed by GitHub
parent ffd975d2d6
commit b40e79c160
27 changed files with 983 additions and 755 deletions

View File

@ -821,13 +821,14 @@ aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
AOTCompData *comp_data, AOTObjectData *obj_data)
{
uint32 offset = *p_offset;
uint32 aot_curr_version = AOT_CURRENT_VERSION;
EMIT_U8('\0');
EMIT_U8('a');
EMIT_U8('o');
EMIT_U8('t');
EMIT_U32(1);
EMIT_U32(aot_curr_version);
*p_offset = offset;
return true;

View File

@ -143,20 +143,19 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef ret_type, uint8 wasm_ret_type,
LLVMValueRef *p_value_ret, LLVMValueRef *p_res)
{
LLVMTypeRef func_type, func_ptr_type, func_param_types[5];
LLVMTypeRef func_type, func_ptr_type, func_param_types[4];
LLVMTypeRef ret_ptr_type, elem_ptr_type;
LLVMValueRef func, elem_idx, elem_ptr;
LLVMValueRef func_param_values[5], value_ret = NULL, value_ret_ptr, res;
LLVMValueRef func_param_values[4], value_ret = NULL, res;
char buf[32], *func_name = "aot_invoke_native";
uint32 i, cell_num = 0;
/* prepare function type of aot_invoke_native */
func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */
func_param_types[1] = I32_TYPE; /* func_idx */
func_param_types[2] = INT32_PTR_TYPE; /* frame_lp */
func_param_types[3] = I32_TYPE; /* argc */
func_param_types[4] = INT32_PTR_TYPE; /* argv_ret */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 5, false))) {
func_param_types[2] = I32_TYPE; /* argc */
func_param_types[3] = INT32_PTR_TYPE; /* argv */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 4, false))) {
aot_set_last_error("llvm add function type failed.");
return false;
}
@ -216,6 +215,24 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
cell_num += wasm_value_type_cell_num(aot_func_type->types[i]);
}
func_param_values[0] = func_ctx->exec_env;
func_param_values[1] = func_idx;
func_param_values[2] = I32_CONST(param_cell_num);
func_param_values[3] = func_ctx->argv_buf;
if (!func_param_values[2]) {
aot_set_last_error("llvm create const failed.");
return false;
}
/* call aot_invoke_native() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func,
func_param_values, 4, "res"))) {
aot_set_last_error("llvm build call failed.");
return false;
}
/* get function return value */
if (wasm_ret_type != VALUE_TYPE_VOID) {
if (!(ret_ptr_type = LLVMPointerType(ret_type, 0))) {
aot_set_last_error("llvm add pointer type failed.");
@ -227,39 +244,12 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("llvm build bit cast failed.");
return false;
}
/* convert to int32 pointer */
if (!(value_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, value_ret,
INT32_PTR_TYPE, "argv_ret_ptr"))) {
aot_set_last_error("llvm build store failed.");
if (!(*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret,
"value_ret"))) {
aot_set_last_error("llvm build load failed.");
return false;
}
}
else {
value_ret_ptr = LLVMConstNull(INT32_PTR_TYPE);
}
func_param_values[0] = func_ctx->exec_env;
func_param_values[1] = func_idx;
func_param_values[2] = func_ctx->argv_buf;
func_param_values[3] = I32_CONST(param_cell_num);
func_param_values[4] = value_ret_ptr;
if (!func_param_values[3]) {
aot_set_last_error("llvm create const failed.");
return false;
}
/* call aot_invoke_native() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func,
func_param_values, 5, "res"))) {
aot_set_last_error("llvm build call failed.");
return false;
}
if (wasm_ret_type != VALUE_TYPE_VOID)
/* get function return value */
*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret, "value_ret");
*p_res = res;
return true;
@ -395,10 +385,10 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef ret_type, uint8 wasm_ret_type,
LLVMValueRef *p_value_ret, LLVMValueRef *p_res)
{
LLVMTypeRef func_type, func_ptr_type, func_param_types[7];
LLVMTypeRef func_type, func_ptr_type, func_param_types[6];
LLVMTypeRef ret_ptr_type, elem_ptr_type;
LLVMValueRef func, elem_idx, elem_ptr;
LLVMValueRef func_param_values[7], value_ret = NULL, value_ret_ptr, res = NULL;
LLVMValueRef func_param_values[6], value_ret = NULL, res = NULL;
char buf[32], *func_name = "aot_call_indirect";
uint32 i, cell_num = 0;
@ -407,10 +397,9 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
func_param_types[1] = INT8_TYPE; /* check_func_type */
func_param_types[2] = I32_TYPE; /* func_type_idx */
func_param_types[3] = I32_TYPE; /* table_elem_idx */
func_param_types[4] = INT32_PTR_TYPE; /* frame_lp */
func_param_types[5] = I32_TYPE; /* argc */
func_param_types[6] = INT32_PTR_TYPE; /* argv_ret */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 7, false))) {
func_param_types[4] = I32_TYPE; /* argc */
func_param_types[5] = INT32_PTR_TYPE; /* argv */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 6, false))) {
aot_set_last_error("llvm add function type failed.");
return false;
}
@ -470,6 +459,26 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
cell_num += wasm_value_type_cell_num(aot_func_type->types[i]);
}
func_param_values[0] = func_ctx->exec_env;
func_param_values[1] = I8_CONST(true);
func_param_values[2] = func_type_idx;
func_param_values[3] = table_elem_idx;
func_param_values[4] = I32_CONST(param_cell_num);
func_param_values[5] = func_ctx->argv_buf;
if (!func_param_values[1] || !func_param_values[4]) {
aot_set_last_error("llvm create const failed.");
return false;
}
/* call aot_call_indirect() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func,
func_param_values, 6, "res"))) {
aot_set_last_error("llvm build call failed.");
return false;
}
/* get function return value */
if (wasm_ret_type != VALUE_TYPE_VOID) {
if (!(ret_ptr_type = LLVMPointerType(ret_type, 0))) {
aot_set_last_error("llvm add pointer type failed.");
@ -482,40 +491,12 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false;
}
/* convert to int32 pointer */
if (!(value_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, value_ret,
INT32_PTR_TYPE, "argv_ret_ptr"))) {
aot_set_last_error("llvm build store failed.");
if (!(*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret,
"value_ret"))) {
aot_set_last_error("llvm build load failed.");
return false;
}
}
else {
value_ret_ptr = LLVMConstNull(INT32_PTR_TYPE);
}
func_param_values[0] = func_ctx->exec_env;
func_param_values[1] = I8_CONST(true);
func_param_values[2] = func_type_idx;
func_param_values[3] = table_elem_idx;
func_param_values[4] = func_ctx->argv_buf;
func_param_values[5] = I32_CONST(param_cell_num);
func_param_values[6] = value_ret_ptr;
if (!func_param_values[1] || !func_param_values[4]) {
aot_set_last_error("llvm create const failed.");
return false;
}
/* call aot_call_indirect() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func,
func_param_values, 7, "res"))) {
aot_set_last_error("llvm build call failed.");
return false;
}
if (wasm_ret_type != VALUE_TYPE_VOID)
/* get function return value */
*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret, "value_ret");
*p_res = res;
return true;

View File

@ -23,14 +23,6 @@
} \
} while (0)
#define BUILD_COND_BR(cmp_val, then_block, else_block) do { \
if (!LLVMBuildCondBr(comp_ctx->builder, cmp_val, \
then_block, else_block)) { \
aot_set_last_error("llvm build cond br failed."); \
goto fail; \
} \
} while (0)
#define ADD_BASIC_BLOCK(block, name) do { \
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
func_ctx->func, \
@ -43,53 +35,88 @@
#define SET_BUILD_POS(block) \
LLVMPositionBuilderAtEnd(comp_ctx->builder, block)
static LLVMValueRef
get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 bytes)
{
LLVMValueRef mem_check_bound = NULL;
switch (bytes) {
case 1:
mem_check_bound = func_ctx->mem_bound_check_1byte;
break;
case 2:
mem_check_bound = func_ctx->mem_bound_check_2bytes;
break;
case 4:
mem_check_bound = func_ctx->mem_bound_check_4bytes;
break;
case 8:
mem_check_bound = func_ctx->mem_bound_check_8bytes;
break;
default:
bh_assert(0);
return NULL;
}
if (func_ctx->mem_space_unchanged)
return mem_check_bound;
if (!(mem_check_bound = LLVMBuildLoad(comp_ctx->builder,
mem_check_bound,
"mem_check_bound"))) {
aot_set_last_error("llvm build load failed.");
return NULL;
}
return mem_check_bound;
}
static LLVMValueRef
check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 offset, uint32 bytes)
{
LLVMValueRef offset_const = I32_CONST(offset);
LLVMValueRef size_const = I32_CONST(bytes);
LLVMValueRef addr, maddr, moffset;
LLVMValueRef cmp, phi;
LLVMValueRef mem_base_addr, mem_data_size;
LLVMValueRef heap_base_addr, heap_base_offset;
LLVMValueRef mem_offset_max = NULL, heap_offset_max = NULL;
LLVMBasicBlockRef check_mem_space, check_heap_space, check_succ;
LLVMValueRef bytes_const = I32_CONST(bytes);
LLVMValueRef bytes64_const = I64_CONST(bytes);
LLVMValueRef heap_base_offset = func_ctx->heap_base_offset;
LLVMValueRef addr, maddr, offset1, offset2, cmp;
LLVMValueRef mem_base_addr, mem_check_bound, total_mem_size;
LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
LLVMBasicBlockRef check_succ, check_mem_space;
CHECK_LLVM_CONST(offset_const);
CHECK_LLVM_CONST(size_const);
CHECK_LLVM_CONST(bytes_const);
CHECK_LLVM_CONST(bytes64_const);
heap_base_addr = func_ctx->heap_base_addr;
heap_base_offset = func_ctx->heap_base_offset;
/* Get memory base address and memory data size */
if (func_ctx->mem_space_unchanged) {
mem_base_addr = func_ctx->mem_base_addr;
}
else {
if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_base_addr,
"mem_base"))) {
aot_set_last_error("llvm build load failed.");
goto fail;
}
}
POP_I32(addr);
BUILD_OP(Add, offset_const, addr, moffset, "moffset");
/* offset1 = offset + addr; */
BUILD_OP(Add, offset_const, addr, offset1, "offset1");
/* return addres directly if constant offset and inside memory space */
if (LLVMIsConstant(moffset)) {
uint32 memory_offset = (uint32)LLVMConstIntGetZExtValue(moffset);
if (LLVMIsConstant(offset1)) {
uint32 mem_offset = (uint32)LLVMConstIntGetZExtValue(offset1);
uint32 num_bytes_per_page = comp_ctx->comp_data->num_bytes_per_page;
uint32 init_page_count = comp_ctx->comp_data->mem_init_page_count;
if (init_page_count > 0
&& memory_offset <= comp_ctx->comp_data->num_bytes_per_page
* init_page_count - bytes) {
uint32 mem_data_size = num_bytes_per_page * init_page_count;
if (mem_data_size > 0
&& mem_offset <= mem_data_size - bytes) {
/* inside memory space */
if (!func_ctx->mem_space_unchanged) {
if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_base_addr,
"mem_base"))) {
aot_set_last_error("llvm build load failed.");
return NULL;
}
}
else {
mem_base_addr = func_ctx->mem_base_addr;
}
/* maddr = mem_base_addr + moffset */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder,
mem_base_addr,
&moffset, 1, "maddr"))) {
&offset1, 1, "maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
}
@ -97,136 +124,63 @@ check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
}
/* Add basic blocks */
ADD_BASIC_BLOCK(check_heap_space, "check_heap_space");
ADD_BASIC_BLOCK(check_succ, "check_succ");
LLVMMoveBasicBlockAfter(check_heap_space, block_curr);
LLVMMoveBasicBlockAfter(check_succ, check_heap_space);
/* Add return maddress phi for check_succ block */
SET_BUILD_POS(check_succ);
if (!(phi = LLVMBuildPhi(comp_ctx->builder,
INT8_PTR_TYPE, "maddr_phi"))) {
aot_set_last_error("llvm build phi failed.");
goto fail;
}
SET_BUILD_POS(block_curr);
/* Get memory data size */
if (!func_ctx->mem_space_unchanged) {
if (!(mem_data_size = LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_data_size,
"mem_data_size"))) {
aot_set_last_error("llvm build load failed.");
return NULL;
}
}
else {
mem_data_size = func_ctx->mem_data_size;
}
if (comp_ctx->comp_data->mem_init_page_count == 0) {
/* Get total memory size */
if (func_ctx->mem_space_unchanged) {
total_mem_size = func_ctx->total_mem_size;
}
else {
if (!(total_mem_size = LLVMBuildLoad(comp_ctx->builder,
func_ctx->total_mem_size,
"total_mem_size"))) {
aot_set_last_error("llvm build load failed.");
goto fail;
}
}
ADD_BASIC_BLOCK(check_mem_space, "check_mem_space");
LLVMMoveBasicBlockAfter(check_mem_space, block_curr);
/* if mem_data_size is zero, check heap space */
BUILD_ICMP(LLVMIntEQ, mem_data_size, I32_ZERO, cmp,
"cmp_mem_data_size");
BUILD_COND_BR(cmp, check_heap_space, check_mem_space);
/* if total_mem_size is zero, boundary check fail */
BUILD_ICMP(LLVMIntEQ, total_mem_size, I32_ZERO, cmp,
"cmp_total_mem_size");
if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
true, cmp, check_mem_space)) {
goto fail;
}
SET_BUILD_POS(check_mem_space);
}
/* Get memory base address */
if (!func_ctx->mem_space_unchanged) {
if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_base_addr,
"mem_base"))) {
aot_set_last_error("llvm build load failed.");
return NULL;
}
}
else {
mem_base_addr = func_ctx->mem_base_addr;
}
/* offset2 = offset1 - heap_base_offset; */
BUILD_OP(Sub, offset1, heap_base_offset, offset2, "offset2");
/* maddr = mem_base_addr + moffset */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr,
&moffset, 1, "maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
}
block_curr = LLVMGetInsertBlock(comp_ctx->builder);
LLVMAddIncoming(phi, &maddr, &block_curr, 1);
if (!func_ctx->mem_space_unchanged) {
/* mem_offset_max = mem_data_size - bytes to load/read */
if (!(mem_offset_max = LLVMBuildSub(comp_ctx->builder,
mem_data_size, size_const,
"mem_offset_max"))) {
aot_set_last_error("llvm build sub failed.");
goto fail;
}
}
else {
if (bytes == 1)
mem_offset_max = func_ctx->mem_bound_1_byte;
else if (bytes == 2)
mem_offset_max = func_ctx->mem_bound_2_bytes;
else if (bytes == 4)
mem_offset_max = func_ctx->mem_bound_4_bytes;
else if (bytes == 8)
mem_offset_max = func_ctx->mem_bound_8_bytes;
}
/* in linear memory if (uint32)moffset <= (uint32)mem_offset_max,
else check heap space */
BUILD_ICMP(LLVMIntULE, moffset, mem_offset_max, cmp, "cmp_mem_offset");
/* Create condtion br */
BUILD_COND_BR(cmp, check_succ, check_heap_space);
/* Start to translate the check_heap_space block */
SET_BUILD_POS(check_heap_space);
/* moffset -= heap_base_offset */
if (!(moffset = LLVMBuildSub(comp_ctx->builder,
moffset, heap_base_offset,
"moffset_to_heap"))) {
aot_set_last_error("llvm build sub failed.");
if (!(mem_check_bound =
get_memory_check_bound(comp_ctx, func_ctx, bytes))) {
goto fail;
}
/* maddr = heap_base_addr + moffset */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, heap_base_addr,
&moffset, 1, "maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
}
block_curr = LLVMGetInsertBlock(comp_ctx->builder);
LLVMAddIncoming(phi, &maddr, &block_curr, 1);
/* Add basic blocks */
ADD_BASIC_BLOCK(check_succ, "check_succ");
LLVMMoveBasicBlockAfter(check_succ, block_curr);
/* heap space base addr and size is unchanged,
the heap boundary is unchanged also. */
if (bytes == 1)
heap_offset_max = func_ctx->heap_bound_1_byte;
else if (bytes == 2)
heap_offset_max = func_ctx->heap_bound_2_bytes;
else if (bytes == 4)
heap_offset_max = func_ctx->heap_bound_4_bytes;
else if (bytes == 8)
heap_offset_max = func_ctx->heap_bound_8_bytes;
/* in heap space if (uint32)moffset <= (uint32)heap_offset_max,
else throw exception */
BUILD_ICMP(LLVMIntUGT, moffset, heap_offset_max, cmp, "cmp_heap_offset");
/* offset2 > bound ? */
BUILD_ICMP(LLVMIntUGT, offset2, mem_check_bound, cmp, "cmp");
if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
true, cmp, check_succ))
true, cmp, check_succ)) {
goto fail;
}
SET_BUILD_POS(check_succ);
return phi;
/* maddr = mem_base_addr + offset1 */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr,
&offset1, 1, "maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
}
return maddr;
fail:
return NULL;
}

View File

@ -105,7 +105,7 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTCompData *comp_data = comp_ctx->comp_data;
uint32 import_global_count = comp_data->import_global_count;
uint32 global_base_offset = offsetof(AOTModuleInstance,
global_table_heap_data.bytes);
global_table_data.bytes);
uint32 global_offset;
uint8 global_type;
LLVMValueRef offset, global_ptr, global;

View File

@ -181,68 +181,117 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
}
/* Load memory data size */
offset = I32_CONST(offsetof(AOTModuleInstance, memory_data_size));
if (!(func_ctx->mem_data_size =
/* Load total memory size */
offset = I32_CONST(offsetof(AOTModuleInstance, total_mem_size));
if (!(func_ctx->total_mem_size =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "mem_data_size_offset"))) {
&offset, 1, "bound_check_1byte_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->mem_data_size =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_data_size,
INT32_PTR_TYPE, "mem_data_size_ptr"))) {
if (!(func_ctx->total_mem_size =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->total_mem_size,
INT32_PTR_TYPE, "bound_check_1byte_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (mem_space_unchanged) {
if (!(func_ctx->mem_data_size =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_data_size,
"mem_data_size"))) {
if (!(func_ctx->total_mem_size =
LLVMBuildLoad(comp_ctx->builder, func_ctx->total_mem_size,
"bound_check_1byte"))) {
aot_set_last_error("llvm build load failed");
return false;
}
if (!(func_ctx->mem_bound_1_byte =
LLVMBuildSub(comp_ctx->builder,
func_ctx->mem_data_size, I32_ONE,
"mem_bound_1_byte"))
|| !(func_ctx->mem_bound_2_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->mem_data_size, I32_TWO,
"mem_bound_2_bytes"))
|| !(func_ctx->mem_bound_4_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->mem_data_size, I32_FOUR,
"mem_bound_4_bytes"))
|| !(func_ctx->mem_bound_8_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->mem_data_size, I32_EIGHT,
"mem_bound_8_bytes"))) {
aot_set_last_error("llvm build sub failed");
return false;
}
}
/* Load heap base address */
offset = I32_CONST(offsetof(AOTModuleInstance, heap_data.ptr));
if (!(func_ctx->heap_base_addr =
/* Load memory bound check constants */
offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_1byte));
if (!(func_ctx->mem_bound_check_1byte =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "heap_base_addr_offset"))) {
&offset, 1, "bound_check_1byte_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->heap_base_addr =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->heap_base_addr,
int8_ptr_type, "heap_base_addr_tmp"))) {
if (!(func_ctx->mem_bound_check_1byte =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_1byte,
INT32_PTR_TYPE, "bound_check_1byte_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (!(func_ctx->heap_base_addr =
LLVMBuildLoad(comp_ctx->builder, func_ctx->heap_base_addr,
"heap_base_addr"))) {
aot_set_last_error("llvm build load failed");
if (mem_space_unchanged) {
if (!(func_ctx->mem_bound_check_1byte =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_1byte,
"bound_check_1byte"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_2bytes));
if (!(func_ctx->mem_bound_check_2bytes =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "bound_check_2bytes_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->mem_bound_check_2bytes =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_2bytes,
INT32_PTR_TYPE, "bound_check_2bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (mem_space_unchanged) {
if (!(func_ctx->mem_bound_check_2bytes =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_2bytes,
"bound_check_2bytes"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_4bytes));
if (!(func_ctx->mem_bound_check_4bytes =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "bound_check_4bytes_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->mem_bound_check_4bytes =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_4bytes,
INT32_PTR_TYPE, "bound_check_4bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (mem_space_unchanged) {
if (!(func_ctx->mem_bound_check_4bytes =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_4bytes,
"bound_check_4bytes"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_8bytes));
if (!(func_ctx->mem_bound_check_8bytes =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "bound_check_8bytes_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->mem_bound_check_8bytes =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_8bytes,
INT32_PTR_TYPE, "bound_check_8bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (mem_space_unchanged) {
if (!(func_ctx->mem_bound_check_8bytes =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_8bytes,
"bound_check_8bytes"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
/* Load heap base offset */
offset = I32_CONST(offsetof(AOTModuleInstance, heap_base_offset));
@ -265,46 +314,6 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false;
}
/* Load heap data size */
offset = I32_CONST(offsetof(AOTModuleInstance, heap_data_size));
if (!(func_ctx->heap_data_size =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "heap_data_size_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->heap_data_size =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->heap_data_size,
INT32_PTR_TYPE, "heap_data_size_tmp"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (!(func_ctx->heap_data_size =
LLVMBuildLoad(comp_ctx->builder, func_ctx->heap_data_size,
"heap_data_size"))) {
aot_set_last_error("llvm build load failed");
return false;
}
if (!(func_ctx->heap_bound_1_byte =
LLVMBuildSub(comp_ctx->builder,
func_ctx->heap_data_size, I32_ONE,
"heap_bound_1_byte"))
|| !(func_ctx->heap_bound_2_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->heap_data_size, I32_TWO,
"heap_bound_2_bytes"))
|| !(func_ctx->heap_bound_4_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->heap_data_size, I32_FOUR,
"heap_bound_4_bytes"))
|| !(func_ctx->heap_bound_8_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->heap_data_size, I32_EIGHT,
"heap_bound_8_bytes"))) {
aot_set_last_error("llvm build sub failed");
return false;
}
return true;
}
@ -313,7 +322,7 @@ create_table_base(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{
LLVMValueRef offset;
offset = I32_CONST(offsetof(AOTModuleInstance, global_table_heap_data.bytes)
offset = I32_CONST(offsetof(AOTModuleInstance, global_table_data.bytes)
+ comp_ctx->comp_data->global_data_size);
func_ctx->table_base = LLVMBuildInBoundsGEP(comp_ctx->builder,
func_ctx->aot_inst,
@ -918,6 +927,7 @@ aot_create_comp_context(AOTCompData *comp_data,
/* Create LLVM execution engine */
LLVMInitializeMCJITCompilerOptions(&jit_options, sizeof(jit_options));
jit_options.OptLevel = LLVMCodeGenLevelAggressive;
jit_options.EnableFastISel = true;
/*jit_options.CodeModel = LLVMCodeModelSmall;*/
if (LLVMCreateMCJITCompilerForModule
(&comp_ctx->exec_engine, comp_ctx->module,

View File

@ -94,20 +94,13 @@ typedef struct AOTFuncContext {
LLVMValueRef table_base;
LLVMValueRef argv_buf;
LLVMValueRef mem_data_size;
LLVMValueRef mem_base_addr;
LLVMValueRef mem_bound_1_byte;
LLVMValueRef mem_bound_2_bytes;
LLVMValueRef mem_bound_4_bytes;
LLVMValueRef mem_bound_8_bytes;
LLVMValueRef heap_base_offset;
LLVMValueRef heap_base_addr;
LLVMValueRef heap_data_size;
LLVMValueRef heap_bound_1_byte;
LLVMValueRef heap_bound_2_bytes;
LLVMValueRef heap_bound_4_bytes;
LLVMValueRef heap_bound_8_bytes;
LLVMValueRef mem_base_addr;
LLVMValueRef total_mem_size;
LLVMValueRef mem_bound_check_1byte;
LLVMValueRef mem_bound_check_2bytes;
LLVMValueRef mem_bound_check_4bytes;
LLVMValueRef mem_bound_check_8bytes;
LLVMValueRef cur_exception;