aot_llvm.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #ifndef _AOT_LLVM_H_
  6. #define _AOT_LLVM_H_
  7. #include "aot.h"
  8. #include "llvm-c/Types.h"
  9. #include "llvm-c/Target.h"
  10. #include "llvm-c/Core.h"
  11. #include "llvm-c/Object.h"
  12. #include "llvm-c/ExecutionEngine.h"
  13. #include "llvm-c/Analysis.h"
  14. #include "llvm-c/Transforms/Scalar.h"
  15. #ifdef __cplusplus
  16. extern "C" {
  17. #endif
  18. /**
  19. * Value in the WASM operation stack, each stack element
  20. * is an LLVM value
  21. */
  22. typedef struct AOTValue {
  23. struct AOTValue *next;
  24. struct AOTValue *prev;
  25. LLVMValueRef value;
  26. /* VALUE_TYPE_I32/I64/F32/F64/VOID */
  27. uint8 type;
  28. bool is_local;
  29. uint32 local_idx;
  30. } AOTValue;
  31. /**
  32. * Value stack, represents stack elements in a WASM block
  33. */
  34. typedef struct AOTValueStack {
  35. AOTValue *value_list_head;
  36. AOTValue *value_list_end;
  37. } AOTValueStack;
  38. typedef struct AOTBlock {
  39. struct AOTBlock *next;
  40. struct AOTBlock *prev;
  41. /* Block index */
  42. uint32 block_index;
  43. /* LABEL_TYPE_BLOCK/LOOP/IF/FUNCTION */
  44. uint32 label_type;
  45. /* Whether it is reachable */
  46. bool is_reachable;
  47. /* Whether skip translation of wasm else branch */
  48. bool skip_wasm_code_else;
  49. /* code of else opcode of this block, if it is a IF block */
  50. uint8 *wasm_code_else;
  51. /* code end of this block */
  52. uint8 *wasm_code_end;
  53. /* LLVM label points to code begin */
  54. LLVMBasicBlockRef llvm_entry_block;
  55. /* LLVM label points to code else */
  56. LLVMBasicBlockRef llvm_else_block;
  57. /* LLVM label points to code end */
  58. LLVMBasicBlockRef llvm_end_block;
  59. /* WASM operation stack */
  60. AOTValueStack value_stack;
  61. /* Param count/types/PHIs of this block */
  62. uint32 param_count;
  63. uint8 *param_types;
  64. LLVMValueRef *param_phis;
  65. LLVMValueRef *else_param_phis;
  66. /* Result count/types/PHIs of this block */
  67. uint32 result_count;
  68. uint8 *result_types;
  69. LLVMValueRef *result_phis;
  70. } AOTBlock;
  71. /**
  72. * Block stack, represents WASM block stack elements
  73. */
  74. typedef struct AOTBlockStack {
  75. AOTBlock *block_list_head;
  76. AOTBlock *block_list_end;
  77. /* Current block index of each block type */
  78. uint32 block_index[3];
  79. } AOTBlockStack;
  80. typedef struct AOTCheckedAddr {
  81. struct AOTCheckedAddr *next;
  82. uint32 local_idx;
  83. uint32 offset;
  84. uint32 bytes;
  85. } AOTCheckedAddr, *AOTCheckedAddrList;
  86. typedef struct AOTMemInfo {
  87. LLVMValueRef mem_base_addr;
  88. LLVMValueRef mem_cur_page_count_addr;
  89. LLVMValueRef mem_bound_check_heap_base;
  90. LLVMValueRef mem_bound_check_1byte;
  91. LLVMValueRef mem_bound_check_2bytes;
  92. LLVMValueRef mem_bound_check_4bytes;
  93. LLVMValueRef mem_bound_check_8bytes;
  94. } AOTMemInfo;
  95. typedef struct AOTFuncContext {
  96. AOTFunc *aot_func;
  97. LLVMValueRef func;
  98. AOTBlockStack block_stack;
  99. LLVMValueRef exec_env;
  100. LLVMValueRef aot_inst;
  101. LLVMValueRef table_base;
  102. LLVMValueRef argv_buf;
  103. LLVMValueRef native_stack_bound;
  104. LLVMValueRef last_alloca;
  105. AOTMemInfo *mem_info;
  106. LLVMValueRef cur_exception;
  107. bool mem_space_unchanged;
  108. AOTCheckedAddrList checked_addr_list;
  109. LLVMBasicBlockRef *exception_blocks;
  110. LLVMBasicBlockRef got_exception_block;
  111. LLVMBasicBlockRef func_return_block;
  112. LLVMValueRef exception_id_phi;
  113. LLVMValueRef func_type_indexes;
  114. LLVMValueRef locals[1];
  115. } AOTFuncContext;
  116. typedef struct AOTLLVMTypes {
  117. LLVMTypeRef int1_type;
  118. LLVMTypeRef int8_type;
  119. LLVMTypeRef int16_type;
  120. LLVMTypeRef int32_type;
  121. LLVMTypeRef int64_type;
  122. LLVMTypeRef float32_type;
  123. LLVMTypeRef float64_type;
  124. LLVMTypeRef void_type;
  125. LLVMTypeRef int8_ptr_type;
  126. LLVMTypeRef int16_ptr_type;
  127. LLVMTypeRef int32_ptr_type;
  128. LLVMTypeRef int64_ptr_type;
  129. LLVMTypeRef float32_ptr_type;
  130. LLVMTypeRef float64_ptr_type;
  131. LLVMTypeRef meta_data_type;
  132. } AOTLLVMTypes;
  133. typedef struct AOTLLVMConsts {
  134. LLVMValueRef i8_zero;
  135. LLVMValueRef i32_zero;
  136. LLVMValueRef i64_zero;
  137. LLVMValueRef f32_zero;
  138. LLVMValueRef f64_zero;
  139. LLVMValueRef i32_one;
  140. LLVMValueRef i32_two;
  141. LLVMValueRef i32_three;
  142. LLVMValueRef i32_four;
  143. LLVMValueRef i32_eight;
  144. LLVMValueRef i32_neg_one;
  145. LLVMValueRef i64_neg_one;
  146. LLVMValueRef i32_min;
  147. LLVMValueRef i64_min;
  148. LLVMValueRef i32_31;
  149. LLVMValueRef i32_32;
  150. LLVMValueRef i64_63;
  151. LLVMValueRef i64_64;
  152. } AOTLLVMConsts;
  153. /**
  154. * Compiler context
  155. */
  156. typedef struct AOTCompContext {
  157. AOTCompData *comp_data;
  158. /* LLVM variables required to emit LLVM IR */
  159. LLVMContextRef context;
  160. LLVMModuleRef module;
  161. LLVMBuilderRef builder;
  162. LLVMTargetMachineRef target_machine;
  163. char *target_cpu;
  164. char target_arch[16];
  165. /* LLVM execution engine required by JIT */
  166. LLVMExecutionEngineRef exec_engine;
  167. bool is_jit_mode;
  168. /* Bulk memory feature */
  169. bool enable_bulk_memory;
  170. /* Bounday Check */
  171. bool enable_bound_check;
  172. /* Thread Manager */
  173. bool enable_thread_mgr;
  174. /* Whether optimize the JITed code */
  175. bool optimize;
  176. /* LLVM pass manager to optimize the JITed code */
  177. LLVMPassManagerRef pass_mgr;
  178. /* LLVM floating-point rounding mode metadata */
  179. LLVMValueRef fp_rounding_mode;
  180. /* LLVM floating-point exception behavior metadata */
  181. LLVMValueRef fp_exception_behavior;
  182. /* LLVM data types */
  183. AOTLLVMTypes basic_types;
  184. LLVMTypeRef exec_env_type;
  185. LLVMTypeRef aot_inst_type;
  186. /* LLVM const values */
  187. AOTLLVMConsts llvm_consts;
  188. /* Function contexts */
  189. AOTFuncContext **func_ctxes;
  190. uint32 func_ctx_count;
  191. } AOTCompContext;
  192. enum {
  193. AOT_FORMAT_FILE,
  194. AOT_OBJECT_FILE,
  195. AOT_LLVMIR_UNOPT_FILE,
  196. AOT_LLVMIR_OPT_FILE,
  197. };
  198. typedef struct AOTCompOption{
  199. bool is_jit_mode;
  200. char *target_arch;
  201. char *target_abi;
  202. char *target_cpu;
  203. char *cpu_features;
  204. bool enable_bulk_memory;
  205. bool enable_thread_mgr;
  206. bool is_sgx_platform;
  207. uint32 opt_level;
  208. uint32 size_level;
  209. uint32 output_format;
  210. uint32 bounds_checks;
  211. } AOTCompOption, *aot_comp_option_t;
  212. AOTCompContext *
  213. aot_create_comp_context(AOTCompData *comp_data,
  214. aot_comp_option_t option);
  215. void
  216. aot_destroy_comp_context(AOTCompContext *comp_ctx);
  217. bool
  218. aot_compile_wasm(AOTCompContext *comp_ctx);
  219. uint8*
  220. aot_emit_elf_file(AOTCompContext *comp_ctx, uint32 *p_elf_file_size);
  221. void
  222. aot_destroy_elf_file(uint8 *elf_file);
  223. void
  224. aot_value_stack_push(AOTValueStack *stack, AOTValue *value);
  225. AOTValue *
  226. aot_value_stack_pop(AOTValueStack *stack);
  227. void
  228. aot_value_stack_destroy(AOTValueStack *stack);
  229. void
  230. aot_block_stack_push(AOTBlockStack *stack, AOTBlock *block);
  231. AOTBlock *
  232. aot_block_stack_pop(AOTBlockStack *stack);
  233. void
  234. aot_block_stack_destroy(AOTBlockStack *stack);
  235. void
  236. aot_block_destroy(AOTBlock *block);
  237. LLVMTypeRef
  238. wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type);
  239. bool
  240. aot_checked_addr_list_add(AOTFuncContext *func_ctx,
  241. uint32 local_idx, uint32 offset, uint32 bytes);
  242. void
  243. aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx);
  244. bool
  245. aot_checked_addr_list_find(AOTFuncContext *func_ctx,
  246. uint32 local_idx, uint32 offset, uint32 bytes);
  247. void
  248. aot_checked_addr_list_destroy(AOTFuncContext *func_ctx);
  249. #ifdef __cplusplus
  250. } /* end of extern "C" */
  251. #endif
  252. #endif /* end of _AOT_LLVM_H_ */