aot_llvm.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  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/Config/llvm-config.h"
  9. #include "llvm-c/Types.h"
  10. #include "llvm-c/Target.h"
  11. #include "llvm-c/Core.h"
  12. #include "llvm-c/Object.h"
  13. #include "llvm-c/ExecutionEngine.h"
  14. #include "llvm-c/Analysis.h"
  15. #include "llvm-c/Transforms/Utils.h"
  16. #include "llvm-c/Transforms/Scalar.h"
  17. #include "llvm-c/Transforms/Vectorize.h"
  18. #if WASM_ENABLE_LAZY_JIT != 0
  19. #include "aot_llvm_lazyjit.h"
  20. #include "llvm-c/Orc.h"
  21. #include "llvm-c/Error.h"
  22. #include "llvm-c/Initialization.h"
  23. #include "llvm-c/Support.h"
  24. #endif
  25. #ifdef __cplusplus
  26. extern "C" {
  27. #endif
  28. /**
  29. * Value in the WASM operation stack, each stack element
  30. * is an LLVM value
  31. */
  32. typedef struct AOTValue {
  33. struct AOTValue *next;
  34. struct AOTValue *prev;
  35. LLVMValueRef value;
  36. /* VALUE_TYPE_I32/I64/F32/F64/VOID */
  37. uint8 type;
  38. bool is_local;
  39. uint32 local_idx;
  40. } AOTValue;
  41. /**
  42. * Value stack, represents stack elements in a WASM block
  43. */
  44. typedef struct AOTValueStack {
  45. AOTValue *value_list_head;
  46. AOTValue *value_list_end;
  47. } AOTValueStack;
  48. typedef struct AOTBlock {
  49. struct AOTBlock *next;
  50. struct AOTBlock *prev;
  51. /* Block index */
  52. uint32 block_index;
  53. /* LABEL_TYPE_BLOCK/LOOP/IF/FUNCTION */
  54. uint32 label_type;
  55. /* Whether it is reachable */
  56. bool is_reachable;
  57. /* Whether skip translation of wasm else branch */
  58. bool skip_wasm_code_else;
  59. /* code of else opcode of this block, if it is a IF block */
  60. uint8 *wasm_code_else;
  61. /* code end of this block */
  62. uint8 *wasm_code_end;
  63. /* LLVM label points to code begin */
  64. LLVMBasicBlockRef llvm_entry_block;
  65. /* LLVM label points to code else */
  66. LLVMBasicBlockRef llvm_else_block;
  67. /* LLVM label points to code end */
  68. LLVMBasicBlockRef llvm_end_block;
  69. /* WASM operation stack */
  70. AOTValueStack value_stack;
  71. /* Param count/types/PHIs of this block */
  72. uint32 param_count;
  73. uint8 *param_types;
  74. LLVMValueRef *param_phis;
  75. LLVMValueRef *else_param_phis;
  76. /* Result count/types/PHIs of this block */
  77. uint32 result_count;
  78. uint8 *result_types;
  79. LLVMValueRef *result_phis;
  80. } AOTBlock;
  81. /**
  82. * Block stack, represents WASM block stack elements
  83. */
  84. typedef struct AOTBlockStack {
  85. AOTBlock *block_list_head;
  86. AOTBlock *block_list_end;
  87. /* Current block index of each block type */
  88. uint32 block_index[3];
  89. } AOTBlockStack;
  90. typedef struct AOTCheckedAddr {
  91. struct AOTCheckedAddr *next;
  92. uint32 local_idx;
  93. uint32 offset;
  94. uint32 bytes;
  95. } AOTCheckedAddr, *AOTCheckedAddrList;
  96. typedef struct AOTMemInfo {
  97. LLVMValueRef mem_base_addr;
  98. LLVMValueRef mem_data_size_addr;
  99. LLVMValueRef mem_cur_page_count_addr;
  100. LLVMValueRef mem_bound_check_1byte;
  101. LLVMValueRef mem_bound_check_2bytes;
  102. LLVMValueRef mem_bound_check_4bytes;
  103. LLVMValueRef mem_bound_check_8bytes;
  104. LLVMValueRef mem_bound_check_16bytes;
  105. } AOTMemInfo;
  106. typedef struct AOTFuncContext {
  107. AOTFunc *aot_func;
  108. LLVMValueRef func;
  109. LLVMTypeRef func_type;
  110. AOTBlockStack block_stack;
  111. LLVMValueRef exec_env;
  112. LLVMValueRef aot_inst;
  113. LLVMValueRef argv_buf;
  114. LLVMValueRef native_stack_bound;
  115. LLVMValueRef aux_stack_bound;
  116. LLVMValueRef aux_stack_bottom;
  117. LLVMValueRef native_symbol;
  118. LLVMValueRef last_alloca;
  119. LLVMValueRef func_ptrs;
  120. AOTMemInfo *mem_info;
  121. LLVMValueRef cur_exception;
  122. bool mem_space_unchanged;
  123. AOTCheckedAddrList checked_addr_list;
  124. LLVMBasicBlockRef got_exception_block;
  125. LLVMBasicBlockRef func_return_block;
  126. LLVMValueRef exception_id_phi;
  127. LLVMValueRef func_type_indexes;
  128. LLVMValueRef locals[1];
  129. } AOTFuncContext;
  130. typedef struct AOTLLVMTypes {
  131. LLVMTypeRef int1_type;
  132. LLVMTypeRef int8_type;
  133. LLVMTypeRef int16_type;
  134. LLVMTypeRef int32_type;
  135. LLVMTypeRef int64_type;
  136. LLVMTypeRef float32_type;
  137. LLVMTypeRef float64_type;
  138. LLVMTypeRef void_type;
  139. LLVMTypeRef int8_ptr_type;
  140. LLVMTypeRef int8_pptr_type;
  141. LLVMTypeRef int16_ptr_type;
  142. LLVMTypeRef int32_ptr_type;
  143. LLVMTypeRef int64_ptr_type;
  144. LLVMTypeRef float32_ptr_type;
  145. LLVMTypeRef float64_ptr_type;
  146. LLVMTypeRef v128_type;
  147. LLVMTypeRef v128_ptr_type;
  148. LLVMTypeRef i8x16_vec_type;
  149. LLVMTypeRef i16x8_vec_type;
  150. LLVMTypeRef i32x4_vec_type;
  151. LLVMTypeRef i64x2_vec_type;
  152. LLVMTypeRef f32x4_vec_type;
  153. LLVMTypeRef f64x2_vec_type;
  154. LLVMTypeRef meta_data_type;
  155. LLVMTypeRef funcref_type;
  156. LLVMTypeRef externref_type;
  157. } AOTLLVMTypes;
  158. typedef struct AOTLLVMConsts {
  159. LLVMValueRef i8_zero;
  160. LLVMValueRef i32_zero;
  161. LLVMValueRef i64_zero;
  162. LLVMValueRef f32_zero;
  163. LLVMValueRef f64_zero;
  164. LLVMValueRef v128_zero;
  165. LLVMValueRef i8x16_vec_zero;
  166. LLVMValueRef i16x8_vec_zero;
  167. LLVMValueRef i32x4_vec_zero;
  168. LLVMValueRef i64x2_vec_zero;
  169. LLVMValueRef f32x4_vec_zero;
  170. LLVMValueRef f64x2_vec_zero;
  171. LLVMValueRef i32_one;
  172. LLVMValueRef i32_two;
  173. LLVMValueRef i32_three;
  174. LLVMValueRef i32_four;
  175. LLVMValueRef i32_five;
  176. LLVMValueRef i32_six;
  177. LLVMValueRef i32_seven;
  178. LLVMValueRef i32_eight;
  179. LLVMValueRef i32_neg_one;
  180. LLVMValueRef i64_neg_one;
  181. LLVMValueRef i32_min;
  182. LLVMValueRef i64_min;
  183. LLVMValueRef i32_31;
  184. LLVMValueRef i32_32;
  185. LLVMValueRef i64_63;
  186. LLVMValueRef i64_64;
  187. LLVMValueRef ref_null;
  188. } AOTLLVMConsts;
  189. /**
  190. * Compiler context
  191. */
  192. typedef struct AOTCompContext {
  193. AOTCompData *comp_data;
  194. /* LLVM variables required to emit LLVM IR */
  195. LLVMContextRef context;
  196. LLVMModuleRef module;
  197. LLVMBuilderRef builder;
  198. LLVMTargetMachineRef target_machine;
  199. char *target_cpu;
  200. char target_arch[16];
  201. unsigned pointer_size;
  202. /* Hardware intrinsic compability flags */
  203. uint64 flags[8];
  204. /* LLVM execution engine required by JIT */
  205. #if WASM_ENABLE_LAZY_JIT != 0
  206. LLVMOrcLLLazyJITRef lazy_orcjit;
  207. LLVMOrcThreadSafeContextRef ts_context;
  208. LLVMOrcJITTargetMachineBuilderRef tm_builder;
  209. #else
  210. LLVMExecutionEngineRef exec_engine;
  211. #endif
  212. bool is_jit_mode;
  213. /* AOT indirect mode flag & symbol list */
  214. bool is_indirect_mode;
  215. bh_list native_symbols;
  216. /* Bulk memory feature */
  217. bool enable_bulk_memory;
  218. /* Bounday Check */
  219. bool enable_bound_check;
  220. /* 128-bit SIMD */
  221. bool enable_simd;
  222. /* Auxiliary stack overflow/underflow check */
  223. bool enable_aux_stack_check;
  224. /* Generate auxiliary stack frame */
  225. bool enable_aux_stack_frame;
  226. /* Thread Manager */
  227. bool enable_thread_mgr;
  228. /* Tail Call */
  229. bool enable_tail_call;
  230. /* Reference Types */
  231. bool enable_ref_types;
  232. /* Disable LLVM built-in intrinsics */
  233. bool disable_llvm_intrinsics;
  234. /* Whether optimize the JITed code */
  235. bool optimize;
  236. /* LLVM pass manager to optimize the JITed code */
  237. LLVMPassManagerRef pass_mgr;
  238. /* LLVM floating-point rounding mode metadata */
  239. LLVMValueRef fp_rounding_mode;
  240. /* LLVM floating-point exception behavior metadata */
  241. LLVMValueRef fp_exception_behavior;
  242. /* LLVM data types */
  243. AOTLLVMTypes basic_types;
  244. LLVMTypeRef exec_env_type;
  245. LLVMTypeRef aot_inst_type;
  246. /* LLVM const values */
  247. AOTLLVMConsts llvm_consts;
  248. /* Function contexts */
  249. AOTFuncContext **func_ctxes;
  250. uint32 func_ctx_count;
  251. } AOTCompContext;
  252. enum {
  253. AOT_FORMAT_FILE,
  254. AOT_OBJECT_FILE,
  255. AOT_LLVMIR_UNOPT_FILE,
  256. AOT_LLVMIR_OPT_FILE,
  257. };
  258. typedef struct AOTCompOption{
  259. bool is_jit_mode;
  260. bool is_indirect_mode;
  261. char *target_arch;
  262. char *target_abi;
  263. char *target_cpu;
  264. char *cpu_features;
  265. bool is_sgx_platform;
  266. bool enable_bulk_memory;
  267. bool enable_thread_mgr;
  268. bool enable_tail_call;
  269. bool enable_simd;
  270. bool enable_ref_types;
  271. bool enable_aux_stack_check;
  272. bool enable_aux_stack_frame;
  273. bool disable_llvm_intrinsics;
  274. uint32 opt_level;
  275. uint32 size_level;
  276. uint32 output_format;
  277. uint32 bounds_checks;
  278. } AOTCompOption, *aot_comp_option_t;
  279. AOTCompContext *
  280. aot_create_comp_context(AOTCompData *comp_data,
  281. aot_comp_option_t option);
  282. void
  283. aot_destroy_comp_context(AOTCompContext *comp_ctx);
  284. int32
  285. aot_get_native_symbol_index(AOTCompContext *comp_ctx, const char *symbol);
  286. bool
  287. aot_compile_wasm(AOTCompContext *comp_ctx);
  288. uint8*
  289. aot_emit_elf_file(AOTCompContext *comp_ctx, uint32 *p_elf_file_size);
  290. void
  291. aot_destroy_elf_file(uint8 *elf_file);
  292. void
  293. aot_value_stack_push(AOTValueStack *stack, AOTValue *value);
  294. AOTValue *
  295. aot_value_stack_pop(AOTValueStack *stack);
  296. void
  297. aot_value_stack_destroy(AOTValueStack *stack);
  298. void
  299. aot_block_stack_push(AOTBlockStack *stack, AOTBlock *block);
  300. AOTBlock *
  301. aot_block_stack_pop(AOTBlockStack *stack);
  302. void
  303. aot_block_stack_destroy(AOTBlockStack *stack);
  304. void
  305. aot_block_destroy(AOTBlock *block);
  306. LLVMTypeRef
  307. wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type);
  308. bool
  309. aot_checked_addr_list_add(AOTFuncContext *func_ctx,
  310. uint32 local_idx, uint32 offset, uint32 bytes);
  311. void
  312. aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx);
  313. bool
  314. aot_checked_addr_list_find(AOTFuncContext *func_ctx,
  315. uint32 local_idx, uint32 offset, uint32 bytes);
  316. void
  317. aot_checked_addr_list_destroy(AOTFuncContext *func_ctx);
  318. bool
  319. aot_build_zero_function_ret(AOTCompContext *comp_ctx,
  320. AOTFuncType *func_type);
  321. LLVMValueRef
  322. aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx,
  323. const AOTFuncContext *func_ctx,
  324. const char *name,
  325. LLVMTypeRef ret_type,
  326. LLVMTypeRef *param_types,
  327. int param_count,
  328. ...);
  329. LLVMValueRef
  330. aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx,
  331. const AOTFuncContext *func_ctx,
  332. const char *name,
  333. LLVMTypeRef ret_type,
  334. LLVMTypeRef *param_types,
  335. int param_count,
  336. va_list param_value_list);
  337. LLVMValueRef
  338. aot_get_func_from_table(const AOTCompContext *comp_ctx,
  339. LLVMValueRef base,
  340. LLVMTypeRef func_type,
  341. int32 index);
  342. bool
  343. aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
  344. #if WASM_ENABLE_LAZY_JIT != 0
  345. void
  346. aot_handle_llvm_errmsg(char *error_buf,
  347. uint32 error_buf_size,
  348. const char *string,
  349. LLVMErrorRef error);
  350. #endif
  351. #ifdef __cplusplus
  352. } /* end of extern "C" */
  353. #endif
  354. #endif /* end of _AOT_LLVM_H_ */