| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- /*
- * Copyright (C) 2019 Intel Corporation. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- */
- #ifndef _AOT_LLVM_H_
- #define _AOT_LLVM_H_
- #include "aot.h"
- #include "llvm/Config/llvm-config.h"
- #include "llvm-c/Types.h"
- #include "llvm-c/Target.h"
- #include "llvm-c/Core.h"
- #include "llvm-c/Object.h"
- #include "llvm-c/ExecutionEngine.h"
- #include "llvm-c/Analysis.h"
- #include "llvm-c/Transforms/Utils.h"
- #include "llvm-c/Transforms/Scalar.h"
- #include "llvm-c/Transforms/Vectorize.h"
- #if WASM_ENABLE_LAZY_JIT != 0
- #include "aot_llvm_lazyjit.h"
- #include "llvm-c/Orc.h"
- #include "llvm-c/Error.h"
- #include "llvm-c/Initialization.h"
- #include "llvm-c/Support.h"
- #endif
- #if WASM_ENABLE_DEBUG_AOT != 0
- #include "llvm-c/DebugInfo.h"
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * Value in the WASM operation stack, each stack element
- * is an LLVM value
- */
- typedef struct AOTValue {
- struct AOTValue *next;
- struct AOTValue *prev;
- LLVMValueRef value;
- /* VALUE_TYPE_I32/I64/F32/F64/VOID */
- uint8 type;
- bool is_local;
- uint32 local_idx;
- } AOTValue;
- /**
- * Value stack, represents stack elements in a WASM block
- */
- typedef struct AOTValueStack {
- AOTValue *value_list_head;
- AOTValue *value_list_end;
- } AOTValueStack;
- typedef struct AOTBlock {
- struct AOTBlock *next;
- struct AOTBlock *prev;
- /* Block index */
- uint32 block_index;
- /* LABEL_TYPE_BLOCK/LOOP/IF/FUNCTION */
- uint32 label_type;
- /* Whether it is reachable */
- bool is_reachable;
- /* Whether skip translation of wasm else branch */
- bool skip_wasm_code_else;
- /* code of else opcode of this block, if it is a IF block */
- uint8 *wasm_code_else;
- /* code end of this block */
- uint8 *wasm_code_end;
- /* LLVM label points to code begin */
- LLVMBasicBlockRef llvm_entry_block;
- /* LLVM label points to code else */
- LLVMBasicBlockRef llvm_else_block;
- /* LLVM label points to code end */
- LLVMBasicBlockRef llvm_end_block;
- /* WASM operation stack */
- AOTValueStack value_stack;
- /* Param count/types/PHIs of this block */
- uint32 param_count;
- uint8 *param_types;
- LLVMValueRef *param_phis;
- LLVMValueRef *else_param_phis;
- /* Result count/types/PHIs of this block */
- uint32 result_count;
- uint8 *result_types;
- LLVMValueRef *result_phis;
- } AOTBlock;
- /**
- * Block stack, represents WASM block stack elements
- */
- typedef struct AOTBlockStack {
- AOTBlock *block_list_head;
- AOTBlock *block_list_end;
- /* Current block index of each block type */
- uint32 block_index[3];
- } AOTBlockStack;
- typedef struct AOTCheckedAddr {
- struct AOTCheckedAddr *next;
- uint32 local_idx;
- uint32 offset;
- uint32 bytes;
- } AOTCheckedAddr, *AOTCheckedAddrList;
- typedef struct AOTMemInfo {
- LLVMValueRef mem_base_addr;
- LLVMValueRef mem_data_size_addr;
- LLVMValueRef mem_cur_page_count_addr;
- LLVMValueRef mem_bound_check_1byte;
- LLVMValueRef mem_bound_check_2bytes;
- LLVMValueRef mem_bound_check_4bytes;
- LLVMValueRef mem_bound_check_8bytes;
- LLVMValueRef mem_bound_check_16bytes;
- } AOTMemInfo;
- typedef struct AOTFuncContext {
- AOTFunc *aot_func;
- LLVMValueRef func;
- LLVMTypeRef func_type;
- AOTBlockStack block_stack;
- LLVMValueRef exec_env;
- LLVMValueRef aot_inst;
- LLVMValueRef argv_buf;
- LLVMValueRef native_stack_bound;
- LLVMValueRef aux_stack_bound;
- LLVMValueRef aux_stack_bottom;
- LLVMValueRef native_symbol;
- LLVMValueRef last_alloca;
- LLVMValueRef func_ptrs;
- AOTMemInfo *mem_info;
- LLVMValueRef cur_exception;
- bool mem_space_unchanged;
- AOTCheckedAddrList checked_addr_list;
- LLVMBasicBlockRef got_exception_block;
- LLVMBasicBlockRef func_return_block;
- LLVMValueRef exception_id_phi;
- LLVMValueRef func_type_indexes;
- #if WASM_ENABLE_DEBUG_AOT != 0
- LLVMMetadataRef debug_func;
- #endif
- LLVMValueRef locals[1];
- } AOTFuncContext;
- typedef struct AOTLLVMTypes {
- LLVMTypeRef int1_type;
- LLVMTypeRef int8_type;
- LLVMTypeRef int16_type;
- LLVMTypeRef int32_type;
- LLVMTypeRef int64_type;
- LLVMTypeRef float32_type;
- LLVMTypeRef float64_type;
- LLVMTypeRef void_type;
- LLVMTypeRef int8_ptr_type;
- LLVMTypeRef int8_pptr_type;
- LLVMTypeRef int16_ptr_type;
- LLVMTypeRef int32_ptr_type;
- LLVMTypeRef int64_ptr_type;
- LLVMTypeRef float32_ptr_type;
- LLVMTypeRef float64_ptr_type;
- LLVMTypeRef v128_type;
- LLVMTypeRef v128_ptr_type;
- LLVMTypeRef i8x16_vec_type;
- LLVMTypeRef i16x8_vec_type;
- LLVMTypeRef i32x4_vec_type;
- LLVMTypeRef i64x2_vec_type;
- LLVMTypeRef f32x4_vec_type;
- LLVMTypeRef f64x2_vec_type;
- LLVMTypeRef i1x2_vec_type;
- LLVMTypeRef meta_data_type;
- LLVMTypeRef funcref_type;
- LLVMTypeRef externref_type;
- } AOTLLVMTypes;
- typedef struct AOTLLVMConsts {
- LLVMValueRef i1_zero;
- LLVMValueRef i1_one;
- LLVMValueRef i8_zero;
- LLVMValueRef i32_zero;
- LLVMValueRef i64_zero;
- LLVMValueRef f32_zero;
- LLVMValueRef f64_zero;
- LLVMValueRef i32_one;
- LLVMValueRef i32_two;
- LLVMValueRef i32_three;
- LLVMValueRef i32_four;
- LLVMValueRef i32_five;
- LLVMValueRef i32_six;
- LLVMValueRef i32_seven;
- LLVMValueRef i32_eight;
- LLVMValueRef i32_nine;
- LLVMValueRef i32_ten;
- LLVMValueRef i32_eleven;
- LLVMValueRef i32_twelve;
- LLVMValueRef i32_thirteen;
- LLVMValueRef i32_fourteen;
- LLVMValueRef i32_fifteen;
- LLVMValueRef i32_neg_one;
- LLVMValueRef i64_neg_one;
- LLVMValueRef i32_min;
- LLVMValueRef i64_min;
- LLVMValueRef i32_31;
- LLVMValueRef i32_32;
- LLVMValueRef i64_63;
- LLVMValueRef i64_64;
- LLVMValueRef i8x16_vec_zero;
- LLVMValueRef i16x8_vec_zero;
- LLVMValueRef i32x4_vec_zero;
- LLVMValueRef i64x2_vec_zero;
- LLVMValueRef f32x4_vec_zero;
- LLVMValueRef f64x2_vec_zero;
- LLVMValueRef i8x16_undef;
- LLVMValueRef i16x8_undef;
- LLVMValueRef i32x4_undef;
- LLVMValueRef i64x2_undef;
- LLVMValueRef f32x4_undef;
- LLVMValueRef f64x2_undef;
- LLVMValueRef i32x16_zero;
- LLVMValueRef i32x8_zero;
- LLVMValueRef i32x4_zero;
- LLVMValueRef i32x2_zero;
- } AOTLLVMConsts;
- /**
- * Compiler context
- */
- typedef struct AOTCompContext {
- AOTCompData *comp_data;
- /* LLVM variables required to emit LLVM IR */
- LLVMContextRef context;
- LLVMModuleRef module;
- LLVMBuilderRef builder;
- #if WASM_ENABLE_DEBUG_AOT
- LLVMDIBuilderRef debug_builder;
- LLVMMetadataRef debug_file;
- LLVMMetadataRef debug_comp_unit;
- #endif
- LLVMTargetMachineRef target_machine;
- char *target_cpu;
- char target_arch[16];
- unsigned pointer_size;
- /* Hardware intrinsic compability flags */
- uint64 flags[8];
- /* LLVM execution engine required by JIT */
- #if WASM_ENABLE_LAZY_JIT != 0
- LLVMOrcLLLazyJITRef lazy_orcjit;
- LLVMOrcThreadSafeContextRef ts_context;
- LLVMOrcJITTargetMachineBuilderRef tm_builder;
- #else
- LLVMExecutionEngineRef exec_engine;
- #endif
- bool is_jit_mode;
- /* AOT indirect mode flag & symbol list */
- bool is_indirect_mode;
- bh_list native_symbols;
- /* Bulk memory feature */
- bool enable_bulk_memory;
- /* Bounday Check */
- bool enable_bound_check;
- /* 128-bit SIMD */
- bool enable_simd;
- /* Auxiliary stack overflow/underflow check */
- bool enable_aux_stack_check;
- /* Generate auxiliary stack frame */
- bool enable_aux_stack_frame;
- /* Thread Manager */
- bool enable_thread_mgr;
- /* Tail Call */
- bool enable_tail_call;
- /* Reference Types */
- bool enable_ref_types;
- /* Disable LLVM built-in intrinsics */
- bool disable_llvm_intrinsics;
- /* Whether optimize the JITed code */
- bool optimize;
- /* LLVM pass manager to optimize the JITed code */
- LLVMPassManagerRef pass_mgr;
- /* LLVM floating-point rounding mode metadata */
- LLVMValueRef fp_rounding_mode;
- /* LLVM floating-point exception behavior metadata */
- LLVMValueRef fp_exception_behavior;
- /* LLVM data types */
- AOTLLVMTypes basic_types;
- LLVMTypeRef exec_env_type;
- LLVMTypeRef aot_inst_type;
- /* LLVM const values */
- AOTLLVMConsts llvm_consts;
- /* Function contexts */
- AOTFuncContext **func_ctxes;
- uint32 func_ctx_count;
- } AOTCompContext;
- enum {
- AOT_FORMAT_FILE,
- AOT_OBJECT_FILE,
- AOT_LLVMIR_UNOPT_FILE,
- AOT_LLVMIR_OPT_FILE,
- };
- typedef struct AOTCompOption {
- bool is_jit_mode;
- bool is_indirect_mode;
- char *target_arch;
- char *target_abi;
- char *target_cpu;
- char *cpu_features;
- bool is_sgx_platform;
- bool enable_bulk_memory;
- bool enable_thread_mgr;
- bool enable_tail_call;
- bool enable_simd;
- bool enable_ref_types;
- bool enable_aux_stack_check;
- bool enable_aux_stack_frame;
- bool disable_llvm_intrinsics;
- uint32 opt_level;
- uint32 size_level;
- uint32 output_format;
- uint32 bounds_checks;
- } AOTCompOption, *aot_comp_option_t;
- AOTCompContext *
- aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option);
- void
- aot_destroy_comp_context(AOTCompContext *comp_ctx);
- int32
- aot_get_native_symbol_index(AOTCompContext *comp_ctx, const char *symbol);
- bool
- aot_compile_wasm(AOTCompContext *comp_ctx);
- uint8 *
- aot_emit_elf_file(AOTCompContext *comp_ctx, uint32 *p_elf_file_size);
- void
- aot_destroy_elf_file(uint8 *elf_file);
- void
- aot_value_stack_push(AOTValueStack *stack, AOTValue *value);
- AOTValue *
- aot_value_stack_pop(AOTValueStack *stack);
- void
- aot_value_stack_destroy(AOTValueStack *stack);
- void
- aot_block_stack_push(AOTBlockStack *stack, AOTBlock *block);
- AOTBlock *
- aot_block_stack_pop(AOTBlockStack *stack);
- void
- aot_block_stack_destroy(AOTBlockStack *stack);
- void
- aot_block_destroy(AOTBlock *block);
- LLVMTypeRef
- wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type);
- bool
- aot_checked_addr_list_add(AOTFuncContext *func_ctx, uint32 local_idx,
- uint32 offset, uint32 bytes);
- void
- aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx);
- bool
- aot_checked_addr_list_find(AOTFuncContext *func_ctx, uint32 local_idx,
- uint32 offset, uint32 bytes);
- void
- aot_checked_addr_list_destroy(AOTFuncContext *func_ctx);
- bool
- aot_build_zero_function_ret(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
- AOTFuncType *func_type);
- LLVMValueRef
- aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx,
- const AOTFuncContext *func_ctx, const char *intrinsic,
- LLVMTypeRef ret_type, LLVMTypeRef *param_types,
- int param_count, ...);
- LLVMValueRef
- aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx,
- const AOTFuncContext *func_ctx, const char *intrinsic,
- LLVMTypeRef ret_type, LLVMTypeRef *param_types,
- int param_count, va_list param_value_list);
- LLVMValueRef
- aot_get_func_from_table(const AOTCompContext *comp_ctx, LLVMValueRef base,
- LLVMTypeRef func_type, int32 index);
- bool
- aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
- #if WASM_ENABLE_LAZY_JIT != 0
- void
- aot_handle_llvm_errmsg(char *error_buf, uint32 error_buf_size,
- const char *string, LLVMErrorRef error);
- #endif
- #ifdef __cplusplus
- } /* end of extern "C" */
- #endif
- #endif /* end of _AOT_LLVM_H_ */
|