aot_emit_control.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_emit_control.h"
  6. #include "aot_compiler.h"
  7. #include "aot_emit_exception.h"
  8. #include "../aot/aot_runtime.h"
  9. #include "../interpreter/wasm_loader.h"
  10. #if WASM_ENABLE_DEBUG_AOT != 0
  11. #include "debug/dwarf_extractor.h"
  12. #endif
  13. static char *block_name_prefix[] = { "block", "loop", "if" };
  14. static char *block_name_suffix[] = { "begin", "else", "end" };
  15. /* clang-format off */
  16. enum {
  17. LABEL_BEGIN = 0,
  18. LABEL_ELSE,
  19. LABEL_END
  20. };
  21. /* clang-format on */
  22. static void
  23. format_block_name(char *name, uint32 name_size, uint32 block_index,
  24. uint32 label_type, uint32 label_id)
  25. {
  26. if (label_type != LABEL_TYPE_FUNCTION)
  27. snprintf(name, name_size, "%s%d%s%s", block_name_prefix[label_type],
  28. block_index, "_", block_name_suffix[label_id]);
  29. else
  30. snprintf(name, name_size, "%s", "func_end");
  31. }
  32. #define CREATE_BLOCK(new_llvm_block, name) \
  33. do { \
  34. if (!(new_llvm_block = LLVMAppendBasicBlockInContext( \
  35. comp_ctx->context, func_ctx->func, name))) { \
  36. aot_set_last_error("add LLVM basic block failed."); \
  37. goto fail; \
  38. } \
  39. } while (0)
  40. #define CURR_BLOCK() LLVMGetInsertBlock(comp_ctx->builder)
  41. #define MOVE_BLOCK_AFTER(llvm_block, llvm_block_after) \
  42. LLVMMoveBasicBlockAfter(llvm_block, llvm_block_after)
  43. #define MOVE_BLOCK_AFTER_CURR(llvm_block) \
  44. LLVMMoveBasicBlockAfter(llvm_block, CURR_BLOCK())
  45. #define MOVE_BLOCK_BEFORE(llvm_block, llvm_block_before) \
  46. LLVMMoveBasicBlockBefore(llvm_block, llvm_block_before)
  47. #define BUILD_BR(llvm_block) \
  48. do { \
  49. if (!LLVMBuildBr(comp_ctx->builder, llvm_block)) { \
  50. aot_set_last_error("llvm build br failed."); \
  51. goto fail; \
  52. } \
  53. } while (0)
  54. #define BUILD_COND_BR(value_if, block_then, block_else) \
  55. do { \
  56. if (!LLVMBuildCondBr(comp_ctx->builder, value_if, block_then, \
  57. block_else)) { \
  58. aot_set_last_error("llvm build cond br failed."); \
  59. goto fail; \
  60. } \
  61. } while (0)
  62. #define SET_BUILDER_POS(llvm_block) \
  63. LLVMPositionBuilderAtEnd(comp_ctx->builder, llvm_block)
  64. #define CREATE_RESULT_VALUE_PHIS(block) \
  65. do { \
  66. if (block->result_count && !block->result_phis) { \
  67. uint32 _i; \
  68. uint64 _size; \
  69. LLVMBasicBlockRef _block_curr = CURR_BLOCK(); \
  70. /* Allocate memory */ \
  71. _size = sizeof(LLVMValueRef) * (uint64)block->result_count; \
  72. if (_size >= UINT32_MAX \
  73. || !(block->result_phis = \
  74. wasm_runtime_malloc((uint32)_size))) { \
  75. aot_set_last_error("allocate memory failed."); \
  76. goto fail; \
  77. } \
  78. SET_BUILDER_POS(block->llvm_end_block); \
  79. for (_i = 0; _i < block->result_count; _i++) { \
  80. if (!(block->result_phis[_i] = LLVMBuildPhi( \
  81. comp_ctx->builder, \
  82. TO_LLVM_TYPE(block->result_types[_i]), "phi"))) { \
  83. aot_set_last_error("llvm build phi failed."); \
  84. goto fail; \
  85. } \
  86. } \
  87. SET_BUILDER_POS(_block_curr); \
  88. } \
  89. } while (0)
  90. #define ADD_TO_RESULT_PHIS(block, value, idx) \
  91. do { \
  92. LLVMBasicBlockRef _block_curr = CURR_BLOCK(); \
  93. LLVMTypeRef phi_ty = LLVMTypeOf(block->result_phis[idx]); \
  94. LLVMTypeRef value_ty = LLVMTypeOf(value); \
  95. bh_assert(LLVMGetTypeKind(phi_ty) == LLVMGetTypeKind(value_ty)); \
  96. bh_assert(LLVMGetTypeContext(phi_ty) == LLVMGetTypeContext(value_ty)); \
  97. LLVMAddIncoming(block->result_phis[idx], &value, &_block_curr, 1); \
  98. (void)phi_ty; \
  99. (void)value_ty; \
  100. } while (0)
  101. #define BUILD_ICMP(op, left, right, res, name) \
  102. do { \
  103. if (!(res = \
  104. LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \
  105. aot_set_last_error("llvm build icmp failed."); \
  106. goto fail; \
  107. } \
  108. } while (0)
  109. #define ADD_TO_PARAM_PHIS(block, value, idx) \
  110. do { \
  111. LLVMBasicBlockRef _block_curr = CURR_BLOCK(); \
  112. LLVMAddIncoming(block->param_phis[idx], &value, &_block_curr, 1); \
  113. } while (0)
  114. static LLVMBasicBlockRef
  115. find_next_llvm_end_block(AOTBlock *block)
  116. {
  117. block = block->prev;
  118. while (block && !block->llvm_end_block)
  119. block = block->prev;
  120. return block ? block->llvm_end_block : NULL;
  121. }
  122. static AOTBlock *
  123. get_target_block(AOTFuncContext *func_ctx, uint32 br_depth)
  124. {
  125. uint32 i = br_depth;
  126. AOTBlock *block = func_ctx->block_stack.block_list_end;
  127. while (i-- > 0 && block) {
  128. block = block->prev;
  129. }
  130. if (!block) {
  131. aot_set_last_error("WASM block stack underflow.");
  132. return NULL;
  133. }
  134. return block;
  135. }
  136. static bool
  137. handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  138. uint8 **p_frame_ip)
  139. {
  140. AOTBlock *block = func_ctx->block_stack.block_list_end;
  141. AOTBlock *block_prev;
  142. uint8 *frame_ip = NULL;
  143. uint32 i;
  144. AOTFuncType *func_type;
  145. LLVMValueRef ret;
  146. #if WASM_ENABLE_DEBUG_AOT != 0
  147. LLVMMetadataRef return_location;
  148. #endif
  149. aot_checked_addr_list_destroy(func_ctx);
  150. bh_assert(block);
  151. #if WASM_ENABLE_DEBUG_AOT != 0
  152. return_location = dwarf_gen_location(
  153. comp_ctx, func_ctx,
  154. (*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code);
  155. #endif
  156. if (block->label_type == LABEL_TYPE_IF && block->llvm_else_block
  157. && *p_frame_ip <= block->wasm_code_else) {
  158. /* Clear value stack and start to translate else branch */
  159. aot_value_stack_destroy(&block->value_stack);
  160. /* Recover parameters of else branch */
  161. for (i = 0; i < block->param_count; i++)
  162. PUSH(block->else_param_phis[i], block->param_types[i]);
  163. SET_BUILDER_POS(block->llvm_else_block);
  164. *p_frame_ip = block->wasm_code_else + 1;
  165. return true;
  166. }
  167. while (block && !block->is_reachable) {
  168. block_prev = block->prev;
  169. block = aot_block_stack_pop(&func_ctx->block_stack);
  170. if (block->label_type == LABEL_TYPE_IF) {
  171. if (block->llvm_else_block && !block->skip_wasm_code_else
  172. && *p_frame_ip <= block->wasm_code_else) {
  173. /* Clear value stack and start to translate else branch */
  174. aot_value_stack_destroy(&block->value_stack);
  175. SET_BUILDER_POS(block->llvm_else_block);
  176. *p_frame_ip = block->wasm_code_else + 1;
  177. /* Push back the block */
  178. aot_block_stack_push(&func_ctx->block_stack, block);
  179. /* Recover parameters of else branch */
  180. for (i = 0; i < block->param_count; i++)
  181. PUSH(block->else_param_phis[i], block->param_types[i]);
  182. return true;
  183. }
  184. else if (block->llvm_end_block) {
  185. /* Remove unreachable basic block */
  186. LLVMDeleteBasicBlock(block->llvm_end_block);
  187. block->llvm_end_block = NULL;
  188. }
  189. }
  190. frame_ip = block->wasm_code_end;
  191. aot_block_destroy(block);
  192. block = block_prev;
  193. }
  194. if (!block) {
  195. *p_frame_ip = frame_ip + 1;
  196. return true;
  197. }
  198. if (block->label_type == LABEL_TYPE_IF && block->llvm_else_block
  199. && !block->skip_wasm_code_else
  200. && *p_frame_ip <= block->wasm_code_else) {
  201. /* Clear value stack and start to translate else branch */
  202. aot_value_stack_destroy(&block->value_stack);
  203. /* Recover parameters of else branch */
  204. for (i = 0; i < block->param_count; i++)
  205. PUSH(block->else_param_phis[i], block->param_types[i]);
  206. SET_BUILDER_POS(block->llvm_else_block);
  207. *p_frame_ip = block->wasm_code_else + 1;
  208. return true;
  209. }
  210. *p_frame_ip = block->wasm_code_end + 1;
  211. SET_BUILDER_POS(block->llvm_end_block);
  212. /* Pop block, push its return value, and destroy the block */
  213. block = aot_block_stack_pop(&func_ctx->block_stack);
  214. func_type = func_ctx->aot_func->func_type;
  215. for (i = 0; i < block->result_count; i++) {
  216. bh_assert(block->result_phis[i]);
  217. if (block->label_type != LABEL_TYPE_FUNCTION) {
  218. PUSH(block->result_phis[i], block->result_types[i]);
  219. }
  220. else {
  221. /* Store extra return values to function parameters */
  222. if (i != 0) {
  223. LLVMValueRef res;
  224. uint32 param_index = func_type->param_count + i;
  225. if (!(res = LLVMBuildStore(
  226. comp_ctx->builder, block->result_phis[i],
  227. LLVMGetParam(func_ctx->func, param_index)))) {
  228. aot_set_last_error("llvm build store failed.");
  229. goto fail;
  230. }
  231. LLVMSetAlignment(res, 1);
  232. }
  233. }
  234. }
  235. if (block->label_type == LABEL_TYPE_FUNCTION) {
  236. if (block->result_count) {
  237. /* Return the first return value */
  238. if (!(ret =
  239. LLVMBuildRet(comp_ctx->builder, block->result_phis[0]))) {
  240. aot_set_last_error("llvm build return failed.");
  241. goto fail;
  242. }
  243. #if WASM_ENABLE_DEBUG_AOT != 0
  244. if (return_location != NULL) {
  245. LLVMInstructionSetDebugLoc(ret, return_location);
  246. }
  247. #endif
  248. }
  249. else {
  250. if (!(ret = LLVMBuildRetVoid(comp_ctx->builder))) {
  251. aot_set_last_error("llvm build return void failed.");
  252. goto fail;
  253. }
  254. #if WASM_ENABLE_DEBUG_AOT != 0
  255. if (return_location != NULL) {
  256. LLVMInstructionSetDebugLoc(ret, return_location);
  257. }
  258. #endif
  259. }
  260. }
  261. aot_block_destroy(block);
  262. return true;
  263. fail:
  264. return false;
  265. }
  266. static bool
  267. push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
  268. AOTFuncContext *func_ctx,
  269. AOTBlock *block)
  270. {
  271. uint32 i, param_index;
  272. LLVMValueRef value, br_inst;
  273. uint64 size;
  274. char name[32];
  275. LLVMBasicBlockRef block_curr = CURR_BLOCK();
  276. if (block->param_count) {
  277. size = sizeof(LLVMValueRef) * (uint64)block->param_count;
  278. if (size >= UINT32_MAX
  279. || !(block->param_phis = wasm_runtime_malloc((uint32)size))) {
  280. aot_set_last_error("allocate memory failed.");
  281. return false;
  282. }
  283. if (block->label_type == LABEL_TYPE_IF && !block->skip_wasm_code_else
  284. && !(block->else_param_phis = wasm_runtime_malloc((uint32)size))) {
  285. wasm_runtime_free(block->param_phis);
  286. block->param_phis = NULL;
  287. aot_set_last_error("allocate memory failed.");
  288. return false;
  289. }
  290. /* Create param phis */
  291. for (i = 0; i < block->param_count; i++) {
  292. SET_BUILDER_POS(block->llvm_entry_block);
  293. snprintf(name, sizeof(name), "%s%d_phi%d",
  294. block_name_prefix[block->label_type], block->block_index,
  295. i);
  296. if (!(block->param_phis[i] = LLVMBuildPhi(
  297. comp_ctx->builder, TO_LLVM_TYPE(block->param_types[i]),
  298. name))) {
  299. aot_set_last_error("llvm build phi failed.");
  300. goto fail;
  301. }
  302. if (block->label_type == LABEL_TYPE_IF
  303. && !block->skip_wasm_code_else && block->llvm_else_block) {
  304. /* Build else param phis */
  305. SET_BUILDER_POS(block->llvm_else_block);
  306. snprintf(name, sizeof(name), "else%d_phi%d", block->block_index,
  307. i);
  308. if (!(block->else_param_phis[i] = LLVMBuildPhi(
  309. comp_ctx->builder,
  310. TO_LLVM_TYPE(block->param_types[i]), name))) {
  311. aot_set_last_error("llvm build phi failed.");
  312. goto fail;
  313. }
  314. }
  315. }
  316. /* At this point, the branch instruction was already built to jump to
  317. * the new BB, to avoid generating zext instruction from the popped
  318. * operand that would come after branch instruction, we should position
  319. * the builder before the last branch instruction */
  320. br_inst = LLVMGetLastInstruction(block_curr);
  321. bh_assert(LLVMGetInstructionOpcode(br_inst) == LLVMBr);
  322. LLVMPositionBuilderBefore(comp_ctx->builder, br_inst);
  323. /* Pop param values from current block's
  324. * value stack and add to param phis.
  325. */
  326. for (i = 0; i < block->param_count; i++) {
  327. param_index = block->param_count - 1 - i;
  328. POP(value, block->param_types[param_index]);
  329. if (block->llvm_entry_block)
  330. /* Only add incoming phis if the entry block was created */
  331. ADD_TO_PARAM_PHIS(block, value, param_index);
  332. if (block->label_type == LABEL_TYPE_IF
  333. && !block->skip_wasm_code_else) {
  334. if (block->llvm_else_block) {
  335. /* has else branch, add to else param phis */
  336. LLVMAddIncoming(block->else_param_phis[param_index], &value,
  337. &block_curr, 1);
  338. }
  339. else {
  340. /* no else branch, add to result phis */
  341. CREATE_RESULT_VALUE_PHIS(block);
  342. ADD_TO_RESULT_PHIS(block, value, param_index);
  343. }
  344. }
  345. }
  346. }
  347. /* Push the new block to block stack */
  348. aot_block_stack_push(&func_ctx->block_stack, block);
  349. /* Push param phis to the new block */
  350. for (i = 0; i < block->param_count; i++) {
  351. if (block->llvm_entry_block)
  352. /* Push param phis if the entry basic block was created */
  353. PUSH(block->param_phis[i], block->param_types[i]);
  354. else {
  355. bh_assert(block->label_type == LABEL_TYPE_IF
  356. && block->llvm_else_block && block->else_param_phis
  357. && !block->skip_wasm_code_else);
  358. /* Push else param phis if we start to translate the
  359. else branch */
  360. PUSH(block->else_param_phis[i], block->param_types[i]);
  361. }
  362. }
  363. return true;
  364. fail:
  365. if (block->param_phis) {
  366. wasm_runtime_free(block->param_phis);
  367. block->param_phis = NULL;
  368. }
  369. if (block->else_param_phis) {
  370. wasm_runtime_free(block->else_param_phis);
  371. block->else_param_phis = NULL;
  372. }
  373. return false;
  374. }
  375. bool
  376. aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  377. uint8 **p_frame_ip, uint8 *frame_ip_end, uint32 label_type,
  378. uint32 param_count, uint8 *param_types,
  379. uint32 result_count, uint8 *result_types)
  380. {
  381. BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
  382. AOTBlock *block;
  383. uint8 *else_addr, *end_addr;
  384. LLVMValueRef value;
  385. char name[32];
  386. /* Check block stack */
  387. if (!func_ctx->block_stack.block_list_end) {
  388. aot_set_last_error("WASM block stack underflow.");
  389. return false;
  390. }
  391. memset(block_addr_cache, 0, sizeof(block_addr_cache));
  392. /* Get block info */
  393. if (!(wasm_loader_find_block_addr(
  394. NULL, (BlockAddr *)block_addr_cache, *p_frame_ip, frame_ip_end,
  395. (uint8)label_type, &else_addr, &end_addr))) {
  396. aot_set_last_error("find block end addr failed.");
  397. return false;
  398. }
  399. /* Allocate memory */
  400. if (!(block = wasm_runtime_malloc(sizeof(AOTBlock)))) {
  401. aot_set_last_error("allocate memory failed.");
  402. return false;
  403. }
  404. memset(block, 0, sizeof(AOTBlock));
  405. if (param_count
  406. && !(block->param_types = wasm_runtime_malloc(param_count))) {
  407. aot_set_last_error("allocate memory failed.");
  408. goto fail;
  409. }
  410. if (result_count) {
  411. if (!(block->result_types = wasm_runtime_malloc(result_count))) {
  412. aot_set_last_error("allocate memory failed.");
  413. goto fail;
  414. }
  415. }
  416. /* Init aot block data */
  417. block->label_type = label_type;
  418. block->param_count = param_count;
  419. if (param_count) {
  420. bh_memcpy_s(block->param_types, param_count, param_types, param_count);
  421. }
  422. block->result_count = result_count;
  423. if (result_count) {
  424. bh_memcpy_s(block->result_types, result_count, result_types,
  425. result_count);
  426. }
  427. block->wasm_code_else = else_addr;
  428. block->wasm_code_end = end_addr;
  429. block->block_index = func_ctx->block_stack.block_index[label_type];
  430. func_ctx->block_stack.block_index[label_type]++;
  431. if (label_type == LABEL_TYPE_BLOCK || label_type == LABEL_TYPE_LOOP) {
  432. /* Create block */
  433. format_block_name(name, sizeof(name), block->block_index, label_type,
  434. LABEL_BEGIN);
  435. CREATE_BLOCK(block->llvm_entry_block, name);
  436. MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
  437. /* Jump to the entry block */
  438. BUILD_BR(block->llvm_entry_block);
  439. if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx, block))
  440. goto fail;
  441. /* Start to translate the block */
  442. SET_BUILDER_POS(block->llvm_entry_block);
  443. if (label_type == LABEL_TYPE_LOOP)
  444. aot_checked_addr_list_destroy(func_ctx);
  445. }
  446. else if (label_type == LABEL_TYPE_IF) {
  447. POP_COND(value);
  448. if (LLVMIsUndef(value)
  449. #if LLVM_VERSION_NUMBER >= 12
  450. || LLVMIsPoison(value)
  451. #endif
  452. ) {
  453. if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INTEGER_OVERFLOW,
  454. false, NULL, NULL))) {
  455. goto fail;
  456. }
  457. aot_block_destroy(block);
  458. return aot_handle_next_reachable_block(comp_ctx, func_ctx,
  459. p_frame_ip);
  460. }
  461. if (!LLVMIsEfficientConstInt(value)) {
  462. /* Compare value is not constant, create condition br IR */
  463. /* Create entry block */
  464. format_block_name(name, sizeof(name), block->block_index,
  465. label_type, LABEL_BEGIN);
  466. CREATE_BLOCK(block->llvm_entry_block, name);
  467. MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
  468. /* Create end block */
  469. format_block_name(name, sizeof(name), block->block_index,
  470. label_type, LABEL_END);
  471. CREATE_BLOCK(block->llvm_end_block, name);
  472. MOVE_BLOCK_AFTER(block->llvm_end_block, block->llvm_entry_block);
  473. if (else_addr) {
  474. /* Create else block */
  475. format_block_name(name, sizeof(name), block->block_index,
  476. label_type, LABEL_ELSE);
  477. CREATE_BLOCK(block->llvm_else_block, name);
  478. MOVE_BLOCK_AFTER(block->llvm_else_block,
  479. block->llvm_entry_block);
  480. /* Create condition br IR */
  481. BUILD_COND_BR(value, block->llvm_entry_block,
  482. block->llvm_else_block);
  483. }
  484. else {
  485. /* Create condition br IR */
  486. BUILD_COND_BR(value, block->llvm_entry_block,
  487. block->llvm_end_block);
  488. block->is_reachable = true;
  489. }
  490. if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx,
  491. block))
  492. goto fail;
  493. /* Start to translate if branch of BLOCK if */
  494. SET_BUILDER_POS(block->llvm_entry_block);
  495. }
  496. else {
  497. if ((int32)LLVMConstIntGetZExtValue(value) != 0) {
  498. /* Compare value is not 0, condition is true, else branch of
  499. BLOCK if cannot be reached */
  500. block->skip_wasm_code_else = true;
  501. /* Create entry block */
  502. format_block_name(name, sizeof(name), block->block_index,
  503. label_type, LABEL_BEGIN);
  504. CREATE_BLOCK(block->llvm_entry_block, name);
  505. MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
  506. /* Jump to the entry block */
  507. BUILD_BR(block->llvm_entry_block);
  508. if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx,
  509. block))
  510. goto fail;
  511. /* Start to translate the if branch */
  512. SET_BUILDER_POS(block->llvm_entry_block);
  513. }
  514. else {
  515. /* Compare value is not 0, condition is false, if branch of
  516. BLOCK if cannot be reached */
  517. if (else_addr) {
  518. /* Create else block */
  519. format_block_name(name, sizeof(name), block->block_index,
  520. label_type, LABEL_ELSE);
  521. CREATE_BLOCK(block->llvm_else_block, name);
  522. MOVE_BLOCK_AFTER_CURR(block->llvm_else_block);
  523. /* Jump to the else block */
  524. BUILD_BR(block->llvm_else_block);
  525. if (!push_aot_block_to_stack_and_pass_params(
  526. comp_ctx, func_ctx, block))
  527. goto fail;
  528. /* Start to translate the else branch */
  529. SET_BUILDER_POS(block->llvm_else_block);
  530. *p_frame_ip = else_addr + 1;
  531. }
  532. else {
  533. /* skip the block */
  534. aot_block_destroy(block);
  535. *p_frame_ip = end_addr + 1;
  536. }
  537. }
  538. }
  539. }
  540. else {
  541. aot_set_last_error("Invalid block type.");
  542. goto fail;
  543. }
  544. return true;
  545. fail:
  546. aot_block_destroy(block);
  547. return false;
  548. }
  549. bool
  550. aot_compile_op_else(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  551. uint8 **p_frame_ip)
  552. {
  553. AOTBlock *block = func_ctx->block_stack.block_list_end;
  554. LLVMValueRef value;
  555. char name[32];
  556. uint32 i, result_index;
  557. /* Check block */
  558. if (!block) {
  559. aot_set_last_error("WASM block stack underflow.");
  560. return false;
  561. }
  562. if (block->label_type != LABEL_TYPE_IF
  563. || (!block->skip_wasm_code_else && !block->llvm_else_block)) {
  564. aot_set_last_error("Invalid WASM block type.");
  565. return false;
  566. }
  567. /* Create end block if needed */
  568. if (!block->llvm_end_block) {
  569. format_block_name(name, sizeof(name), block->block_index,
  570. block->label_type, LABEL_END);
  571. CREATE_BLOCK(block->llvm_end_block, name);
  572. if (block->llvm_else_block)
  573. MOVE_BLOCK_AFTER(block->llvm_end_block, block->llvm_else_block);
  574. else
  575. MOVE_BLOCK_AFTER_CURR(block->llvm_end_block);
  576. }
  577. block->is_reachable = true;
  578. /* Comes from the if branch of BLOCK if */
  579. CREATE_RESULT_VALUE_PHIS(block);
  580. for (i = 0; i < block->result_count; i++) {
  581. result_index = block->result_count - 1 - i;
  582. POP(value, block->result_types[result_index]);
  583. ADD_TO_RESULT_PHIS(block, value, result_index);
  584. }
  585. /* Jump to end block */
  586. BUILD_BR(block->llvm_end_block);
  587. if (!block->skip_wasm_code_else && block->llvm_else_block) {
  588. /* Clear value stack, recover param values
  589. * and start to translate else branch.
  590. */
  591. aot_value_stack_destroy(&block->value_stack);
  592. for (i = 0; i < block->param_count; i++)
  593. PUSH(block->else_param_phis[i], block->param_types[i]);
  594. SET_BUILDER_POS(block->llvm_else_block);
  595. aot_checked_addr_list_destroy(func_ctx);
  596. return true;
  597. }
  598. /* No else branch or no need to translate else branch */
  599. block->is_reachable = true;
  600. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  601. fail:
  602. return false;
  603. }
  604. bool
  605. aot_compile_op_end(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  606. uint8 **p_frame_ip)
  607. {
  608. AOTBlock *block;
  609. LLVMValueRef value;
  610. LLVMBasicBlockRef next_llvm_end_block;
  611. char name[32];
  612. uint32 i, result_index;
  613. /* Check block stack */
  614. if (!(block = func_ctx->block_stack.block_list_end)) {
  615. aot_set_last_error("WASM block stack underflow.");
  616. return false;
  617. }
  618. /* Create the end block */
  619. if (!block->llvm_end_block) {
  620. format_block_name(name, sizeof(name), block->block_index,
  621. block->label_type, LABEL_END);
  622. CREATE_BLOCK(block->llvm_end_block, name);
  623. if ((next_llvm_end_block = find_next_llvm_end_block(block)))
  624. MOVE_BLOCK_BEFORE(block->llvm_end_block, next_llvm_end_block);
  625. }
  626. /* Handle block result values */
  627. CREATE_RESULT_VALUE_PHIS(block);
  628. for (i = 0; i < block->result_count; i++) {
  629. value = NULL;
  630. result_index = block->result_count - 1 - i;
  631. POP(value, block->result_types[result_index]);
  632. bh_assert(value);
  633. ADD_TO_RESULT_PHIS(block, value, result_index);
  634. }
  635. /* Jump to the end block */
  636. BUILD_BR(block->llvm_end_block);
  637. block->is_reachable = true;
  638. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  639. fail:
  640. return false;
  641. }
  642. #if WASM_ENABLE_THREAD_MGR != 0
  643. bool
  644. check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
  645. {
  646. LLVMValueRef terminate_addr, terminate_flags, flag, offset, res;
  647. LLVMBasicBlockRef terminate_block, non_terminate_block;
  648. AOTFuncType *aot_func_type = func_ctx->aot_func->func_type;
  649. bool is_shared_memory =
  650. comp_ctx->comp_data->memories[0].memory_flags & 0x02 ? true : false;
  651. /* Only need to check the suspend flags when memory is shared since
  652. shared memory must be enabled for multi-threading */
  653. if (!is_shared_memory) {
  654. return true;
  655. }
  656. /* Offset of suspend_flags */
  657. offset = I32_FIVE;
  658. if (!(terminate_addr = LLVMBuildInBoundsGEP2(
  659. comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env, &offset, 1,
  660. "terminate_addr"))) {
  661. aot_set_last_error("llvm build in bounds gep failed");
  662. return false;
  663. }
  664. if (!(terminate_addr =
  665. LLVMBuildBitCast(comp_ctx->builder, terminate_addr,
  666. INT32_PTR_TYPE, "terminate_addr_ptr"))) {
  667. aot_set_last_error("llvm build bit cast failed");
  668. return false;
  669. }
  670. if (!(terminate_flags =
  671. LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, terminate_addr,
  672. "terminate_flags"))) {
  673. aot_set_last_error("llvm build LOAD failed");
  674. return false;
  675. }
  676. /* Set terminate_flags memory accecc to volatile, so that the value
  677. will always be loaded from memory rather than register */
  678. LLVMSetVolatile(terminate_flags, true);
  679. if (!(flag = LLVMBuildAnd(comp_ctx->builder, terminate_flags, I32_ONE,
  680. "termination_flag"))) {
  681. aot_set_last_error("llvm build AND failed");
  682. return false;
  683. }
  684. CREATE_BLOCK(non_terminate_block, "non_terminate");
  685. MOVE_BLOCK_AFTER_CURR(non_terminate_block);
  686. CREATE_BLOCK(terminate_block, "terminate");
  687. MOVE_BLOCK_AFTER_CURR(terminate_block);
  688. BUILD_ICMP(LLVMIntEQ, flag, I32_ZERO, res, "flag_terminate");
  689. BUILD_COND_BR(res, non_terminate_block, terminate_block);
  690. /* Move builder to terminate block */
  691. SET_BUILDER_POS(terminate_block);
  692. if (!aot_build_zero_function_ret(comp_ctx, func_ctx, aot_func_type)) {
  693. goto fail;
  694. }
  695. /* Move builder to non terminate block */
  696. SET_BUILDER_POS(non_terminate_block);
  697. return true;
  698. fail:
  699. return false;
  700. }
  701. #endif /* End of WASM_ENABLE_THREAD_MGR */
  702. bool
  703. aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  704. uint32 br_depth, uint8 **p_frame_ip)
  705. {
  706. AOTBlock *block_dst;
  707. LLVMValueRef value_ret, value_param;
  708. LLVMBasicBlockRef next_llvm_end_block;
  709. char name[32];
  710. uint32 i, param_index, result_index;
  711. #if WASM_ENABLE_THREAD_MGR != 0
  712. /* Insert suspend check point */
  713. if (comp_ctx->enable_thread_mgr) {
  714. if (!check_suspend_flags(comp_ctx, func_ctx))
  715. return false;
  716. }
  717. #endif
  718. if (!(block_dst = get_target_block(func_ctx, br_depth))) {
  719. return false;
  720. }
  721. if (block_dst->label_type == LABEL_TYPE_LOOP) {
  722. /* Dest block is Loop block */
  723. /* Handle Loop parameters */
  724. for (i = 0; i < block_dst->param_count; i++) {
  725. param_index = block_dst->param_count - 1 - i;
  726. POP(value_param, block_dst->param_types[param_index]);
  727. ADD_TO_PARAM_PHIS(block_dst, value_param, param_index);
  728. }
  729. BUILD_BR(block_dst->llvm_entry_block);
  730. }
  731. else {
  732. /* Dest block is Block/If/Function block */
  733. /* Create the end block */
  734. if (!block_dst->llvm_end_block) {
  735. format_block_name(name, sizeof(name), block_dst->block_index,
  736. block_dst->label_type, LABEL_END);
  737. CREATE_BLOCK(block_dst->llvm_end_block, name);
  738. if ((next_llvm_end_block = find_next_llvm_end_block(block_dst)))
  739. MOVE_BLOCK_BEFORE(block_dst->llvm_end_block,
  740. next_llvm_end_block);
  741. }
  742. block_dst->is_reachable = true;
  743. /* Handle result values */
  744. CREATE_RESULT_VALUE_PHIS(block_dst);
  745. for (i = 0; i < block_dst->result_count; i++) {
  746. result_index = block_dst->result_count - 1 - i;
  747. POP(value_ret, block_dst->result_types[result_index]);
  748. ADD_TO_RESULT_PHIS(block_dst, value_ret, result_index);
  749. }
  750. /* Jump to the end block */
  751. BUILD_BR(block_dst->llvm_end_block);
  752. }
  753. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  754. fail:
  755. return false;
  756. }
  757. bool
  758. aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  759. uint32 br_depth, uint8 **p_frame_ip)
  760. {
  761. AOTBlock *block_dst;
  762. LLVMValueRef value_cmp, value, *values = NULL;
  763. LLVMBasicBlockRef llvm_else_block, next_llvm_end_block;
  764. char name[32];
  765. uint32 i, param_index, result_index;
  766. uint64 size;
  767. #if WASM_ENABLE_THREAD_MGR != 0
  768. /* Insert suspend check point */
  769. if (comp_ctx->enable_thread_mgr) {
  770. if (!check_suspend_flags(comp_ctx, func_ctx))
  771. return false;
  772. }
  773. #endif
  774. POP_COND(value_cmp);
  775. if (LLVMIsUndef(value_cmp)
  776. #if LLVM_VERSION_NUMBER >= 12
  777. || LLVMIsPoison(value_cmp)
  778. #endif
  779. ) {
  780. if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INTEGER_OVERFLOW,
  781. false, NULL, NULL))) {
  782. goto fail;
  783. }
  784. return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  785. }
  786. if (!LLVMIsEfficientConstInt(value_cmp)) {
  787. /* Compare value is not constant, create condition br IR */
  788. if (!(block_dst = get_target_block(func_ctx, br_depth))) {
  789. return false;
  790. }
  791. /* Create llvm else block */
  792. CREATE_BLOCK(llvm_else_block, "br_if_else");
  793. MOVE_BLOCK_AFTER_CURR(llvm_else_block);
  794. if (block_dst->label_type == LABEL_TYPE_LOOP) {
  795. /* Dest block is Loop block */
  796. /* Handle Loop parameters */
  797. if (block_dst->param_count) {
  798. size = sizeof(LLVMValueRef) * (uint64)block_dst->param_count;
  799. if (size >= UINT32_MAX
  800. || !(values = wasm_runtime_malloc((uint32)size))) {
  801. aot_set_last_error("allocate memory failed.");
  802. goto fail;
  803. }
  804. for (i = 0; i < block_dst->param_count; i++) {
  805. param_index = block_dst->param_count - 1 - i;
  806. POP(value, block_dst->param_types[param_index]);
  807. ADD_TO_PARAM_PHIS(block_dst, value, param_index);
  808. values[param_index] = value;
  809. }
  810. for (i = 0; i < block_dst->param_count; i++) {
  811. PUSH(values[i], block_dst->param_types[i]);
  812. }
  813. wasm_runtime_free(values);
  814. values = NULL;
  815. }
  816. BUILD_COND_BR(value_cmp, block_dst->llvm_entry_block,
  817. llvm_else_block);
  818. /* Move builder to else block */
  819. SET_BUILDER_POS(llvm_else_block);
  820. }
  821. else {
  822. /* Dest block is Block/If/Function block */
  823. /* Create the end block */
  824. if (!block_dst->llvm_end_block) {
  825. format_block_name(name, sizeof(name), block_dst->block_index,
  826. block_dst->label_type, LABEL_END);
  827. CREATE_BLOCK(block_dst->llvm_end_block, name);
  828. if ((next_llvm_end_block = find_next_llvm_end_block(block_dst)))
  829. MOVE_BLOCK_BEFORE(block_dst->llvm_end_block,
  830. next_llvm_end_block);
  831. }
  832. /* Set reachable flag and create condition br IR */
  833. block_dst->is_reachable = true;
  834. /* Handle result values */
  835. if (block_dst->result_count) {
  836. size = sizeof(LLVMValueRef) * (uint64)block_dst->result_count;
  837. if (size >= UINT32_MAX
  838. || !(values = wasm_runtime_malloc((uint32)size))) {
  839. aot_set_last_error("allocate memory failed.");
  840. goto fail;
  841. }
  842. CREATE_RESULT_VALUE_PHIS(block_dst);
  843. for (i = 0; i < block_dst->result_count; i++) {
  844. result_index = block_dst->result_count - 1 - i;
  845. POP(value, block_dst->result_types[result_index]);
  846. values[result_index] = value;
  847. ADD_TO_RESULT_PHIS(block_dst, value, result_index);
  848. }
  849. for (i = 0; i < block_dst->result_count; i++) {
  850. PUSH(values[i], block_dst->result_types[i]);
  851. }
  852. wasm_runtime_free(values);
  853. values = NULL;
  854. }
  855. /* Condition jump to end block */
  856. BUILD_COND_BR(value_cmp, block_dst->llvm_end_block,
  857. llvm_else_block);
  858. /* Move builder to else block */
  859. SET_BUILDER_POS(llvm_else_block);
  860. }
  861. }
  862. else {
  863. if ((int32)LLVMConstIntGetZExtValue(value_cmp) != 0) {
  864. /* Compare value is not 0, condition is true, same as op_br */
  865. return aot_compile_op_br(comp_ctx, func_ctx, br_depth, p_frame_ip);
  866. }
  867. else {
  868. /* Compare value is not 0, condition is false, skip br_if */
  869. return true;
  870. }
  871. }
  872. return true;
  873. fail:
  874. if (values)
  875. wasm_runtime_free(values);
  876. return false;
  877. }
  878. bool
  879. aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  880. uint32 *br_depths, uint32 br_count, uint8 **p_frame_ip)
  881. {
  882. uint32 i, j;
  883. LLVMValueRef value_switch, value_cmp, value_case, value, *values = NULL;
  884. LLVMBasicBlockRef default_llvm_block = NULL, target_llvm_block;
  885. LLVMBasicBlockRef next_llvm_end_block;
  886. AOTBlock *target_block;
  887. uint32 br_depth, depth_idx;
  888. uint32 param_index, result_index;
  889. uint64 size;
  890. char name[32];
  891. #if WASM_ENABLE_THREAD_MGR != 0
  892. /* Insert suspend check point */
  893. if (comp_ctx->enable_thread_mgr) {
  894. if (!check_suspend_flags(comp_ctx, func_ctx))
  895. return false;
  896. }
  897. #endif
  898. POP_I32(value_cmp);
  899. if (LLVMIsUndef(value_cmp)
  900. #if LLVM_VERSION_NUMBER >= 12
  901. || LLVMIsPoison(value_cmp)
  902. #endif
  903. ) {
  904. if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INTEGER_OVERFLOW,
  905. false, NULL, NULL))) {
  906. goto fail;
  907. }
  908. return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  909. }
  910. if (!LLVMIsEfficientConstInt(value_cmp)) {
  911. /* Compare value is not constant, create switch IR */
  912. for (i = 0; i <= br_count; i++) {
  913. target_block = get_target_block(func_ctx, br_depths[i]);
  914. if (!target_block)
  915. return false;
  916. if (target_block->label_type != LABEL_TYPE_LOOP) {
  917. /* Dest block is Block/If/Function block */
  918. /* Create the end block */
  919. if (!target_block->llvm_end_block) {
  920. format_block_name(name, sizeof(name),
  921. target_block->block_index,
  922. target_block->label_type, LABEL_END);
  923. CREATE_BLOCK(target_block->llvm_end_block, name);
  924. if ((next_llvm_end_block =
  925. find_next_llvm_end_block(target_block)))
  926. MOVE_BLOCK_BEFORE(target_block->llvm_end_block,
  927. next_llvm_end_block);
  928. }
  929. /* Handle result values */
  930. if (target_block->result_count) {
  931. size = sizeof(LLVMValueRef)
  932. * (uint64)target_block->result_count;
  933. if (size >= UINT32_MAX
  934. || !(values = wasm_runtime_malloc((uint32)size))) {
  935. aot_set_last_error("allocate memory failed.");
  936. goto fail;
  937. }
  938. CREATE_RESULT_VALUE_PHIS(target_block);
  939. for (j = 0; j < target_block->result_count; j++) {
  940. result_index = target_block->result_count - 1 - j;
  941. POP(value, target_block->result_types[result_index]);
  942. values[result_index] = value;
  943. ADD_TO_RESULT_PHIS(target_block, value, result_index);
  944. }
  945. for (j = 0; j < target_block->result_count; j++) {
  946. PUSH(values[j], target_block->result_types[j]);
  947. }
  948. wasm_runtime_free(values);
  949. values = NULL;
  950. }
  951. target_block->is_reachable = true;
  952. if (i == br_count)
  953. default_llvm_block = target_block->llvm_end_block;
  954. }
  955. else {
  956. /* Handle Loop parameters */
  957. if (target_block->param_count) {
  958. size = sizeof(LLVMValueRef)
  959. * (uint64)target_block->param_count;
  960. if (size >= UINT32_MAX
  961. || !(values = wasm_runtime_malloc((uint32)size))) {
  962. aot_set_last_error("allocate memory failed.");
  963. goto fail;
  964. }
  965. for (j = 0; j < target_block->param_count; j++) {
  966. param_index = target_block->param_count - 1 - j;
  967. POP(value, target_block->param_types[param_index]);
  968. values[param_index] = value;
  969. ADD_TO_PARAM_PHIS(target_block, value, param_index);
  970. }
  971. for (j = 0; j < target_block->param_count; j++) {
  972. PUSH(values[j], target_block->param_types[j]);
  973. }
  974. wasm_runtime_free(values);
  975. values = NULL;
  976. }
  977. if (i == br_count)
  978. default_llvm_block = target_block->llvm_entry_block;
  979. }
  980. }
  981. /* Create switch IR */
  982. if (!(value_switch = LLVMBuildSwitch(comp_ctx->builder, value_cmp,
  983. default_llvm_block, br_count))) {
  984. aot_set_last_error("llvm build switch failed.");
  985. return false;
  986. }
  987. /* Add each case for switch IR */
  988. for (i = 0; i < br_count; i++) {
  989. value_case = I32_CONST(i);
  990. CHECK_LLVM_CONST(value_case);
  991. target_block = get_target_block(func_ctx, br_depths[i]);
  992. if (!target_block)
  993. return false;
  994. target_llvm_block = target_block->label_type != LABEL_TYPE_LOOP
  995. ? target_block->llvm_end_block
  996. : target_block->llvm_entry_block;
  997. LLVMAddCase(value_switch, value_case, target_llvm_block);
  998. }
  999. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  1000. }
  1001. else {
  1002. /* Compare value is constant, create br IR */
  1003. depth_idx = (uint32)LLVMConstIntGetZExtValue(value_cmp);
  1004. br_depth = br_depths[br_count];
  1005. if (depth_idx < br_count) {
  1006. br_depth = br_depths[depth_idx];
  1007. }
  1008. return aot_compile_op_br(comp_ctx, func_ctx, br_depth, p_frame_ip);
  1009. }
  1010. fail:
  1011. if (values)
  1012. wasm_runtime_free(values);
  1013. return false;
  1014. }
  1015. bool
  1016. aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  1017. uint8 **p_frame_ip)
  1018. {
  1019. AOTBlock *block_func = func_ctx->block_stack.block_list_head;
  1020. LLVMValueRef value;
  1021. LLVMValueRef ret;
  1022. AOTFuncType *func_type;
  1023. uint32 i, param_index, result_index;
  1024. #if WASM_ENABLE_DEBUG_AOT != 0
  1025. LLVMMetadataRef return_location;
  1026. #endif
  1027. bh_assert(block_func);
  1028. func_type = func_ctx->aot_func->func_type;
  1029. #if WASM_ENABLE_DEBUG_AOT != 0
  1030. return_location = dwarf_gen_location(
  1031. comp_ctx, func_ctx,
  1032. (*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code);
  1033. #endif
  1034. if (block_func->result_count) {
  1035. /* Store extra result values to function parameters */
  1036. for (i = 0; i < block_func->result_count - 1; i++) {
  1037. LLVMValueRef res;
  1038. result_index = block_func->result_count - 1 - i;
  1039. POP(value, block_func->result_types[result_index]);
  1040. param_index = func_type->param_count + result_index;
  1041. if (!(res = LLVMBuildStore(
  1042. comp_ctx->builder, value,
  1043. LLVMGetParam(func_ctx->func, param_index)))) {
  1044. aot_set_last_error("llvm build store failed.");
  1045. goto fail;
  1046. }
  1047. LLVMSetAlignment(res, 1);
  1048. }
  1049. /* Return the first result value */
  1050. POP(value, block_func->result_types[0]);
  1051. if (!(ret = LLVMBuildRet(comp_ctx->builder, value))) {
  1052. aot_set_last_error("llvm build return failed.");
  1053. goto fail;
  1054. }
  1055. #if WASM_ENABLE_DEBUG_AOT != 0
  1056. LLVMInstructionSetDebugLoc(ret, return_location);
  1057. #endif
  1058. }
  1059. else {
  1060. if (!(ret = LLVMBuildRetVoid(comp_ctx->builder))) {
  1061. aot_set_last_error("llvm build return void failed.");
  1062. goto fail;
  1063. }
  1064. #if WASM_ENABLE_DEBUG_AOT != 0
  1065. LLVMInstructionSetDebugLoc(ret, return_location);
  1066. #endif
  1067. }
  1068. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  1069. fail:
  1070. return false;
  1071. }
  1072. bool
  1073. aot_compile_op_unreachable(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  1074. uint8 **p_frame_ip)
  1075. {
  1076. if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_UNREACHABLE, false, NULL,
  1077. NULL))
  1078. return false;
  1079. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  1080. }
  1081. bool
  1082. aot_handle_next_reachable_block(AOTCompContext *comp_ctx,
  1083. AOTFuncContext *func_ctx, uint8 **p_frame_ip)
  1084. {
  1085. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  1086. }