aot_llvm.h 13 KB

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