aot_llvm.c 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_llvm.h"
  6. #include "aot_compiler.h"
  7. #include "aot_emit_exception.h"
  8. #include "../aot/aot_runtime.h"
  9. #include "../aot/aot_intrinsic.h"
  10. LLVMTypeRef
  11. wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type)
  12. {
  13. switch (wasm_type) {
  14. case VALUE_TYPE_I32:
  15. case VALUE_TYPE_FUNCREF:
  16. case VALUE_TYPE_EXTERNREF:
  17. return llvm_types->int32_type;
  18. case VALUE_TYPE_I64:
  19. return llvm_types->int64_type;
  20. case VALUE_TYPE_F32:
  21. return llvm_types->float32_type;
  22. case VALUE_TYPE_F64:
  23. return llvm_types->float64_type;
  24. case VALUE_TYPE_V128:
  25. return llvm_types->i64x2_vec_type;
  26. case VALUE_TYPE_VOID:
  27. return llvm_types->void_type;
  28. default:
  29. break;
  30. }
  31. return NULL;
  32. }
  33. /**
  34. * Add LLVM function
  35. */
  36. static LLVMValueRef
  37. aot_add_llvm_func(AOTCompContext *comp_ctx, AOTFuncType *aot_func_type,
  38. uint32 func_index, LLVMTypeRef *p_func_type)
  39. {
  40. LLVMValueRef func = NULL;
  41. LLVMTypeRef *param_types, ret_type, func_type;
  42. LLVMValueRef local_value;
  43. char func_name[32];
  44. uint64 size;
  45. uint32 i, j = 0, param_count = (uint64)aot_func_type->param_count;
  46. /* exec env as first parameter */
  47. param_count++;
  48. /* Extra wasm function results(except the first one)'s address are
  49. * appended to aot function parameters. */
  50. if (aot_func_type->result_count > 1)
  51. param_count += aot_func_type->result_count - 1;
  52. /* Initialize parameter types of the LLVM function */
  53. size = sizeof(LLVMTypeRef) * ((uint64)param_count);
  54. if (size >= UINT32_MAX
  55. || !(param_types = wasm_runtime_malloc((uint32)size))) {
  56. aot_set_last_error("allocate memory failed.");
  57. return NULL;
  58. }
  59. /* exec env as first parameter */
  60. param_types[j++] = comp_ctx->exec_env_type;
  61. for (i = 0; i < aot_func_type->param_count; i++)
  62. param_types[j++] = TO_LLVM_TYPE(aot_func_type->types[i]);
  63. /* Extra results' address */
  64. for (i = 1; i < aot_func_type->result_count; i++, j++) {
  65. param_types[j] =
  66. TO_LLVM_TYPE(aot_func_type->types[aot_func_type->param_count + i]);
  67. if (!(param_types[j] = LLVMPointerType(param_types[j], 0))) {
  68. aot_set_last_error("llvm get pointer type failed.");
  69. goto fail;
  70. }
  71. }
  72. /* Resolve return type of the LLVM function */
  73. if (aot_func_type->result_count)
  74. ret_type = TO_LLVM_TYPE(aot_func_type->types[aot_func_type->param_count]);
  75. else
  76. ret_type = VOID_TYPE;
  77. /* Resolve function prototype */
  78. if (!(func_type = LLVMFunctionType(ret_type, param_types,
  79. param_count, false))) {
  80. aot_set_last_error("create LLVM function type failed.");
  81. goto fail;
  82. }
  83. /* Add LLVM function */
  84. snprintf(func_name, sizeof(func_name), "%s%d", AOT_FUNC_PREFIX, func_index);
  85. if (!(func = LLVMAddFunction(comp_ctx->module, func_name, func_type))) {
  86. aot_set_last_error("add LLVM function failed.");
  87. goto fail;
  88. }
  89. j = 0;
  90. local_value = LLVMGetParam(func, j++);
  91. LLVMSetValueName(local_value, "exec_env");
  92. /* Set parameter names */
  93. for (i = 0; i < aot_func_type->param_count; i++) {
  94. local_value = LLVMGetParam(func, j++);
  95. LLVMSetValueName(local_value, "");
  96. }
  97. if (p_func_type)
  98. *p_func_type = func_type;
  99. fail:
  100. wasm_runtime_free(param_types);
  101. return func;
  102. }
  103. static void
  104. free_block_memory(AOTBlock *block)
  105. {
  106. if (block->param_types)
  107. wasm_runtime_free(block->param_types);
  108. if (block->result_types)
  109. wasm_runtime_free(block->result_types);
  110. wasm_runtime_free(block);
  111. }
  112. /**
  113. * Create first AOTBlock, or function block for the function
  114. */
  115. static AOTBlock *
  116. aot_create_func_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  117. AOTFunc *func, AOTFuncType *aot_func_type)
  118. {
  119. AOTBlock *aot_block;
  120. uint32 param_count = aot_func_type->param_count,
  121. result_count = aot_func_type->result_count;
  122. /* Allocate memory */
  123. if (!(aot_block = wasm_runtime_malloc(sizeof(AOTBlock)))) {
  124. aot_set_last_error("allocate memory failed.");
  125. return NULL;
  126. }
  127. memset(aot_block, 0, sizeof(AOTBlock));
  128. if (param_count
  129. && !(aot_block->param_types = wasm_runtime_malloc(param_count))) {
  130. aot_set_last_error("allocate memory failed.");
  131. goto fail;
  132. }
  133. if (result_count) {
  134. if (!(aot_block->result_types = wasm_runtime_malloc(result_count))) {
  135. aot_set_last_error("allocate memory failed.");
  136. goto fail;
  137. }
  138. }
  139. /* Set block data */
  140. aot_block->label_type = LABEL_TYPE_FUNCTION;
  141. aot_block->param_count = param_count;
  142. memcpy(aot_block->param_types, aot_func_type->types, param_count);
  143. aot_block->result_count = result_count;
  144. memcpy(aot_block->result_types, aot_func_type->types + param_count, result_count);
  145. aot_block->wasm_code_end = func->code + func->code_size;
  146. /* Add function entry block */
  147. if (!(aot_block->llvm_entry_block =
  148. LLVMAppendBasicBlockInContext(comp_ctx->context, func_ctx->func,
  149. "func_begin"))) {
  150. aot_set_last_error("add LLVM basic block failed.");
  151. goto fail;
  152. }
  153. return aot_block;
  154. fail:
  155. free_block_memory(aot_block);
  156. return NULL;
  157. }
  158. static bool
  159. create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  160. LLVMTypeRef int8_ptr_type, uint32 func_index)
  161. {
  162. LLVMValueRef offset, mem_info_base;
  163. uint32 memory_count;
  164. WASMModule *module = comp_ctx->comp_data->wasm_module;
  165. WASMFunction *func = module->functions[func_index];
  166. LLVMTypeRef bound_check_type;
  167. bool mem_space_unchanged = (!func->has_op_memory_grow && !func->has_op_func_call)
  168. || (!module->possible_memory_grow);
  169. #if WASM_ENABLE_SHARED_MEMORY != 0
  170. bool is_shared_memory;
  171. #endif
  172. func_ctx->mem_space_unchanged = mem_space_unchanged;
  173. memory_count = module->memory_count + module->import_memory_count;
  174. /* If the module dosen't have memory, reserve
  175. one mem_info space with empty content */
  176. if (memory_count == 0)
  177. memory_count = 1;
  178. if (!(func_ctx->mem_info =
  179. wasm_runtime_malloc(sizeof(AOTMemInfo) * memory_count))) {
  180. return false;
  181. }
  182. memset(func_ctx->mem_info, 0, sizeof(AOTMemInfo));
  183. /* Currently we only create memory info for memory 0 */
  184. /* Load memory base address */
  185. #if WASM_ENABLE_SHARED_MEMORY != 0
  186. is_shared_memory = comp_ctx->comp_data->memories[0].memory_flags & 0x02
  187. ? true : false;
  188. if (is_shared_memory) {
  189. LLVMValueRef shared_mem_addr;
  190. offset = I32_CONST(offsetof(AOTModuleInstance, memories));
  191. if (!offset) {
  192. aot_set_last_error("create llvm const failed.");
  193. return false;
  194. }
  195. /* aot_inst->memories */
  196. if (!(shared_mem_addr =
  197. LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
  198. &offset, 1, "shared_mem_addr_offset"))) {
  199. aot_set_last_error("llvm build in bounds gep failed");
  200. return false;
  201. }
  202. if (!(shared_mem_addr =
  203. LLVMBuildBitCast(comp_ctx->builder,
  204. shared_mem_addr, int8_ptr_type,
  205. "shared_mem_addr_ptr"))) {
  206. aot_set_last_error("llvm build bit cast failed");
  207. return false;
  208. }
  209. /* aot_inst->memories[0] */
  210. if (!(shared_mem_addr =
  211. LLVMBuildLoad(comp_ctx->builder,
  212. shared_mem_addr, "shared_mem_addr"))) {
  213. aot_set_last_error("llvm build load failed");
  214. return false;
  215. }
  216. if (!(shared_mem_addr =
  217. LLVMBuildBitCast(comp_ctx->builder,
  218. shared_mem_addr, int8_ptr_type,
  219. "shared_mem_addr_ptr"))) {
  220. aot_set_last_error("llvm build bit cast failed");
  221. return false;
  222. }
  223. if (!(shared_mem_addr =
  224. LLVMBuildLoad(comp_ctx->builder,
  225. shared_mem_addr, "shared_mem_addr"))) {
  226. aot_set_last_error("llvm build load failed");
  227. return false;
  228. }
  229. offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data.ptr));
  230. if (!(func_ctx->mem_info[0].mem_base_addr =
  231. LLVMBuildInBoundsGEP(comp_ctx->builder, shared_mem_addr,
  232. &offset, 1, "mem_base_addr_offset"))) {
  233. aot_set_last_error("llvm build in bounds gep failed");
  234. return false;
  235. }
  236. offset = I32_CONST(offsetof(AOTMemoryInstance, cur_page_count));
  237. if (!(func_ctx->mem_info[0].mem_cur_page_count_addr =
  238. LLVMBuildInBoundsGEP(comp_ctx->builder, shared_mem_addr,
  239. &offset, 1, "mem_cur_page_offset"))) {
  240. aot_set_last_error("llvm build in bounds gep failed");
  241. return false;
  242. }
  243. offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data_size));
  244. if (!(func_ctx->mem_info[0].mem_data_size_addr =
  245. LLVMBuildInBoundsGEP(comp_ctx->builder, shared_mem_addr,
  246. &offset, 1, "mem_data_size_offset"))) {
  247. aot_set_last_error("llvm build in bounds gep failed");
  248. return false;
  249. }
  250. }
  251. else
  252. #endif
  253. {
  254. offset = I32_CONST(offsetof(AOTModuleInstance, global_table_data)
  255. + offsetof(AOTMemoryInstance, memory_data.ptr));
  256. if (!(func_ctx->mem_info[0].mem_base_addr =
  257. LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
  258. &offset, 1, "mem_base_addr_offset"))) {
  259. aot_set_last_error("llvm build in bounds gep failed");
  260. return false;
  261. }
  262. offset = I32_CONST(offsetof(AOTModuleInstance, global_table_data)
  263. + offsetof(AOTMemoryInstance, cur_page_count));
  264. if (!(func_ctx->mem_info[0].mem_cur_page_count_addr =
  265. LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
  266. &offset, 1, "mem_cur_page_offset"))) {
  267. aot_set_last_error("llvm build in bounds gep failed");
  268. return false;
  269. }
  270. offset = I32_CONST(offsetof(AOTModuleInstance, global_table_data)
  271. + offsetof(AOTMemoryInstance, memory_data_size));
  272. if (!(func_ctx->mem_info[0].mem_data_size_addr =
  273. LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
  274. &offset, 1, "mem_data_size_offset"))) {
  275. aot_set_last_error("llvm build in bounds gep failed");
  276. return false;
  277. }
  278. }
  279. /* Store mem info base address before cast */
  280. mem_info_base = func_ctx->mem_info[0].mem_base_addr;
  281. if (!(func_ctx->mem_info[0].mem_base_addr =
  282. LLVMBuildBitCast(comp_ctx->builder,
  283. func_ctx->mem_info[0].mem_base_addr,
  284. int8_ptr_type, "mem_base_addr_ptr"))) {
  285. aot_set_last_error("llvm build bit cast failed");
  286. return false;
  287. }
  288. if (!(func_ctx->mem_info[0].mem_cur_page_count_addr =
  289. LLVMBuildBitCast(comp_ctx->builder,
  290. func_ctx->mem_info[0].mem_cur_page_count_addr,
  291. INT32_PTR_TYPE, "mem_cur_page_ptr"))) {
  292. aot_set_last_error("llvm build bit cast failed");
  293. return false;
  294. }
  295. if (!(func_ctx->mem_info[0].mem_data_size_addr =
  296. LLVMBuildBitCast(comp_ctx->builder,
  297. func_ctx->mem_info[0].mem_data_size_addr,
  298. INT32_PTR_TYPE, "mem_data_size_ptr"))) {
  299. aot_set_last_error("llvm build bit cast failed");
  300. return false;
  301. }
  302. if (mem_space_unchanged) {
  303. if (!(func_ctx->mem_info[0].mem_base_addr =
  304. LLVMBuildLoad(comp_ctx->builder,
  305. func_ctx->mem_info[0].mem_base_addr,
  306. "mem_base_addr"))) {
  307. aot_set_last_error("llvm build load failed");
  308. return false;
  309. }
  310. if (!(func_ctx->mem_info[0].mem_cur_page_count_addr =
  311. LLVMBuildLoad(comp_ctx->builder,
  312. func_ctx->mem_info[0].mem_cur_page_count_addr,
  313. "mem_cur_page_count"))) {
  314. aot_set_last_error("llvm build load failed");
  315. return false;
  316. }
  317. if (!(func_ctx->mem_info[0].mem_data_size_addr =
  318. LLVMBuildLoad(comp_ctx->builder,
  319. func_ctx->mem_info[0].mem_data_size_addr,
  320. "mem_data_size"))) {
  321. aot_set_last_error("llvm build load failed");
  322. return false;
  323. }
  324. }
  325. #if WASM_ENABLE_SHARED_MEMORY != 0
  326. else if (is_shared_memory) {
  327. /* The base address for shared memory will never changed,
  328. we can load the value here */
  329. if (!(func_ctx->mem_info[0].mem_base_addr =
  330. LLVMBuildLoad(comp_ctx->builder,
  331. func_ctx->mem_info[0].mem_base_addr,
  332. "mem_base_addr"))) {
  333. aot_set_last_error("llvm build load failed");
  334. return false;
  335. }
  336. }
  337. #endif
  338. bound_check_type = (comp_ctx->pointer_size == sizeof(uint64))
  339. ? INT64_PTR_TYPE : INT32_PTR_TYPE;
  340. /* Load memory bound check constants */
  341. offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_1byte)
  342. - offsetof(AOTMemoryInstance, memory_data.ptr));
  343. if (!(func_ctx->mem_info[0].mem_bound_check_1byte =
  344. LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base,
  345. &offset, 1, "bound_check_1byte_offset"))) {
  346. aot_set_last_error("llvm build in bounds gep failed");
  347. return false;
  348. }
  349. if (!(func_ctx->mem_info[0].mem_bound_check_1byte =
  350. LLVMBuildBitCast(comp_ctx->builder,
  351. func_ctx->mem_info[0].mem_bound_check_1byte,
  352. bound_check_type, "bound_check_1byte_ptr"))) {
  353. aot_set_last_error("llvm build bit cast failed");
  354. return false;
  355. }
  356. if (mem_space_unchanged) {
  357. if (!(func_ctx->mem_info[0].mem_bound_check_1byte =
  358. LLVMBuildLoad(comp_ctx->builder,
  359. func_ctx->mem_info[0].mem_bound_check_1byte,
  360. "bound_check_1byte"))) {
  361. aot_set_last_error("llvm build load failed");
  362. return false;
  363. }
  364. }
  365. offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_2bytes)
  366. - offsetof(AOTMemoryInstance, memory_data.ptr));
  367. if (!(func_ctx->mem_info[0].mem_bound_check_2bytes =
  368. LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base,
  369. &offset, 1, "bound_check_2bytes_offset"))) {
  370. aot_set_last_error("llvm build in bounds gep failed");
  371. return false;
  372. }
  373. if (!(func_ctx->mem_info[0].mem_bound_check_2bytes =
  374. LLVMBuildBitCast(comp_ctx->builder,
  375. func_ctx->mem_info[0].mem_bound_check_2bytes,
  376. bound_check_type, "bound_check_2bytes_ptr"))) {
  377. aot_set_last_error("llvm build bit cast failed");
  378. return false;
  379. }
  380. if (mem_space_unchanged) {
  381. if (!(func_ctx->mem_info[0].mem_bound_check_2bytes =
  382. LLVMBuildLoad(comp_ctx->builder,
  383. func_ctx->mem_info[0].mem_bound_check_2bytes,
  384. "bound_check_2bytes"))) {
  385. aot_set_last_error("llvm build load failed");
  386. return false;
  387. }
  388. }
  389. offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_4bytes)
  390. - offsetof(AOTMemoryInstance, memory_data.ptr));
  391. if (!(func_ctx->mem_info[0].mem_bound_check_4bytes =
  392. LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base,
  393. &offset, 1, "bound_check_4bytes_offset"))) {
  394. aot_set_last_error("llvm build in bounds gep failed");
  395. return false;
  396. }
  397. if (!(func_ctx->mem_info[0].mem_bound_check_4bytes =
  398. LLVMBuildBitCast(comp_ctx->builder,
  399. func_ctx->mem_info[0].mem_bound_check_4bytes,
  400. bound_check_type, "bound_check_4bytes_ptr"))) {
  401. aot_set_last_error("llvm build bit cast failed");
  402. return false;
  403. }
  404. if (mem_space_unchanged) {
  405. if (!(func_ctx->mem_info[0].mem_bound_check_4bytes =
  406. LLVMBuildLoad(comp_ctx->builder,
  407. func_ctx->mem_info[0].mem_bound_check_4bytes,
  408. "bound_check_4bytes"))) {
  409. aot_set_last_error("llvm build load failed");
  410. return false;
  411. }
  412. }
  413. offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_8bytes)
  414. - offsetof(AOTMemoryInstance, memory_data.ptr));
  415. if (!(func_ctx->mem_info[0].mem_bound_check_8bytes =
  416. LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base,
  417. &offset, 1, "bound_check_8bytes_offset"))) {
  418. aot_set_last_error("llvm build in bounds gep failed");
  419. return false;
  420. }
  421. if (!(func_ctx->mem_info[0].mem_bound_check_8bytes =
  422. LLVMBuildBitCast(comp_ctx->builder,
  423. func_ctx->mem_info[0].mem_bound_check_8bytes,
  424. bound_check_type, "bound_check_8bytes_ptr"))) {
  425. aot_set_last_error("llvm build bit cast failed");
  426. return false;
  427. }
  428. if (mem_space_unchanged) {
  429. if (!(func_ctx->mem_info[0].mem_bound_check_8bytes =
  430. LLVMBuildLoad(comp_ctx->builder,
  431. func_ctx->mem_info[0].mem_bound_check_8bytes,
  432. "bound_check_8bytes"))) {
  433. aot_set_last_error("llvm build load failed");
  434. return false;
  435. }
  436. }
  437. offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_16bytes)
  438. - offsetof(AOTMemoryInstance, memory_data.ptr));
  439. if (!(func_ctx->mem_info[0].mem_bound_check_16bytes =
  440. LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base,
  441. &offset, 1, "bound_check_16bytes_offset"))) {
  442. aot_set_last_error("llvm build in bounds gep failed");
  443. return false;
  444. }
  445. if (!(func_ctx->mem_info[0].mem_bound_check_16bytes =
  446. LLVMBuildBitCast(comp_ctx->builder,
  447. func_ctx->mem_info[0].mem_bound_check_16bytes,
  448. bound_check_type, "bound_check_16bytes_ptr"))) {
  449. aot_set_last_error("llvm build bit cast failed");
  450. return false;
  451. }
  452. if (mem_space_unchanged) {
  453. if (!(func_ctx->mem_info[0].mem_bound_check_16bytes =
  454. LLVMBuildLoad(comp_ctx->builder,
  455. func_ctx->mem_info[0].mem_bound_check_16bytes,
  456. "bound_check_16bytes"))) {
  457. aot_set_last_error("llvm build load failed");
  458. return false;
  459. }
  460. }
  461. return true;
  462. }
  463. static bool
  464. create_cur_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
  465. {
  466. LLVMValueRef offset;
  467. offset = I32_CONST(offsetof(AOTModuleInstance, cur_exception));
  468. func_ctx->cur_exception = LLVMBuildInBoundsGEP(comp_ctx->builder,
  469. func_ctx->aot_inst,
  470. &offset, 1,
  471. "cur_execption");
  472. if (!func_ctx->cur_exception) {
  473. aot_set_last_error("llvm build in bounds gep failed.");
  474. return false;
  475. }
  476. return true;
  477. }
  478. static bool
  479. create_func_type_indexes(AOTCompContext *comp_ctx,
  480. AOTFuncContext *func_ctx)
  481. {
  482. LLVMValueRef offset, func_type_indexes_ptr;
  483. LLVMTypeRef int32_ptr_type;
  484. offset = I32_CONST(offsetof(AOTModuleInstance, func_type_indexes.ptr));
  485. func_type_indexes_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder,
  486. func_ctx->aot_inst,
  487. &offset, 1,
  488. "func_type_indexes_ptr");
  489. if (!func_type_indexes_ptr) {
  490. aot_set_last_error("llvm build add failed.");
  491. return false;
  492. }
  493. if (!(int32_ptr_type = LLVMPointerType(INT32_PTR_TYPE, 0))) {
  494. aot_set_last_error("llvm get pointer type failed.");
  495. return false;
  496. }
  497. func_ctx->func_type_indexes = LLVMBuildBitCast(comp_ctx->builder,
  498. func_type_indexes_ptr,
  499. int32_ptr_type,
  500. "func_type_indexes_tmp");
  501. if (!func_ctx->func_type_indexes) {
  502. aot_set_last_error("llvm build bit cast failed.");
  503. return false;
  504. }
  505. func_ctx->func_type_indexes = LLVMBuildLoad(comp_ctx->builder,
  506. func_ctx->func_type_indexes,
  507. "func_type_indexes");
  508. if (!func_ctx->func_type_indexes) {
  509. aot_set_last_error("llvm build load failed.");
  510. return false;
  511. }
  512. return true;
  513. }
  514. static bool
  515. create_func_ptrs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
  516. {
  517. LLVMValueRef offset;
  518. offset = I32_CONST(offsetof(AOTModuleInstance, func_ptrs));
  519. func_ctx->func_ptrs = LLVMBuildInBoundsGEP(comp_ctx->builder,
  520. func_ctx->aot_inst,
  521. &offset, 1, "func_ptrs_offset");
  522. if (!func_ctx->func_ptrs) {
  523. aot_set_last_error("llvm build in bounds gep failed.");
  524. return false;
  525. }
  526. func_ctx->func_ptrs = LLVMBuildBitCast(comp_ctx->builder, func_ctx->func_ptrs,
  527. comp_ctx->exec_env_type, "func_ptrs_tmp");
  528. if (!func_ctx->func_ptrs) {
  529. aot_set_last_error("llvm build bit cast failed.");
  530. return false;
  531. }
  532. func_ctx->func_ptrs = LLVMBuildLoad(comp_ctx->builder, func_ctx->func_ptrs,
  533. "func_ptrs_ptr");
  534. if (!func_ctx->func_ptrs) {
  535. aot_set_last_error("llvm build load failed.");
  536. return false;
  537. }
  538. func_ctx->func_ptrs = LLVMBuildBitCast(comp_ctx->builder, func_ctx->func_ptrs,
  539. comp_ctx->exec_env_type, "func_ptrs");
  540. if (!func_ctx->func_ptrs) {
  541. aot_set_last_error("llvm build bit cast failed.");
  542. return false;
  543. }
  544. return true;
  545. }
  546. /**
  547. * Create function compiler context
  548. */
  549. static AOTFuncContext *
  550. aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
  551. AOTFunc *func, uint32 func_index)
  552. {
  553. AOTFuncContext *func_ctx;
  554. AOTFuncType *aot_func_type = comp_data->func_types[func->func_type_index];
  555. AOTBlock *aot_block;
  556. LLVMTypeRef int8_ptr_type, int32_ptr_type;
  557. LLVMValueRef aot_inst_offset = I32_TWO, aot_inst_addr;
  558. LLVMValueRef argv_buf_offset = I32_THREE, argv_buf_addr;
  559. LLVMValueRef stack_bound_offset = I32_FOUR, stack_bound_addr;
  560. LLVMValueRef aux_stack_bound_offset = I32_SIX, aux_stack_bound_addr;
  561. LLVMValueRef aux_stack_bottom_offset = I32_SEVEN, aux_stack_bottom_addr;
  562. LLVMValueRef native_symbol_offset = I32_EIGHT, native_symbol_addr;
  563. char local_name[32];
  564. uint64 size;
  565. uint32 i, j = 0;
  566. /* Allocate memory for the function context */
  567. size = offsetof(AOTFuncContext, locals) + sizeof(LLVMValueRef) *
  568. ((uint64)aot_func_type->param_count + func->local_count);
  569. if (size >= UINT32_MAX
  570. || !(func_ctx = wasm_runtime_malloc((uint32)size))) {
  571. aot_set_last_error("allocate memory failed.");
  572. return NULL;
  573. }
  574. memset(func_ctx, 0, (uint32)size);
  575. func_ctx->aot_func = func;
  576. /* Add LLVM function */
  577. if (!(func_ctx->func = aot_add_llvm_func(comp_ctx, aot_func_type,
  578. func_index, &func_ctx->func_type)))
  579. goto fail;
  580. /* Create function's first AOTBlock */
  581. if (!(aot_block = aot_create_func_block(comp_ctx, func_ctx,
  582. func, aot_func_type)))
  583. goto fail;
  584. aot_block_stack_push(&func_ctx->block_stack, aot_block);
  585. /* Add local variables */
  586. LLVMPositionBuilderAtEnd(comp_ctx->builder, aot_block->llvm_entry_block);
  587. /* Save the pameters for fast access */
  588. func_ctx->exec_env = LLVMGetParam(func_ctx->func, j++);
  589. /* Get aot inst address, the layout of exec_env is:
  590. exec_env->next, exec_env->prev, exec_env->module_inst, and argv_buf */
  591. if (!(aot_inst_addr =
  592. LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
  593. &aot_inst_offset, 1, "aot_inst_addr"))) {
  594. aot_set_last_error("llvm build in bounds gep failed");
  595. goto fail;
  596. }
  597. /* Load aot inst */
  598. if (!(func_ctx->aot_inst = LLVMBuildLoad(comp_ctx->builder,
  599. aot_inst_addr, "aot_inst"))) {
  600. aot_set_last_error("llvm build load failed");
  601. goto fail;
  602. }
  603. /* Get argv buffer address */
  604. if (!(argv_buf_addr =
  605. LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
  606. &argv_buf_offset, 1, "argv_buf_addr"))) {
  607. aot_set_last_error("llvm build in bounds gep failed");
  608. goto fail;
  609. }
  610. if (!(int32_ptr_type = LLVMPointerType(INT32_PTR_TYPE, 0))) {
  611. aot_set_last_error("llvm add pointer type failed");
  612. goto fail;
  613. }
  614. /* Convert to int32 pointer type */
  615. if (!(argv_buf_addr = LLVMBuildBitCast(comp_ctx->builder, argv_buf_addr,
  616. int32_ptr_type, "argv_buf_ptr"))) {
  617. aot_set_last_error("llvm build load failed");
  618. goto fail;
  619. }
  620. if (!(func_ctx->argv_buf = LLVMBuildLoad(comp_ctx->builder,
  621. argv_buf_addr, "argv_buf"))) {
  622. aot_set_last_error("llvm build load failed");
  623. goto fail;
  624. }
  625. /* Get native stack boundary address */
  626. if (!(stack_bound_addr =
  627. LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
  628. &stack_bound_offset, 1, "stack_bound_addr"))) {
  629. aot_set_last_error("llvm build in bounds gep failed");
  630. goto fail;
  631. }
  632. if (!(func_ctx->native_stack_bound =
  633. LLVMBuildLoad(comp_ctx->builder,
  634. stack_bound_addr, "native_stack_bound"))) {
  635. aot_set_last_error("llvm build load failed");
  636. goto fail;
  637. }
  638. /* Get aux stack boundary address */
  639. if (!(aux_stack_bound_addr =
  640. LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
  641. &aux_stack_bound_offset, 1,
  642. "aux_stack_bound_addr"))) {
  643. aot_set_last_error("llvm build in bounds gep failed");
  644. goto fail;
  645. }
  646. if (!(aux_stack_bound_addr =
  647. LLVMBuildBitCast(comp_ctx->builder,
  648. aux_stack_bound_addr,
  649. INT32_PTR_TYPE, "aux_stack_bound_ptr"))) {
  650. aot_set_last_error("llvm build bit cast failed");
  651. goto fail;
  652. }
  653. if (!(func_ctx->aux_stack_bound =
  654. LLVMBuildLoad(comp_ctx->builder,
  655. aux_stack_bound_addr, "aux_stack_bound"))) {
  656. aot_set_last_error("llvm build load failed");
  657. goto fail;
  658. }
  659. /* Get aux stack bottom address */
  660. if (!(aux_stack_bottom_addr =
  661. LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
  662. &aux_stack_bottom_offset, 1,
  663. "aux_stack_bottom_addr"))) {
  664. aot_set_last_error("llvm build in bounds gep failed");
  665. goto fail;
  666. }
  667. if (!(aux_stack_bottom_addr =
  668. LLVMBuildBitCast(comp_ctx->builder,
  669. aux_stack_bottom_addr,
  670. INT32_PTR_TYPE, "aux_stack_bottom_ptr"))) {
  671. aot_set_last_error("llvm build bit cast failed");
  672. goto fail;
  673. }
  674. if (!(func_ctx->aux_stack_bottom =
  675. LLVMBuildLoad(comp_ctx->builder,
  676. aux_stack_bottom_addr, "aux_stack_bottom"))) {
  677. aot_set_last_error("llvm build load failed");
  678. goto fail;
  679. }
  680. if (!(native_symbol_addr =
  681. LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
  682. &native_symbol_offset, 1, "native_symbol_addr"))) {
  683. aot_set_last_error("llvm build in bounds gep failed");
  684. goto fail;
  685. }
  686. if (!(func_ctx->native_symbol =
  687. LLVMBuildLoad(comp_ctx->builder, native_symbol_addr,
  688. "native_symbol_tmp"))) {
  689. aot_set_last_error("llvm build bit cast failed");
  690. goto fail;
  691. }
  692. if (!(func_ctx->native_symbol =
  693. LLVMBuildBitCast(comp_ctx->builder, func_ctx->native_symbol,
  694. comp_ctx->exec_env_type, "native_symbol"))) {
  695. aot_set_last_error("llvm build bit cast failed");
  696. goto fail;
  697. }
  698. for (i = 0; i < aot_func_type->param_count; i++, j++) {
  699. snprintf(local_name, sizeof(local_name), "l%d", i);
  700. func_ctx->locals[i] =
  701. LLVMBuildAlloca(comp_ctx->builder,
  702. TO_LLVM_TYPE(aot_func_type->types[i]),
  703. local_name);
  704. if (!func_ctx->locals[i]) {
  705. aot_set_last_error("llvm build alloca failed.");
  706. goto fail;
  707. }
  708. if (!LLVMBuildStore(comp_ctx->builder,
  709. LLVMGetParam(func_ctx->func, j),
  710. func_ctx->locals[i])) {
  711. aot_set_last_error("llvm build store failed.");
  712. goto fail;
  713. }
  714. }
  715. for (i = 0; i < func->local_count; i++) {
  716. LLVMTypeRef local_type;
  717. LLVMValueRef local_value = NULL;
  718. snprintf(local_name, sizeof(local_name), "l%d",
  719. aot_func_type->param_count + i);
  720. local_type = TO_LLVM_TYPE(func->local_types[i]);
  721. func_ctx->locals[aot_func_type->param_count + i] =
  722. LLVMBuildAlloca(comp_ctx->builder, local_type, local_name);
  723. if (!func_ctx->locals[aot_func_type->param_count + i]) {
  724. aot_set_last_error("llvm build alloca failed.");
  725. goto fail;
  726. }
  727. switch (func->local_types[i]) {
  728. case VALUE_TYPE_I32:
  729. local_value = I32_ZERO;
  730. break;
  731. case VALUE_TYPE_I64:
  732. local_value = I64_ZERO;
  733. break;
  734. case VALUE_TYPE_F32:
  735. local_value = F32_ZERO;
  736. break;
  737. case VALUE_TYPE_F64:
  738. local_value = F64_ZERO;
  739. break;
  740. case VALUE_TYPE_V128:
  741. local_value = V128_ZERO;
  742. break;
  743. case VALUE_TYPE_FUNCREF:
  744. case VALUE_TYPE_EXTERNREF:
  745. local_value = REF_NULL;
  746. break;
  747. default:
  748. bh_assert(0);
  749. break;
  750. }
  751. if (!LLVMBuildStore(comp_ctx->builder, local_value,
  752. func_ctx->locals[aot_func_type->param_count + i])) {
  753. aot_set_last_error("llvm build store failed.");
  754. goto fail;
  755. }
  756. }
  757. if (aot_func_type->param_count + func->local_count > 0) {
  758. func_ctx->last_alloca = func_ctx->locals[aot_func_type->param_count
  759. + func->local_count - 1];
  760. if (!(func_ctx->last_alloca =
  761. LLVMBuildBitCast(comp_ctx->builder, func_ctx->last_alloca,
  762. INT8_PTR_TYPE, "stack_ptr"))) {
  763. aot_set_last_error("llvm build bit cast failed.");
  764. goto fail;
  765. }
  766. }
  767. else {
  768. if (!(func_ctx->last_alloca = LLVMBuildAlloca(comp_ctx->builder, INT8_TYPE,
  769. "stack_ptr"))) {
  770. aot_set_last_error("llvm build alloca failed.");
  771. goto fail;
  772. }
  773. }
  774. if (!(int8_ptr_type = LLVMPointerType(INT8_PTR_TYPE, 0))) {
  775. aot_set_last_error("llvm add pointer type failed.");
  776. goto fail;
  777. }
  778. /* Create base addr, end addr, data size of mem, heap */
  779. if (!create_memory_info(comp_ctx, func_ctx, int8_ptr_type, func_index))
  780. goto fail;
  781. /* Load current exception */
  782. if (!create_cur_exception(comp_ctx, func_ctx))
  783. goto fail;
  784. /* Load function type indexes */
  785. if (!create_func_type_indexes(comp_ctx, func_ctx))
  786. goto fail;
  787. /* Load function pointers */
  788. if (!create_func_ptrs(comp_ctx, func_ctx))
  789. goto fail;
  790. return func_ctx;
  791. fail:
  792. if (func_ctx->mem_info)
  793. wasm_runtime_free(func_ctx->mem_info);
  794. aot_block_stack_destroy(&func_ctx->block_stack);
  795. wasm_runtime_free(func_ctx);
  796. return NULL;
  797. }
  798. static void
  799. aot_destroy_func_contexts(AOTFuncContext **func_ctxes, uint32 count)
  800. {
  801. uint32 i;
  802. for (i = 0; i < count; i++)
  803. if (func_ctxes[i]) {
  804. if (func_ctxes[i]->mem_info)
  805. wasm_runtime_free(func_ctxes[i]->mem_info);
  806. aot_block_stack_destroy(&func_ctxes[i]->block_stack);
  807. aot_checked_addr_list_destroy(func_ctxes[i]);
  808. wasm_runtime_free(func_ctxes[i]);
  809. }
  810. wasm_runtime_free(func_ctxes);
  811. }
  812. /**
  813. * Create function compiler contexts
  814. */
  815. static AOTFuncContext **
  816. aot_create_func_contexts(AOTCompData *comp_data, AOTCompContext *comp_ctx)
  817. {
  818. AOTFuncContext **func_ctxes;
  819. uint64 size;
  820. uint32 i;
  821. /* Allocate memory */
  822. size = sizeof(AOTFuncContext*) * (uint64)comp_data->func_count;
  823. if (size >= UINT32_MAX
  824. || !(func_ctxes = wasm_runtime_malloc((uint32)size))) {
  825. aot_set_last_error("allocate memory failed.");
  826. return NULL;
  827. }
  828. memset(func_ctxes, 0, size);
  829. /* Create each function context */
  830. for (i = 0; i < comp_data->func_count; i++) {
  831. AOTFunc *func = comp_data->funcs[i];
  832. if (!(func_ctxes[i] = aot_create_func_context(comp_data, comp_ctx,
  833. func, i))) {
  834. aot_destroy_func_contexts(func_ctxes, comp_data->func_count);
  835. return NULL;
  836. }
  837. }
  838. return func_ctxes;
  839. }
  840. static bool
  841. aot_set_llvm_basic_types(AOTLLVMTypes *basic_types, LLVMContextRef context)
  842. {
  843. basic_types->int1_type = LLVMInt1TypeInContext(context);
  844. basic_types->int8_type = LLVMInt8TypeInContext(context);
  845. basic_types->int16_type = LLVMInt16TypeInContext(context);
  846. basic_types->int32_type = LLVMInt32TypeInContext(context);
  847. basic_types->int64_type = LLVMInt64TypeInContext(context);
  848. basic_types->float32_type = LLVMFloatTypeInContext(context);
  849. basic_types->float64_type = LLVMDoubleTypeInContext(context);
  850. basic_types->void_type = LLVMVoidTypeInContext(context);
  851. basic_types->meta_data_type = LLVMMetadataTypeInContext(context);
  852. basic_types->int8_ptr_type = LLVMPointerType(basic_types->int8_type, 0);
  853. if (basic_types->int8_ptr_type) {
  854. basic_types->int8_pptr_type =
  855. LLVMPointerType(basic_types->int8_ptr_type, 0);
  856. }
  857. basic_types->int16_ptr_type = LLVMPointerType(basic_types->int16_type, 0);
  858. basic_types->int32_ptr_type = LLVMPointerType(basic_types->int32_type, 0);
  859. basic_types->int64_ptr_type = LLVMPointerType(basic_types->int64_type, 0);
  860. basic_types->float32_ptr_type = LLVMPointerType(basic_types->float32_type, 0);
  861. basic_types->float64_ptr_type = LLVMPointerType(basic_types->float64_type, 0);
  862. basic_types->i8x16_vec_type = LLVMVectorType(basic_types->int8_type, 16);
  863. basic_types->i16x8_vec_type = LLVMVectorType(basic_types->int16_type, 8);
  864. basic_types->i32x4_vec_type = LLVMVectorType(basic_types->int32_type, 4);
  865. basic_types->i64x2_vec_type = LLVMVectorType(basic_types->int64_type, 2);
  866. basic_types->f32x4_vec_type = LLVMVectorType(basic_types->float32_type, 4);
  867. basic_types->f64x2_vec_type = LLVMVectorType(basic_types->float64_type, 2);
  868. basic_types->v128_type = basic_types->i64x2_vec_type;
  869. basic_types->v128_ptr_type = LLVMPointerType(basic_types->v128_type, 0);
  870. basic_types->funcref_type = LLVMInt32TypeInContext(context);
  871. basic_types->externref_type = LLVMInt32TypeInContext(context);
  872. return (basic_types->int8_ptr_type
  873. && basic_types->int8_pptr_type
  874. && basic_types->int16_ptr_type
  875. && basic_types->int32_ptr_type
  876. && basic_types->int64_ptr_type
  877. && basic_types->float32_ptr_type
  878. && basic_types->float64_ptr_type
  879. && basic_types->i8x16_vec_type
  880. && basic_types->i16x8_vec_type
  881. && basic_types->i32x4_vec_type
  882. && basic_types->i64x2_vec_type
  883. && basic_types->f32x4_vec_type
  884. && basic_types->f64x2_vec_type
  885. && basic_types->meta_data_type
  886. && basic_types->funcref_type
  887. && basic_types->externref_type) ? true : false;
  888. }
  889. static bool
  890. aot_create_llvm_consts(AOTLLVMConsts *consts, AOTCompContext *comp_ctx)
  891. {
  892. LLVMValueRef i64_consts[2];
  893. consts->i8_zero = I8_CONST(0);
  894. consts->i32_zero = I32_CONST(0);
  895. consts->i64_zero = I64_CONST(0);
  896. consts->f32_zero = F32_CONST(0);
  897. consts->f64_zero = F64_CONST(0);
  898. if (consts->i64_zero) {
  899. i64_consts[0] = i64_consts[1] = consts->i64_zero;
  900. consts->v128_zero = consts->i64x2_vec_zero =
  901. LLVMConstVector(i64_consts, 2);
  902. if (consts->i64x2_vec_zero) {
  903. consts->i8x16_vec_zero = TO_V128_i8x16(consts->i64x2_vec_zero);
  904. consts->i16x8_vec_zero = TO_V128_i16x8(consts->i64x2_vec_zero);
  905. consts->i32x4_vec_zero = TO_V128_i32x4(consts->i64x2_vec_zero);
  906. consts->f32x4_vec_zero = TO_V128_f32x4(consts->i64x2_vec_zero);
  907. consts->f64x2_vec_zero = TO_V128_f64x2(consts->i64x2_vec_zero);
  908. }
  909. }
  910. consts->i32_one = I32_CONST(1);
  911. consts->i32_two = I32_CONST(2);
  912. consts->i32_three = I32_CONST(3);
  913. consts->i32_four = I32_CONST(4);
  914. consts->i32_five = I32_CONST(5);
  915. consts->i32_six = I32_CONST(6);
  916. consts->i32_seven = I32_CONST(7);
  917. consts->i32_eight = I32_CONST(8);
  918. consts->i32_neg_one = I32_CONST((uint32)-1);
  919. consts->i64_neg_one = I64_CONST((uint64)-1);
  920. consts->i32_min = I32_CONST((uint32)INT32_MIN);
  921. consts->i64_min = I64_CONST((uint64)INT64_MIN);
  922. consts->i32_31 = I32_CONST(31);
  923. consts->i32_32 = I32_CONST(32);
  924. consts->i64_63 = I64_CONST(63);
  925. consts->i64_64 = I64_CONST(64);
  926. consts->ref_null = I32_CONST(NULL_REF);
  927. return (consts->i8_zero
  928. && consts->i32_zero
  929. && consts->i64_zero
  930. && consts->f32_zero
  931. && consts->f64_zero
  932. && consts->i8x16_vec_zero
  933. && consts->i16x8_vec_zero
  934. && consts->i32x4_vec_zero
  935. && consts->i64x2_vec_zero
  936. && consts->f32x4_vec_zero
  937. && consts->f64x2_vec_zero
  938. && consts->i32_one
  939. && consts->i32_two
  940. && consts->i32_three
  941. && consts->i32_four
  942. && consts->i32_five
  943. && consts->i32_six
  944. && consts->i32_seven
  945. && consts->i32_eight
  946. && consts->i32_neg_one
  947. && consts->i64_neg_one
  948. && consts->i32_min
  949. && consts->i64_min
  950. && consts->i32_31
  951. && consts->i32_32
  952. && consts->i64_63
  953. && consts->i64_64
  954. && consts->ref_null) ? true : false;
  955. }
  956. typedef struct ArchItem {
  957. char *arch;
  958. bool support_eb;
  959. } ArchItem;
  960. static ArchItem valid_archs[] = {
  961. { "x86_64", false },
  962. { "i386", false },
  963. { "xtensa", false},
  964. { "mips", true },
  965. { "aarch64v8", false },
  966. { "aarch64v8.1", false },
  967. { "aarch64v8.2", false },
  968. { "aarch64v8.3", false },
  969. { "aarch64v8.4", false },
  970. { "aarch64v8.5", false },
  971. { "aarch64_bev8", false }, /* big endian */
  972. { "aarch64_bev8.1", false },
  973. { "aarch64_bev8.2", false },
  974. { "aarch64_bev8.3", false },
  975. { "aarch64_bev8.4", false },
  976. { "aarch64_bev8.5", false },
  977. { "armv4", true },
  978. { "armv4t", true },
  979. { "armv5t", true },
  980. { "armv5te", true },
  981. { "armv5tej", true },
  982. { "armv6", true },
  983. { "armv6kz", true },
  984. { "armv6t2", true },
  985. { "armv6k", true },
  986. { "armv7", true },
  987. { "armv6m", true },
  988. { "armv6sm", true },
  989. { "armv7em", true },
  990. { "armv8a", true },
  991. { "armv8r", true },
  992. { "armv8m.base", true },
  993. { "armv8m.main", true },
  994. { "armv8.1m.main", true },
  995. { "thumbv4", true },
  996. { "thumbv4t", true },
  997. { "thumbv5t", true },
  998. { "thumbv5te", true },
  999. { "thumbv5tej", true },
  1000. { "thumbv6", true },
  1001. { "thumbv6kz", true },
  1002. { "thumbv6t2", true },
  1003. { "thumbv6k", true },
  1004. { "thumbv7", true },
  1005. { "thumbv6m", true },
  1006. { "thumbv6sm", true },
  1007. { "thumbv7em", true },
  1008. { "thumbv8a", true },
  1009. { "thumbv8r", true },
  1010. { "thumbv8m.base", true },
  1011. { "thumbv8m.main", true },
  1012. { "thumbv8.1m.main", true },
  1013. { "riscv32", true},
  1014. { "riscv64", true},
  1015. { "arc", true }
  1016. };
  1017. static const char *valid_abis[] = {
  1018. "gnu",
  1019. "eabi",
  1020. "gnueabihf",
  1021. "msvc",
  1022. "ilp32",
  1023. "ilp32f",
  1024. "ilp32d",
  1025. "lp64",
  1026. "lp64f",
  1027. "lp64d"
  1028. };
  1029. static void
  1030. print_supported_targets()
  1031. {
  1032. uint32 i;
  1033. os_printf("Supported targets:\n");
  1034. for (i = 0; i < sizeof(valid_archs) / sizeof(ArchItem); i++) {
  1035. os_printf("%s ", valid_archs[i].arch);
  1036. if (valid_archs[i].support_eb)
  1037. os_printf("%seb ", valid_archs[i].arch);
  1038. }
  1039. os_printf("\n");
  1040. }
  1041. static void
  1042. print_supported_abis()
  1043. {
  1044. uint32 i;
  1045. os_printf("Supported ABI: ");
  1046. for (i = 0; i < sizeof(valid_abis) / sizeof(const char *); i++)
  1047. os_printf("%s ", valid_abis[i]);
  1048. os_printf("\n");
  1049. }
  1050. static bool
  1051. check_target_arch(const char *target_arch)
  1052. {
  1053. uint32 i;
  1054. char *arch;
  1055. bool support_eb;
  1056. for (i = 0; i < sizeof(valid_archs) / sizeof(ArchItem); i++) {
  1057. arch = valid_archs[i].arch;
  1058. support_eb = valid_archs[i].support_eb;
  1059. if (!strncmp(target_arch, arch, strlen(arch))
  1060. && ((support_eb && (!strcmp(target_arch + strlen(arch), "eb")
  1061. || !strcmp(target_arch + strlen(arch), "")))
  1062. || (!support_eb && !strcmp(target_arch + strlen(arch), "")))) {
  1063. return true;
  1064. }
  1065. }
  1066. return false;
  1067. }
  1068. static bool
  1069. check_target_abi(const char *target_abi)
  1070. {
  1071. uint32 i;
  1072. for (i = 0; i < sizeof(valid_abis) / sizeof(char *); i++) {
  1073. if (!strcmp(target_abi, valid_abis[i]))
  1074. return true;
  1075. }
  1076. return false;
  1077. }
  1078. static void
  1079. get_target_arch_from_triple(const char *triple, char *arch_buf, uint32 buf_size)
  1080. {
  1081. uint32 i = 0;
  1082. while (*triple != '-' && *triple != '\0' && i < buf_size - 1)
  1083. arch_buf[i++] = *triple++;
  1084. /* Make sure buffer is long enough */
  1085. bh_assert(*triple == '-' || *triple == '\0');
  1086. }
  1087. LLVMBool
  1088. WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
  1089. LLVMModuleRef M,
  1090. struct LLVMMCJITCompilerOptions *Options,
  1091. size_t SizeOfOptions,
  1092. char **OutError);
  1093. void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM);
  1094. #if WASM_ENABLE_LAZY_JIT != 0
  1095. void
  1096. aot_handle_llvm_errmsg(char *error_buf,
  1097. uint32 error_buf_size,
  1098. const char *string,
  1099. LLVMErrorRef error)
  1100. {
  1101. char *err_msg = LLVMGetErrorMessage(error);
  1102. if (error_buf != NULL) {
  1103. snprintf(error_buf, error_buf_size,
  1104. "%s: %s", string, err_msg);
  1105. }
  1106. LLVMDisposeErrorMessage(err_msg);
  1107. }
  1108. static bool
  1109. llvm_orcjit_create(AOTCompContext *comp_ctx)
  1110. {
  1111. char *err_msg = NULL;
  1112. char *cpu = NULL;
  1113. char *features = NULL;
  1114. char *llvm_triple = NULL;
  1115. char buf[128] = {0};
  1116. LLVMErrorRef error;
  1117. LLVMTargetRef llvm_targetref = NULL;
  1118. LLVMTargetMachineRef tm_opt = NULL;
  1119. LLVMTargetMachineRef tm_opt2 = NULL;
  1120. LLVMOrcLLLazyJITRef lazy_orcjit = NULL;
  1121. LLVMOrcJITTargetMachineBuilderRef tm_builder = NULL;
  1122. LLVMOrcLLLazyJITBuilderRef lazy_orcjit_builder = NULL;
  1123. #if LLVM_VERSION_MAJOR < 12
  1124. LLVMOrcJITDylibDefinitionGeneratorRef main_gen = NULL;
  1125. #else
  1126. LLVMOrcDefinitionGeneratorRef main_gen = NULL;
  1127. #endif
  1128. llvm_triple = LLVMGetDefaultTargetTriple();
  1129. if (llvm_triple == NULL) {
  1130. snprintf(buf, sizeof(buf), "failed to get default target triple.");
  1131. goto fail;
  1132. }
  1133. if (LLVMGetTargetFromTriple(llvm_triple, &llvm_targetref, &err_msg) != 0) {
  1134. snprintf(buf, sizeof(buf),
  1135. "failed to get target reference from triple %s.", err_msg);
  1136. LLVMDisposeMessage(err_msg);
  1137. goto fail;
  1138. }
  1139. if (!LLVMTargetHasJIT(llvm_targetref)) {
  1140. snprintf(buf, sizeof(buf), "unspported JIT on this platform.");
  1141. goto fail;
  1142. }
  1143. cpu = LLVMGetHostCPUName();
  1144. if (cpu == NULL) {
  1145. snprintf(buf, sizeof(buf), "failed to get host cpu information.");
  1146. goto fail;
  1147. }
  1148. features = LLVMGetHostCPUFeatures();
  1149. if (features == NULL) {
  1150. snprintf(buf, sizeof(buf), "failed to get host cpu features.");
  1151. goto fail;
  1152. }
  1153. LOG_VERBOSE("LLVM ORCJIT detected CPU \"%s\", with features \"%s\"\n",
  1154. cpu, features);
  1155. tm_opt = LLVMCreateTargetMachine(llvm_targetref, llvm_triple,
  1156. cpu, features,
  1157. LLVMCodeGenLevelAggressive,
  1158. LLVMRelocDefault,
  1159. LLVMCodeModelJITDefault);
  1160. if (!tm_opt) {
  1161. snprintf(buf, sizeof(buf), "failed to create target machine.");
  1162. goto fail;
  1163. }
  1164. tm_opt2 = LLVMCreateTargetMachine(llvm_targetref, llvm_triple,
  1165. cpu, features,
  1166. LLVMCodeGenLevelAggressive,
  1167. LLVMRelocDefault,
  1168. LLVMCodeModelJITDefault);
  1169. if (!tm_opt2) {
  1170. snprintf(buf, sizeof(buf), "failed to create target machine2.");
  1171. goto fail;
  1172. }
  1173. /* if success, it will dispose tm_opt2 memory. */
  1174. tm_builder = LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(tm_opt2);
  1175. if (!tm_builder) {
  1176. snprintf(buf, sizeof(buf), "failed to create target machine builder.");
  1177. goto fail;
  1178. }
  1179. tm_opt2 = NULL;
  1180. lazy_orcjit_builder = LLVMOrcCreateLLLazyJITBuilder();
  1181. if (!lazy_orcjit_builder) {
  1182. snprintf(buf, sizeof(buf), "failed to create lazy jit builder.");
  1183. goto fail;
  1184. }
  1185. LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder(lazy_orcjit_builder,
  1186. tm_builder);
  1187. /* if success, it will dispose lazy_orcjit_builder memory */
  1188. error = LLVMOrcCreateLLLazyJIT(&lazy_orcjit, lazy_orcjit_builder);
  1189. if (error) {
  1190. aot_handle_llvm_errmsg(buf, sizeof(buf),
  1191. "failed to create llvm lazy orcjit instance",
  1192. error);
  1193. goto fail;
  1194. }
  1195. lazy_orcjit_builder = NULL;
  1196. error = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
  1197. &main_gen, LLVMOrcLLLazyJITGetGlobalPrefix(lazy_orcjit),
  1198. 0, NULL);
  1199. if (error) {
  1200. aot_handle_llvm_errmsg(buf, sizeof(buf),
  1201. "failed to create dynmaic library search generator", error);
  1202. goto fail;
  1203. }
  1204. LLVMOrcJITDylibAddGenerator(LLVMOrcLLLazyJITGetMainJITDylib(lazy_orcjit),
  1205. main_gen);
  1206. comp_ctx->lazy_orcjit = lazy_orcjit;
  1207. comp_ctx->target_machine = tm_opt;
  1208. comp_ctx->tm_builder = tm_builder;
  1209. LLVMDisposeMessage(llvm_triple);
  1210. LLVMDisposeMessage(cpu);
  1211. LLVMDisposeMessage(features);
  1212. return true;
  1213. fail:
  1214. if (lazy_orcjit)
  1215. LLVMOrcDisposeLLLazyJIT(lazy_orcjit);
  1216. if (tm_builder)
  1217. LLVMOrcDisposeJITTargetMachineBuilder(tm_builder);
  1218. if (lazy_orcjit_builder)
  1219. LLVMOrcDisposeLLLazyJITBuilder(lazy_orcjit_builder);
  1220. if (tm_opt2)
  1221. LLVMDisposeTargetMachine(tm_opt2);
  1222. if (tm_opt)
  1223. LLVMDisposeTargetMachine(tm_opt);
  1224. if (features)
  1225. LLVMDisposeMessage(features);
  1226. if (cpu)
  1227. LLVMDisposeMessage(cpu);
  1228. if (llvm_triple)
  1229. LLVMDisposeMessage(llvm_triple);
  1230. aot_set_last_error(buf);
  1231. return false;
  1232. }
  1233. #endif /* WASM_ENABLE_LAZY_JIT != 0 */
  1234. AOTCompContext *
  1235. aot_create_comp_context(AOTCompData *comp_data,
  1236. aot_comp_option_t option)
  1237. {
  1238. AOTCompContext *comp_ctx, *ret = NULL;
  1239. #if WASM_ENABLE_LAZY_JIT == 0
  1240. struct LLVMMCJITCompilerOptions jit_options;
  1241. #endif
  1242. LLVMTargetRef target;
  1243. char *triple = NULL, *triple_norm, *arch, *abi;
  1244. char *cpu = NULL, *features, buf[128];
  1245. char *triple_norm_new = NULL, *cpu_new = NULL;
  1246. char *err = NULL, *fp_round= "round.tonearest", *fp_exce = "fpexcept.strict";
  1247. char triple_buf[32] = { 0 }, features_buf[128] = { 0 };
  1248. uint32 opt_level, size_level;
  1249. LLVMCodeModel code_model;
  1250. LLVMTargetDataRef target_data_ref;
  1251. /* Initialize LLVM environment */
  1252. #if WASM_ENABLE_LAZY_JIT != 0
  1253. LLVMInitializeCore(LLVMGetGlobalPassRegistry());
  1254. LLVMInitializeNativeTarget();
  1255. LLVMInitializeNativeAsmPrinter();
  1256. LLVMInitializeNativeAsmParser();
  1257. #else
  1258. LLVMInitializeAllTargetInfos();
  1259. LLVMInitializeAllTargets();
  1260. LLVMInitializeAllTargetMCs();
  1261. LLVMInitializeAllAsmPrinters();
  1262. LLVMLinkInMCJIT();
  1263. #endif
  1264. /* Allocate memory */
  1265. if (!(comp_ctx = wasm_runtime_malloc(sizeof(AOTCompContext)))) {
  1266. aot_set_last_error("allocate memory failed.");
  1267. return NULL;
  1268. }
  1269. memset(comp_ctx, 0, sizeof(AOTCompContext));
  1270. comp_ctx->comp_data = comp_data;
  1271. /* Create LLVM context, module and builder */
  1272. #if WASM_ENABLE_LAZY_JIT != 0
  1273. comp_ctx->ts_context = LLVMOrcCreateNewThreadSafeContext();
  1274. if (!comp_ctx->ts_context) {
  1275. aot_set_last_error("create LLVM ThreadSafeContext failed.");
  1276. return NULL;
  1277. }
  1278. /* Get a reference to the underlying LLVMContext */
  1279. if (!(comp_ctx->context =
  1280. LLVMOrcThreadSafeContextGetContext(comp_ctx->ts_context))) {
  1281. aot_set_last_error("get context from LLVM ThreadSafeContext failed.");
  1282. goto fail;
  1283. }
  1284. #else
  1285. if (!(comp_ctx->context = LLVMContextCreate())) {
  1286. aot_set_last_error("create LLVM context failed.");
  1287. goto fail;
  1288. }
  1289. #endif
  1290. if (!(comp_ctx->builder = LLVMCreateBuilderInContext(comp_ctx->context))) {
  1291. aot_set_last_error("create LLVM builder failed.");
  1292. goto fail;
  1293. }
  1294. if (!(comp_ctx->module =
  1295. LLVMModuleCreateWithNameInContext("WASM Module", comp_ctx->context))) {
  1296. aot_set_last_error("create LLVM module failed.");
  1297. goto fail;
  1298. }
  1299. if (BH_LIST_ERROR == bh_list_init(&comp_ctx->native_symbols)) {
  1300. goto fail;
  1301. }
  1302. if (option->enable_bulk_memory)
  1303. comp_ctx->enable_bulk_memory = true;
  1304. if (option->enable_thread_mgr)
  1305. comp_ctx->enable_thread_mgr = true;
  1306. if (option->enable_tail_call)
  1307. comp_ctx->enable_tail_call = true;
  1308. if (option->enable_ref_types)
  1309. comp_ctx->enable_ref_types = true;
  1310. if (option->enable_aux_stack_frame)
  1311. comp_ctx->enable_aux_stack_frame = true;
  1312. if (option->enable_aux_stack_check)
  1313. comp_ctx->enable_aux_stack_check = true;
  1314. if (option->is_indirect_mode)
  1315. comp_ctx->is_indirect_mode = true;
  1316. if (option->disable_llvm_intrinsics)
  1317. comp_ctx->disable_llvm_intrinsics = true;
  1318. if (option->is_jit_mode) {
  1319. char *triple_jit = NULL;
  1320. #if WASM_ENABLE_LAZY_JIT != 0
  1321. /* Create LLLazyJIT Instance */
  1322. if (!llvm_orcjit_create(comp_ctx)) {
  1323. aot_set_last_error("create LLVM Lazy JIT Compiler failed.");
  1324. goto fail;
  1325. }
  1326. #else
  1327. /* Create LLVM execution engine */
  1328. LLVMInitializeMCJITCompilerOptions(&jit_options, sizeof(jit_options));
  1329. jit_options.OptLevel = LLVMCodeGenLevelAggressive;
  1330. jit_options.EnableFastISel = true;
  1331. /*jit_options.CodeModel = LLVMCodeModelSmall;*/
  1332. if (WAMRCreateMCJITCompilerForModule
  1333. (&comp_ctx->exec_engine, comp_ctx->module,
  1334. &jit_options, sizeof(jit_options), &err) != 0) {
  1335. if (err) {
  1336. LLVMDisposeMessage(err);
  1337. err = NULL;
  1338. }
  1339. aot_set_last_error("create LLVM JIT compiler failed.");
  1340. goto fail;
  1341. }
  1342. comp_ctx->target_machine =
  1343. LLVMGetExecutionEngineTargetMachine(comp_ctx->exec_engine);
  1344. #endif
  1345. comp_ctx->is_jit_mode = true;
  1346. #ifndef OS_ENABLE_HW_BOUND_CHECK
  1347. comp_ctx->enable_bound_check = true;
  1348. #else
  1349. comp_ctx->enable_bound_check = false;
  1350. #endif
  1351. #if WASM_ENABLE_LAZY_JIT != 0
  1352. if (!(triple_jit =
  1353. (char *)LLVMOrcLLLazyJITGetTripleString(comp_ctx->lazy_orcjit))) {
  1354. aot_set_last_error("can not get triple from the target machine");
  1355. goto fail;
  1356. }
  1357. /* Save target arch */
  1358. get_target_arch_from_triple(triple_jit, comp_ctx->target_arch,
  1359. sizeof(comp_ctx->target_arch));
  1360. #else
  1361. if (!(triple_jit =
  1362. LLVMGetTargetMachineTriple(comp_ctx->target_machine))) {
  1363. aot_set_last_error("can not get triple from the target machine");
  1364. goto fail;
  1365. }
  1366. /* Save target arch */
  1367. get_target_arch_from_triple(triple_jit, comp_ctx->target_arch,
  1368. sizeof(comp_ctx->target_arch));
  1369. LLVMDisposeMessage(triple_jit);
  1370. #endif
  1371. }
  1372. else {
  1373. /* Create LLVM target machine */
  1374. arch = option->target_arch;
  1375. abi = option->target_abi;
  1376. cpu = option->target_cpu;
  1377. features = option->cpu_features;
  1378. opt_level = option->opt_level;
  1379. size_level = option->size_level;
  1380. if (arch) {
  1381. /* Add default sub-arch if not specified */
  1382. if (!strcmp(arch, "arm"))
  1383. arch = "armv4";
  1384. else if (!strcmp(arch, "armeb"))
  1385. arch = "armv4eb";
  1386. else if (!strcmp(arch, "thumb"))
  1387. arch = "thumbv4t";
  1388. else if (!strcmp(arch, "thumbeb"))
  1389. arch = "thumbv4teb";
  1390. else if (!strcmp(arch, "aarch64"))
  1391. arch = "aarch64v8";
  1392. else if (!strcmp(arch, "aarch64_be"))
  1393. arch = "aarch64_bev8";
  1394. }
  1395. /* Check target arch */
  1396. if (arch && !check_target_arch(arch)) {
  1397. if (!strcmp(arch, "help"))
  1398. print_supported_targets();
  1399. else
  1400. aot_set_last_error("Invalid target. "
  1401. "Use --target=help to list all supported targets");
  1402. goto fail;
  1403. }
  1404. /* Check target ABI */
  1405. if (abi && !check_target_abi(abi)) {
  1406. if (!strcmp(abi, "help"))
  1407. print_supported_abis();
  1408. else
  1409. aot_set_last_error("Invalid target ABI. "
  1410. "Use --target-abi=help to list all supported ABI");
  1411. goto fail;
  1412. }
  1413. /* Set default abi for riscv target */
  1414. if (arch && !strncmp(arch, "riscv", 5) && !abi) {
  1415. if (!strcmp(arch, "riscv64"))
  1416. abi = "lp64d";
  1417. else
  1418. abi = "ilp32d";
  1419. }
  1420. if (arch) {
  1421. /* Construct target triple: <arch>-<vendor>-<sys>-<abi> */
  1422. const char *vendor_sys;
  1423. char *default_triple = LLVMGetDefaultTargetTriple();
  1424. if (!default_triple) {
  1425. aot_set_last_error("llvm get default target triple failed.");
  1426. goto fail;
  1427. }
  1428. if (strstr(default_triple, "windows")) {
  1429. vendor_sys = "-pc-windows-";
  1430. if (!abi)
  1431. abi = "msvc";
  1432. }
  1433. else if (strstr(default_triple, "win32")) {
  1434. vendor_sys = "-pc-win32-";
  1435. if (!abi)
  1436. abi = "msvc";
  1437. }
  1438. else {
  1439. vendor_sys = "-pc-linux-";
  1440. if (!abi)
  1441. abi = "gnu";
  1442. }
  1443. LLVMDisposeMessage(default_triple);
  1444. bh_assert(strlen(arch) + strlen(vendor_sys) + strlen(abi) < sizeof(triple_buf));
  1445. memcpy(triple_buf, arch, strlen(arch));
  1446. memcpy(triple_buf + strlen(arch), vendor_sys, strlen(vendor_sys));
  1447. memcpy(triple_buf + strlen(arch) + strlen(vendor_sys), abi, strlen(abi));
  1448. triple = triple_buf;
  1449. }
  1450. if (!cpu && features) {
  1451. aot_set_last_error("cpu isn't specified for cpu features.");
  1452. goto fail;
  1453. }
  1454. if (!triple && !cpu) {
  1455. /* Get a triple for the host machine */
  1456. if (!(triple_norm = triple_norm_new = LLVMGetDefaultTargetTriple())) {
  1457. aot_set_last_error("llvm get default target triple failed.");
  1458. goto fail;
  1459. }
  1460. /* Get CPU name of the host machine */
  1461. if (!(cpu = cpu_new = LLVMGetHostCPUName())) {
  1462. aot_set_last_error("llvm get host cpu name failed.");
  1463. goto fail;
  1464. }
  1465. }
  1466. else if (triple) {
  1467. /* Normalize a target triple */
  1468. if (!(triple_norm = triple_norm_new = LLVMNormalizeTargetTriple(triple))) {
  1469. snprintf(buf, sizeof(buf),
  1470. "llvm normlalize target triple (%s) failed.", triple);
  1471. aot_set_last_error(buf);
  1472. goto fail;
  1473. }
  1474. if (!cpu)
  1475. cpu = "";
  1476. }
  1477. else {
  1478. /* triple is NULL, cpu isn't NULL */
  1479. snprintf(buf, sizeof(buf),
  1480. "target isn't specified for cpu %s.", cpu);
  1481. aot_set_last_error(buf);
  1482. goto fail;
  1483. }
  1484. /* Add module flag and cpu feature for riscv target */
  1485. if (arch && !strncmp(arch, "riscv", 5)) {
  1486. LLVMMetadataRef meta_target_abi;
  1487. if (!(meta_target_abi = LLVMMDStringInContext2(comp_ctx->context,
  1488. abi, strlen(abi)))) {
  1489. aot_set_last_error("create metadata string failed.");
  1490. goto fail;
  1491. }
  1492. LLVMAddModuleFlag(comp_ctx->module, LLVMModuleFlagBehaviorError,
  1493. "target-abi", strlen("target-abi"), meta_target_abi);
  1494. if (!strcmp(abi, "lp64d") || !strcmp(abi, "ilp32d")) {
  1495. if (features) {
  1496. snprintf(features_buf, sizeof(features_buf),
  1497. "%s%s", features, ",+d");
  1498. features = features_buf;
  1499. }
  1500. else
  1501. features = "+d";
  1502. }
  1503. }
  1504. if (!features)
  1505. features = "";
  1506. /* Get target with triple, note that LLVMGetTargetFromTriple()
  1507. return 0 when success, but not true. */
  1508. if (LLVMGetTargetFromTriple(triple_norm, &target, &err) != 0) {
  1509. if (err) {
  1510. LLVMDisposeMessage(err);
  1511. err = NULL;
  1512. }
  1513. snprintf(buf, sizeof(buf),
  1514. "llvm get target from triple (%s) failed", triple_norm);
  1515. aot_set_last_error(buf);
  1516. goto fail;
  1517. }
  1518. /* Save target arch */
  1519. get_target_arch_from_triple(triple_norm, comp_ctx->target_arch,
  1520. sizeof(comp_ctx->target_arch));
  1521. if (option->bounds_checks == 1 || option->bounds_checks == 0) {
  1522. /* Set by user */
  1523. comp_ctx->enable_bound_check =
  1524. (option->bounds_checks == 1) ? true : false;
  1525. }
  1526. else {
  1527. /* Unset by user, use default value */
  1528. if (strstr(comp_ctx->target_arch, "64") && !option->is_sgx_platform) {
  1529. comp_ctx->enable_bound_check = false;
  1530. }
  1531. else {
  1532. comp_ctx->enable_bound_check = true;
  1533. }
  1534. }
  1535. os_printf("Create AoT compiler with:\n");
  1536. os_printf(" target: %s\n", comp_ctx->target_arch);
  1537. os_printf(" target cpu: %s\n", cpu);
  1538. os_printf(" cpu features: %s\n", features);
  1539. os_printf(" opt level: %d\n", opt_level);
  1540. os_printf(" size level: %d\n", size_level);
  1541. switch (option->output_format) {
  1542. case AOT_LLVMIR_UNOPT_FILE:
  1543. os_printf(" output format: unoptimized LLVM IR\n");
  1544. break;
  1545. case AOT_LLVMIR_OPT_FILE:
  1546. os_printf(" output format: optimized LLVM IR\n");
  1547. break;
  1548. case AOT_FORMAT_FILE:
  1549. os_printf(" output format: AoT file\n");
  1550. break;
  1551. case AOT_OBJECT_FILE:
  1552. os_printf(" output format: native object file\n");
  1553. break;
  1554. }
  1555. if (!LLVMTargetHasTargetMachine(target)) {
  1556. snprintf(buf, sizeof(buf),
  1557. "no target machine for this target (%s).", triple_norm);
  1558. aot_set_last_error(buf);
  1559. goto fail;
  1560. }
  1561. /* Report error if target isn't arc and hasn't asm backend.
  1562. For arc target, as it cannot emit to memory buffer of elf file currently,
  1563. we let it emit to assembly file instead, and then call arc-gcc to compile
  1564. asm file to elf file, and read elf file to memory buffer. */
  1565. if (strncmp(comp_ctx->target_arch, "arc", 3)
  1566. && !LLVMTargetHasAsmBackend(target)) {
  1567. snprintf(buf, sizeof(buf),
  1568. "no asm backend for this target (%s).", LLVMGetTargetName(target));
  1569. aot_set_last_error(buf);
  1570. goto fail;
  1571. }
  1572. /* Set code model */
  1573. if (size_level == 0)
  1574. code_model = LLVMCodeModelLarge;
  1575. else if (size_level == 1)
  1576. code_model = LLVMCodeModelMedium;
  1577. else if (size_level == 2)
  1578. code_model = LLVMCodeModelKernel;
  1579. else
  1580. code_model = LLVMCodeModelSmall;
  1581. /* Create the target machine */
  1582. if (!(comp_ctx->target_machine =
  1583. LLVMCreateTargetMachine(target, triple_norm, cpu, features,
  1584. opt_level, LLVMRelocStatic,
  1585. code_model))) {
  1586. aot_set_last_error("create LLVM target machine failed.");
  1587. goto fail;
  1588. }
  1589. }
  1590. if (option->enable_simd
  1591. && strcmp(comp_ctx->target_arch, "x86_64") != 0
  1592. && strncmp(comp_ctx->target_arch, "aarch64", 7) != 0) {
  1593. /* Disable simd if it isn't supported by target arch */
  1594. option->enable_simd = false;
  1595. }
  1596. if (option->enable_simd) {
  1597. char *tmp;
  1598. bool ret;
  1599. comp_ctx->enable_simd = true;
  1600. if (!(tmp = LLVMGetTargetMachineCPU(comp_ctx->target_machine))) {
  1601. aot_set_last_error("get CPU from Target Machine fail");
  1602. goto fail;
  1603. }
  1604. ret = aot_check_simd_compatibility(comp_ctx->target_arch, tmp);
  1605. LLVMDisposeMessage(tmp);
  1606. if (!ret) {
  1607. aot_set_last_error("SIMD compatibility check failed, "
  1608. "try adding --cpu=<cpu> to specify a cpu "
  1609. "or adding --disable-simd to disable SIMD");
  1610. goto fail;
  1611. }
  1612. }
  1613. if (!(target_data_ref =
  1614. LLVMCreateTargetDataLayout(comp_ctx->target_machine))) {
  1615. aot_set_last_error("create LLVM target data layout failed.");
  1616. goto fail;
  1617. }
  1618. comp_ctx->pointer_size = LLVMPointerSize(target_data_ref);
  1619. LLVMDisposeTargetData(target_data_ref);
  1620. comp_ctx->optimize = true;
  1621. if (option->output_format == AOT_LLVMIR_UNOPT_FILE)
  1622. comp_ctx->optimize = false;
  1623. if (!(comp_ctx->pass_mgr = LLVMCreateFunctionPassManagerForModule
  1624. (comp_ctx->module))) {
  1625. aot_set_last_error("create LLVM pass manager failed.");
  1626. goto fail;
  1627. }
  1628. LLVMAddPromoteMemoryToRegisterPass(comp_ctx->pass_mgr);
  1629. LLVMAddInstructionCombiningPass(comp_ctx->pass_mgr);
  1630. LLVMAddCFGSimplificationPass(comp_ctx->pass_mgr);
  1631. LLVMAddJumpThreadingPass(comp_ctx->pass_mgr);
  1632. #if LLVM_VERSION_MAJOR < 12
  1633. LLVMAddConstantPropagationPass(comp_ctx->pass_mgr);
  1634. #endif
  1635. LLVMAddIndVarSimplifyPass(comp_ctx->pass_mgr);
  1636. if (!option->is_jit_mode) {
  1637. LLVMAddLoopRotatePass(comp_ctx->pass_mgr);
  1638. LLVMAddLoopUnswitchPass(comp_ctx->pass_mgr);
  1639. LLVMAddInstructionCombiningPass(comp_ctx->pass_mgr);
  1640. LLVMAddCFGSimplificationPass(comp_ctx->pass_mgr);
  1641. if (!option->enable_thread_mgr) {
  1642. /* These two passes may destroy the volatile semantics,
  1643. disable them when building as multi-thread mode */
  1644. LLVMAddGVNPass(comp_ctx->pass_mgr);
  1645. LLVMAddLICMPass(comp_ctx->pass_mgr);
  1646. }
  1647. LLVMAddLoopVectorizePass(comp_ctx->pass_mgr);
  1648. LLVMAddSLPVectorizePass(comp_ctx->pass_mgr);
  1649. LLVMAddInstructionCombiningPass(comp_ctx->pass_mgr);
  1650. LLVMAddCFGSimplificationPass(comp_ctx->pass_mgr);
  1651. }
  1652. /* Create metadata for llvm float experimental constrained intrinsics */
  1653. if (!(comp_ctx->fp_rounding_mode =
  1654. LLVMMDStringInContext(comp_ctx->context,
  1655. fp_round,
  1656. (uint32)strlen(fp_round)))
  1657. || !(comp_ctx->fp_exception_behavior =
  1658. LLVMMDStringInContext(comp_ctx->context,
  1659. fp_exce,
  1660. (uint32)strlen(fp_exce)))) {
  1661. aot_set_last_error("create float llvm metadata failed.");
  1662. goto fail;
  1663. }
  1664. if (!aot_set_llvm_basic_types(&comp_ctx->basic_types, comp_ctx->context)) {
  1665. aot_set_last_error("create LLVM basic types failed.");
  1666. goto fail;
  1667. }
  1668. if (!aot_create_llvm_consts(&comp_ctx->llvm_consts, comp_ctx)) {
  1669. aot_set_last_error("create LLVM const values failed.");
  1670. goto fail;
  1671. }
  1672. /* set exec_env data type to int8** */
  1673. comp_ctx->exec_env_type = comp_ctx->basic_types.int8_pptr_type;
  1674. /* set aot_inst data type to int8* */
  1675. comp_ctx->aot_inst_type = INT8_PTR_TYPE;
  1676. /* Create function context for each function */
  1677. comp_ctx->func_ctx_count = comp_data->func_count;
  1678. if (comp_data->func_count > 0
  1679. && !(comp_ctx->func_ctxes =
  1680. aot_create_func_contexts(comp_data, comp_ctx)))
  1681. goto fail;
  1682. if (cpu) {
  1683. uint32 len = (uint32)strlen(cpu) + 1;
  1684. if (!(comp_ctx->target_cpu = wasm_runtime_malloc(len))) {
  1685. aot_set_last_error("allocate memory failed");
  1686. goto fail;
  1687. }
  1688. bh_memcpy_s(comp_ctx->target_cpu, len, cpu, len);
  1689. }
  1690. if (comp_ctx->disable_llvm_intrinsics)
  1691. aot_intrinsic_fill_capability_flags(comp_ctx);
  1692. ret = comp_ctx;
  1693. fail:
  1694. if (triple_norm_new)
  1695. LLVMDisposeMessage(triple_norm_new);
  1696. if (cpu_new)
  1697. LLVMDisposeMessage(cpu_new);
  1698. if (!ret)
  1699. aot_destroy_comp_context(comp_ctx);
  1700. return ret;
  1701. }
  1702. void
  1703. aot_destroy_comp_context(AOTCompContext *comp_ctx)
  1704. {
  1705. if (!comp_ctx)
  1706. return;
  1707. if (comp_ctx->pass_mgr) {
  1708. LLVMFinalizeFunctionPassManager(comp_ctx->pass_mgr);
  1709. LLVMDisposePassManager(comp_ctx->pass_mgr);
  1710. }
  1711. #if WASM_ENABLE_LAZY_JIT != 0
  1712. if (comp_ctx->target_machine && comp_ctx->is_jit_mode)
  1713. LLVMDisposeTargetMachine(comp_ctx->target_machine);
  1714. if (comp_ctx->builder)
  1715. LLVMDisposeBuilder(comp_ctx->builder);
  1716. if (comp_ctx->lazy_orcjit)
  1717. LLVMOrcDisposeLLLazyJIT(comp_ctx->lazy_orcjit);
  1718. if (comp_ctx->ts_context)
  1719. LLVMOrcDisposeThreadSafeContext(comp_ctx->ts_context);
  1720. if (comp_ctx->tm_builder)
  1721. LLVMOrcDisposeJITTargetMachineBuilder(comp_ctx->tm_builder);
  1722. LLVMShutdown();
  1723. #else
  1724. if (comp_ctx->target_machine && !comp_ctx->is_jit_mode)
  1725. LLVMDisposeTargetMachine(comp_ctx->target_machine);
  1726. if (comp_ctx->builder)
  1727. LLVMDisposeBuilder(comp_ctx->builder);
  1728. if (comp_ctx->exec_engine) {
  1729. LLVMDisposeExecutionEngine(comp_ctx->exec_engine);
  1730. /* The LLVM module is freed when disposing execution engine,
  1731. no need to dispose it again. */
  1732. }
  1733. else if (comp_ctx->module)
  1734. LLVMDisposeModule(comp_ctx->module);
  1735. if (comp_ctx->context)
  1736. LLVMContextDispose(comp_ctx->context);
  1737. #endif
  1738. if (comp_ctx->func_ctxes)
  1739. aot_destroy_func_contexts(comp_ctx->func_ctxes,
  1740. comp_ctx->func_ctx_count);
  1741. if (bh_list_length(&comp_ctx->native_symbols) > 0) {
  1742. AOTNativeSymbol *sym = bh_list_first_elem(&comp_ctx->native_symbols);
  1743. while (sym) {
  1744. AOTNativeSymbol *t = bh_list_elem_next(sym);
  1745. bh_list_remove(&comp_ctx->native_symbols, sym);
  1746. wasm_runtime_free(sym);
  1747. sym = t;
  1748. }
  1749. }
  1750. if (comp_ctx->target_cpu) {
  1751. wasm_runtime_free(comp_ctx->target_cpu);
  1752. }
  1753. wasm_runtime_free(comp_ctx);
  1754. }
  1755. int32
  1756. aot_get_native_symbol_index(AOTCompContext *comp_ctx, const char *symbol)
  1757. {
  1758. int32 idx = -1;
  1759. AOTNativeSymbol *sym = NULL;
  1760. sym = bh_list_first_elem(&comp_ctx->native_symbols);
  1761. /* Lookup an existing symobl record */
  1762. while (sym) {
  1763. if (strcmp(sym->symbol, symbol) == 0) {
  1764. idx = sym->index;
  1765. break;
  1766. }
  1767. sym = bh_list_elem_next(sym);
  1768. }
  1769. /* Given symbol is not exist in list, then we alloc a new index for it */
  1770. if (idx < 0) {
  1771. sym = wasm_runtime_malloc(sizeof(AOTNativeSymbol));
  1772. if (!sym) {
  1773. aot_set_last_error("alloc native symbol failed.");
  1774. return idx;
  1775. }
  1776. idx = bh_list_length(&comp_ctx->native_symbols);
  1777. sym->symbol = symbol;
  1778. sym->index = idx;
  1779. if (BH_LIST_ERROR == bh_list_insert(&comp_ctx->native_symbols, sym)) {
  1780. wasm_runtime_free(sym);
  1781. aot_set_last_error("alloc index for native symbol failed.");
  1782. return -1;
  1783. }
  1784. }
  1785. return idx;
  1786. }
  1787. void
  1788. aot_value_stack_push(AOTValueStack *stack, AOTValue *value)
  1789. {
  1790. if (!stack->value_list_head)
  1791. stack->value_list_head = stack->value_list_end = value;
  1792. else {
  1793. stack->value_list_end->next = value;
  1794. value->prev = stack->value_list_end;
  1795. stack->value_list_end = value;
  1796. }
  1797. }
  1798. AOTValue *
  1799. aot_value_stack_pop(AOTValueStack *stack)
  1800. {
  1801. AOTValue *value = stack->value_list_end;
  1802. bh_assert(stack->value_list_end);
  1803. if (stack->value_list_head == stack->value_list_end)
  1804. stack->value_list_head = stack->value_list_end = NULL;
  1805. else {
  1806. stack->value_list_end = stack->value_list_end->prev;
  1807. stack->value_list_end->next = NULL;
  1808. value->prev = NULL;
  1809. }
  1810. return value;
  1811. }
  1812. void
  1813. aot_value_stack_destroy(AOTValueStack *stack)
  1814. {
  1815. AOTValue *value = stack->value_list_head, *p;
  1816. while (value) {
  1817. p = value->next;
  1818. wasm_runtime_free(value);
  1819. value = p;
  1820. }
  1821. }
  1822. void
  1823. aot_block_stack_push(AOTBlockStack *stack, AOTBlock *block)
  1824. {
  1825. if (!stack->block_list_head)
  1826. stack->block_list_head = stack->block_list_end = block;
  1827. else {
  1828. stack->block_list_end->next = block;
  1829. block->prev = stack->block_list_end;
  1830. stack->block_list_end = block;
  1831. }
  1832. }
  1833. AOTBlock *
  1834. aot_block_stack_pop(AOTBlockStack *stack)
  1835. {
  1836. AOTBlock *block = stack->block_list_end;
  1837. bh_assert(stack->block_list_end);
  1838. if (stack->block_list_head == stack->block_list_end)
  1839. stack->block_list_head = stack->block_list_end = NULL;
  1840. else {
  1841. stack->block_list_end = stack->block_list_end->prev;
  1842. stack->block_list_end->next = NULL;
  1843. block->prev = NULL;
  1844. }
  1845. return block;
  1846. }
  1847. void
  1848. aot_block_stack_destroy(AOTBlockStack *stack)
  1849. {
  1850. AOTBlock *block = stack->block_list_head, *p;
  1851. while (block) {
  1852. p = block->next;
  1853. aot_value_stack_destroy(&block->value_stack);
  1854. wasm_runtime_free(block);
  1855. block = p;
  1856. }
  1857. }
  1858. void
  1859. aot_block_destroy(AOTBlock *block)
  1860. {
  1861. aot_value_stack_destroy(&block->value_stack);
  1862. if (block->param_types)
  1863. wasm_runtime_free(block->param_types);
  1864. if (block->param_phis)
  1865. wasm_runtime_free(block->param_phis);
  1866. if (block->else_param_phis)
  1867. wasm_runtime_free(block->else_param_phis);
  1868. if (block->result_types)
  1869. wasm_runtime_free(block->result_types);
  1870. if (block->result_phis)
  1871. wasm_runtime_free(block->result_phis);
  1872. wasm_runtime_free(block);
  1873. }
  1874. bool
  1875. aot_checked_addr_list_add(AOTFuncContext *func_ctx,
  1876. uint32 local_idx, uint32 offset, uint32 bytes)
  1877. {
  1878. AOTCheckedAddr *node = func_ctx->checked_addr_list;
  1879. if (!(node = wasm_runtime_malloc(sizeof(AOTCheckedAddr)))) {
  1880. aot_set_last_error("allocate memory failed.");
  1881. return false;
  1882. }
  1883. node->local_idx = local_idx;
  1884. node->offset = offset;
  1885. node->bytes = bytes;
  1886. node->next = func_ctx->checked_addr_list;
  1887. func_ctx->checked_addr_list = node;
  1888. return true;
  1889. }
  1890. void
  1891. aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx)
  1892. {
  1893. AOTCheckedAddr *node = func_ctx->checked_addr_list;
  1894. AOTCheckedAddr *node_prev = NULL, *node_next;
  1895. while (node) {
  1896. node_next = node->next;
  1897. if (node->local_idx == local_idx) {
  1898. if (!node_prev)
  1899. func_ctx->checked_addr_list = node_next;
  1900. else
  1901. node_prev->next = node_next;
  1902. wasm_runtime_free(node);
  1903. }
  1904. else {
  1905. node_prev = node;
  1906. }
  1907. node = node_next;
  1908. }
  1909. }
  1910. bool
  1911. aot_checked_addr_list_find(AOTFuncContext *func_ctx,
  1912. uint32 local_idx, uint32 offset, uint32 bytes)
  1913. {
  1914. AOTCheckedAddr *node = func_ctx->checked_addr_list;
  1915. while (node) {
  1916. if (node->local_idx == local_idx
  1917. && node->offset == offset
  1918. && node->bytes >= bytes) {
  1919. return true;
  1920. }
  1921. node = node->next;
  1922. }
  1923. return false;
  1924. }
  1925. void
  1926. aot_checked_addr_list_destroy(AOTFuncContext *func_ctx)
  1927. {
  1928. AOTCheckedAddr *node = func_ctx->checked_addr_list, *node_next;
  1929. while (node) {
  1930. node_next = node->next;
  1931. wasm_runtime_free(node);
  1932. node = node_next;
  1933. }
  1934. func_ctx->checked_addr_list = NULL;
  1935. }
  1936. bool
  1937. aot_build_zero_function_ret(AOTCompContext *comp_ctx,
  1938. AOTFuncType *func_type)
  1939. {
  1940. LLVMValueRef ret = NULL;
  1941. if (func_type->result_count) {
  1942. switch (func_type->types[func_type->param_count]) {
  1943. case VALUE_TYPE_I32:
  1944. ret = LLVMBuildRet(comp_ctx->builder, I32_ZERO);
  1945. break;
  1946. case VALUE_TYPE_I64:
  1947. ret = LLVMBuildRet(comp_ctx->builder, I64_ZERO);
  1948. break;
  1949. case VALUE_TYPE_F32:
  1950. ret = LLVMBuildRet(comp_ctx->builder, F32_ZERO);
  1951. break;
  1952. case VALUE_TYPE_F64:
  1953. ret = LLVMBuildRet(comp_ctx->builder, F64_ZERO);
  1954. break;
  1955. case VALUE_TYPE_V128:
  1956. ret = LLVMBuildRet(comp_ctx->builder, V128_ZERO);
  1957. break;
  1958. case VALUE_TYPE_FUNCREF:
  1959. case VALUE_TYPE_EXTERNREF:
  1960. ret = LLVMBuildRet(comp_ctx->builder, REF_NULL);
  1961. break;
  1962. default:
  1963. bh_assert(0);
  1964. }
  1965. }
  1966. else {
  1967. ret = LLVMBuildRetVoid(comp_ctx->builder);
  1968. }
  1969. if (!ret) {
  1970. aot_set_last_error("llvm build ret failed.");
  1971. return false;
  1972. }
  1973. return true;
  1974. }
  1975. static LLVMValueRef
  1976. __call_llvm_intrinsic(const AOTCompContext *comp_ctx,
  1977. const AOTFuncContext *func_ctx,
  1978. const char *name,
  1979. LLVMTypeRef ret_type,
  1980. LLVMTypeRef *param_types,
  1981. int param_count,
  1982. LLVMValueRef *param_values)
  1983. {
  1984. LLVMValueRef func, ret;
  1985. LLVMTypeRef func_type;
  1986. const char *symname;
  1987. int32 func_idx;
  1988. if (comp_ctx->disable_llvm_intrinsics
  1989. && aot_intrinsic_check_capability(comp_ctx, name)) {
  1990. if (func_ctx == NULL) {
  1991. aot_set_last_error_v("invalid func_ctx for intrinsic: %s", name);
  1992. return NULL;
  1993. }
  1994. if (!(func_type = LLVMFunctionType(ret_type, param_types,
  1995. (uint32)param_count, false))) {
  1996. aot_set_last_error("create LLVM intrinsic function type failed.");
  1997. return NULL;
  1998. }
  1999. if (!(func_type = LLVMPointerType(func_type, 0))) {
  2000. aot_set_last_error(
  2001. "create LLVM intrinsic function pointer type failed.");
  2002. return NULL;
  2003. }
  2004. if (!(symname = aot_intrinsic_get_symbol(name))) {
  2005. aot_set_last_error_v("runtime intrinsic not implemented: %s\n",
  2006. name);
  2007. return NULL;
  2008. }
  2009. func_idx =
  2010. aot_get_native_symbol_index((AOTCompContext *)comp_ctx, symname);
  2011. if (func_idx < 0) {
  2012. aot_set_last_error_v("get runtime intrinsc index failed: %s\n",
  2013. name);
  2014. return NULL;
  2015. }
  2016. if (!(func = aot_get_func_from_table(comp_ctx, func_ctx->native_symbol,
  2017. func_type, func_idx))) {
  2018. aot_set_last_error_v("get runtime intrinsc failed: %s\n", name);
  2019. return NULL;
  2020. }
  2021. }
  2022. else {
  2023. /* Declare llvm intrinsic function if necessary */
  2024. if (!(func = LLVMGetNamedFunction(comp_ctx->module, name))) {
  2025. if (!(func_type = LLVMFunctionType(ret_type, param_types,
  2026. (uint32)param_count, false))) {
  2027. aot_set_last_error("create LLVM intrinsic function type failed.");
  2028. return NULL;
  2029. }
  2030. if (!(func = LLVMAddFunction(comp_ctx->module, name, func_type))) {
  2031. aot_set_last_error("add LLVM intrinsic function failed.");
  2032. return NULL;
  2033. }
  2034. }
  2035. }
  2036. /* Call the LLVM intrinsic function */
  2037. if (!(ret = LLVMBuildCall(comp_ctx->builder, func, param_values,
  2038. (uint32)param_count, "call"))) {
  2039. aot_set_last_error("llvm build intrinsic call failed.");
  2040. return NULL;
  2041. }
  2042. return ret;
  2043. }
  2044. LLVMValueRef
  2045. aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx,
  2046. const AOTFuncContext *func_ctx,
  2047. const char *name,
  2048. LLVMTypeRef ret_type,
  2049. LLVMTypeRef *param_types,
  2050. int param_count,
  2051. ...)
  2052. {
  2053. LLVMValueRef *param_values, ret;
  2054. va_list argptr;
  2055. uint64 total_size;
  2056. int i = 0;
  2057. /* Create param values */
  2058. total_size = sizeof(LLVMValueRef) * (uint64)param_count;
  2059. if (total_size >= UINT32_MAX
  2060. || !(param_values = wasm_runtime_malloc((uint32)total_size))) {
  2061. aot_set_last_error("allocate memory for param values failed.");
  2062. return false;
  2063. }
  2064. /* Load each param value */
  2065. va_start(argptr, param_count);
  2066. while (i < param_count)
  2067. param_values[i++] = va_arg(argptr, LLVMValueRef);
  2068. va_end(argptr);
  2069. ret = __call_llvm_intrinsic(comp_ctx, func_ctx, name, ret_type, param_types,
  2070. param_count, param_values);
  2071. wasm_runtime_free(param_values);
  2072. return ret;
  2073. }
  2074. LLVMValueRef
  2075. aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx,
  2076. const AOTFuncContext *func_ctx,
  2077. const char *name,
  2078. LLVMTypeRef ret_type,
  2079. LLVMTypeRef *param_types,
  2080. int param_count,
  2081. va_list param_value_list)
  2082. {
  2083. LLVMValueRef *param_values, ret;
  2084. uint64 total_size;
  2085. int i = 0;
  2086. /* Create param values */
  2087. total_size = sizeof(LLVMValueRef) * (uint64)param_count;
  2088. if (total_size >= UINT32_MAX
  2089. || !(param_values = wasm_runtime_malloc((uint32)total_size))) {
  2090. aot_set_last_error("allocate memory for param values failed.");
  2091. return false;
  2092. }
  2093. /* Load each param value */
  2094. while (i < param_count)
  2095. param_values[i++] = va_arg(param_value_list, LLVMValueRef);
  2096. ret = __call_llvm_intrinsic(comp_ctx, func_ctx, name, ret_type, param_types,
  2097. param_count, param_values);
  2098. wasm_runtime_free(param_values);
  2099. return ret;
  2100. }
  2101. LLVMValueRef
  2102. aot_get_func_from_table(const AOTCompContext *comp_ctx, LLVMValueRef base,
  2103. LLVMTypeRef func_type, int32 index)
  2104. {
  2105. LLVMValueRef func;
  2106. LLVMValueRef func_addr;
  2107. if (!(func_addr = I32_CONST(index))) {
  2108. aot_set_last_error("construct function index failed.");
  2109. goto fail;
  2110. }
  2111. if (!(func_addr = LLVMBuildInBoundsGEP(comp_ctx->builder, base, &func_addr,
  2112. 1, "func_addr"))) {
  2113. aot_set_last_error("get function addr by index failed.");
  2114. goto fail;
  2115. }
  2116. func = LLVMBuildLoad(comp_ctx->builder, func_addr, "func_tmp");
  2117. if (func == NULL) {
  2118. aot_set_last_error("get function pointer failed.");
  2119. goto fail;
  2120. }
  2121. if (!(func = LLVMBuildBitCast(comp_ctx->builder, func, func_type,
  2122. "func"))) {
  2123. aot_set_last_error("cast function fialed.");
  2124. goto fail;
  2125. }
  2126. return func;
  2127. fail:
  2128. return NULL;
  2129. }