aot_llvm.c 89 KB

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