aot_emit_control.c 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759
  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_stack_frame_comp.h"
  9. #if WASM_ENABLE_GC != 0
  10. #include "aot_emit_gc.h"
  11. #endif
  12. #include "../aot/aot_runtime.h"
  13. #include "../interpreter/wasm_loader.h"
  14. #if WASM_ENABLE_DEBUG_AOT != 0
  15. #include "debug/dwarf_extractor.h"
  16. #endif
  17. static char *block_name_prefix[] = { "block", "loop", "if" };
  18. static char *block_name_suffix[] = { "begin", "else", "end" };
  19. /* clang-format off */
  20. enum {
  21. LABEL_BEGIN = 0,
  22. LABEL_ELSE,
  23. LABEL_END
  24. };
  25. /* clang-format on */
  26. static void
  27. format_block_name(char *name, uint32 name_size, uint32 block_index,
  28. uint32 label_type, uint32 label_id)
  29. {
  30. if (label_type != LABEL_TYPE_FUNCTION)
  31. snprintf(name, name_size, "%s%d%s%s", block_name_prefix[label_type],
  32. block_index, "_", block_name_suffix[label_id]);
  33. else
  34. snprintf(name, name_size, "%s", "func_end");
  35. }
  36. #define CREATE_BLOCK(new_llvm_block, name) \
  37. do { \
  38. if (!(new_llvm_block = LLVMAppendBasicBlockInContext( \
  39. comp_ctx->context, func_ctx->func, name))) { \
  40. aot_set_last_error("add LLVM basic block failed."); \
  41. goto fail; \
  42. } \
  43. if (!strcmp(name, "func_end") && comp_ctx->aux_stack_frame_type \
  44. && comp_ctx->call_stack_features.frame_per_function) { \
  45. LLVMBasicBlockRef cur_block = \
  46. LLVMGetInsertBlock(comp_ctx->builder); \
  47. SET_BUILDER_POS(new_llvm_block); \
  48. if (!aot_free_frame_per_function_frame_for_aot_func(comp_ctx, \
  49. func_ctx)) { \
  50. goto fail; \
  51. } \
  52. SET_BUILDER_POS(cur_block); \
  53. } \
  54. } while (0)
  55. #define CURR_BLOCK() LLVMGetInsertBlock(comp_ctx->builder)
  56. #define MOVE_BLOCK_AFTER(llvm_block, llvm_block_after) \
  57. LLVMMoveBasicBlockAfter(llvm_block, llvm_block_after)
  58. #define MOVE_BLOCK_AFTER_CURR(llvm_block) \
  59. LLVMMoveBasicBlockAfter(llvm_block, CURR_BLOCK())
  60. #define MOVE_BLOCK_BEFORE(llvm_block, llvm_block_before) \
  61. LLVMMoveBasicBlockBefore(llvm_block, llvm_block_before)
  62. #define BUILD_BR(llvm_block) \
  63. do { \
  64. if (!LLVMBuildBr(comp_ctx->builder, llvm_block)) { \
  65. aot_set_last_error("llvm build br failed."); \
  66. goto fail; \
  67. } \
  68. } while (0)
  69. #define BUILD_COND_BR(value_if, block_then, block_else) \
  70. do { \
  71. if (!LLVMBuildCondBr(comp_ctx->builder, value_if, block_then, \
  72. block_else)) { \
  73. aot_set_last_error("llvm build cond br failed."); \
  74. goto fail; \
  75. } \
  76. } while (0)
  77. #define SET_BUILDER_POS(llvm_block) \
  78. LLVMPositionBuilderAtEnd(comp_ctx->builder, llvm_block)
  79. #define CREATE_RESULT_VALUE_PHIS(block) \
  80. do { \
  81. if (block->result_count && !block->result_phis) { \
  82. uint32 _i; \
  83. uint64 _size; \
  84. LLVMBasicBlockRef _block_curr = CURR_BLOCK(); \
  85. /* Allocate memory */ \
  86. _size = sizeof(LLVMValueRef) * (uint64)block->result_count; \
  87. if (_size >= UINT32_MAX \
  88. || !(block->result_phis = \
  89. wasm_runtime_malloc((uint32)_size))) { \
  90. aot_set_last_error("allocate memory failed."); \
  91. goto fail; \
  92. } \
  93. SET_BUILDER_POS(block->llvm_end_block); \
  94. LLVMValueRef first_instr = \
  95. get_first_non_phi(block->llvm_end_block); \
  96. if (first_instr) { \
  97. LLVMPositionBuilderBefore(comp_ctx->builder, first_instr); \
  98. } \
  99. for (_i = 0; _i < block->result_count; _i++) { \
  100. if (!(block->result_phis[_i] = LLVMBuildPhi( \
  101. comp_ctx->builder, \
  102. TO_LLVM_TYPE(block->result_types[_i]), "phi"))) { \
  103. aot_set_last_error("llvm build phi failed."); \
  104. goto fail; \
  105. } \
  106. } \
  107. SET_BUILDER_POS(_block_curr); \
  108. } \
  109. } while (0)
  110. #define ADD_TO_RESULT_PHIS(block, value, idx) \
  111. do { \
  112. LLVMBasicBlockRef _block_curr = CURR_BLOCK(); \
  113. LLVMTypeRef phi_ty = LLVMTypeOf(block->result_phis[idx]); \
  114. LLVMTypeRef value_ty = LLVMTypeOf(value); \
  115. bh_assert(LLVMGetTypeKind(phi_ty) == LLVMGetTypeKind(value_ty)); \
  116. bh_assert(LLVMGetTypeContext(phi_ty) == LLVMGetTypeContext(value_ty)); \
  117. LLVMAddIncoming(block->result_phis[idx], &value, &_block_curr, 1); \
  118. (void)phi_ty; \
  119. (void)value_ty; \
  120. } while (0)
  121. #define BUILD_ICMP(op, left, right, res, name) \
  122. do { \
  123. if (!(res = \
  124. LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \
  125. aot_set_last_error("llvm build icmp failed."); \
  126. goto fail; \
  127. } \
  128. } while (0)
  129. #define ADD_TO_PARAM_PHIS(block, value, idx) \
  130. do { \
  131. LLVMBasicBlockRef _block_curr = CURR_BLOCK(); \
  132. LLVMAddIncoming(block->param_phis[idx], &value, &_block_curr, 1); \
  133. } while (0)
  134. static LLVMBasicBlockRef
  135. find_next_llvm_end_block(AOTBlock *block)
  136. {
  137. block = block->prev;
  138. while (block && !block->llvm_end_block)
  139. block = block->prev;
  140. return block ? block->llvm_end_block : NULL;
  141. }
  142. static AOTBlock *
  143. get_target_block(AOTFuncContext *func_ctx, uint32 br_depth)
  144. {
  145. uint32 i = br_depth;
  146. AOTBlock *block = func_ctx->block_stack.block_list_end;
  147. while (i-- > 0 && block) {
  148. block = block->prev;
  149. }
  150. if (!block) {
  151. aot_set_last_error("WASM block stack underflow.");
  152. return NULL;
  153. }
  154. return block;
  155. }
  156. LLVMValueRef
  157. get_first_non_phi(LLVMBasicBlockRef block)
  158. {
  159. LLVMValueRef instr = LLVMGetFirstInstruction(block);
  160. while (instr && LLVMIsAPHINode(instr)) {
  161. instr = LLVMGetNextInstruction(instr);
  162. }
  163. return instr;
  164. }
  165. static void
  166. clear_frame_locals(AOTCompFrame *aot_frame)
  167. {
  168. uint32 i;
  169. for (i = 0; i < aot_frame->max_local_cell_num; i++) {
  170. aot_frame->lp[i].dirty = 0;
  171. aot_frame->lp[i].value = NULL;
  172. if (aot_frame->comp_ctx->enable_gc)
  173. /* Mark the ref flag as committed */
  174. aot_frame->lp[i].committed_ref = aot_frame->lp[i].ref + 1;
  175. }
  176. }
  177. static void
  178. restore_frame_sp_for_op_else(AOTBlock *block, AOTCompFrame *aot_frame)
  179. {
  180. uint32 all_cell_num =
  181. aot_frame->max_local_cell_num + aot_frame->max_stack_cell_num;
  182. AOTValueSlot *p_end = aot_frame->lp + all_cell_num, *p;
  183. /* Reset all the value slots from current frame sp for the else
  184. branch since they be the same as starting to translate the
  185. if branch */
  186. for (p = block->frame_sp_begin; p < p_end; p++) {
  187. p->dirty = 0;
  188. p->value = NULL;
  189. p->type = 0;
  190. if (aot_frame->comp_ctx->enable_gc) {
  191. p->ref = 0;
  192. p->committed_ref = 1;
  193. }
  194. }
  195. bh_assert(aot_frame->sp >= block->frame_sp_begin);
  196. aot_frame->sp = block->frame_sp_begin;
  197. }
  198. static void
  199. restore_frame_sp_for_op_end(AOTBlock *block, AOTCompFrame *aot_frame)
  200. {
  201. uint32 all_cell_num =
  202. aot_frame->max_local_cell_num + aot_frame->max_stack_cell_num;
  203. AOTValueSlot *p_end = aot_frame->lp + all_cell_num, *p;
  204. bh_assert(block->frame_sp_max_reached >= block->frame_sp_begin);
  205. /* Reset all the value slots from current frame sp to be same as
  206. starting to translate this block, except for the frame ref
  207. flags: set the flags to uncommitted before the max frame sp
  208. ever reached, set the flags to committed non-ref after that */
  209. for (p = block->frame_sp_begin; p < p_end; p++) {
  210. p->dirty = 0;
  211. p->value = NULL;
  212. p->type = 0;
  213. if (aot_frame->comp_ctx->enable_gc) {
  214. p->ref = 0;
  215. if (p < block->frame_sp_max_reached)
  216. p->committed_ref = 0;
  217. else
  218. p->committed_ref = 1;
  219. }
  220. }
  221. bh_assert(aot_frame->sp >= block->frame_sp_begin);
  222. aot_frame->sp = block->frame_sp_begin;
  223. }
  224. static bool
  225. handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  226. uint8 **p_frame_ip)
  227. {
  228. AOTBlock *block = func_ctx->block_stack.block_list_end;
  229. AOTBlock *block_prev;
  230. AOTCompFrame *aot_frame = comp_ctx->aot_frame;
  231. uint8 *frame_ip = NULL;
  232. uint32 i;
  233. AOTFuncType *func_type;
  234. LLVMValueRef ret;
  235. #if WASM_ENABLE_DEBUG_AOT != 0
  236. LLVMMetadataRef return_location;
  237. #endif
  238. aot_checked_addr_list_destroy(func_ctx);
  239. bh_assert(block);
  240. #if WASM_ENABLE_DEBUG_AOT != 0
  241. return_location = dwarf_gen_location(
  242. comp_ctx, func_ctx,
  243. (*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code);
  244. #endif
  245. if (aot_frame) {
  246. /* Clear frame local variables since they have been committed */
  247. clear_frame_locals(aot_frame);
  248. }
  249. if (block->label_type == LABEL_TYPE_IF && block->llvm_else_block
  250. && *p_frame_ip <= block->wasm_code_else) {
  251. /* Clear value stack and start to translate else branch */
  252. aot_value_stack_destroy(comp_ctx, &block->value_stack);
  253. if (aot_frame) {
  254. /* Restore the frame sp */
  255. restore_frame_sp_for_op_else(block, aot_frame);
  256. }
  257. /* Recover parameters of else branch */
  258. for (i = 0; i < block->param_count; i++)
  259. PUSH(block->else_param_phis[i], block->param_types[i]);
  260. SET_BUILDER_POS(block->llvm_else_block);
  261. *p_frame_ip = block->wasm_code_else + 1;
  262. return true;
  263. }
  264. while (block && !block->is_reachable) {
  265. block_prev = block->prev;
  266. block = aot_block_stack_pop(&func_ctx->block_stack);
  267. if (block->label_type == LABEL_TYPE_IF) {
  268. if (block->llvm_else_block && !block->skip_wasm_code_else
  269. && *p_frame_ip <= block->wasm_code_else) {
  270. /* Clear value stack and start to translate else branch */
  271. aot_value_stack_destroy(comp_ctx, &block->value_stack);
  272. if (aot_frame) {
  273. /* Restore the frame sp */
  274. restore_frame_sp_for_op_else(block, aot_frame);
  275. }
  276. SET_BUILDER_POS(block->llvm_else_block);
  277. *p_frame_ip = block->wasm_code_else + 1;
  278. /* Push back the block */
  279. aot_block_stack_push(&func_ctx->block_stack, block);
  280. /* Recover parameters of else branch */
  281. for (i = 0; i < block->param_count; i++)
  282. PUSH(block->else_param_phis[i], block->param_types[i]);
  283. return true;
  284. }
  285. else if (block->llvm_end_block) {
  286. /* Remove unreachable basic block */
  287. LLVMDeleteBasicBlock(block->llvm_end_block);
  288. block->llvm_end_block = NULL;
  289. }
  290. }
  291. frame_ip = block->wasm_code_end;
  292. aot_block_destroy(comp_ctx, block);
  293. block = block_prev;
  294. }
  295. if (!block) {
  296. *p_frame_ip = frame_ip + 1;
  297. return true;
  298. }
  299. if (block->label_type == LABEL_TYPE_IF && block->llvm_else_block
  300. && !block->skip_wasm_code_else
  301. && *p_frame_ip <= block->wasm_code_else) {
  302. /* Clear value stack and start to translate else branch */
  303. aot_value_stack_destroy(comp_ctx, &block->value_stack);
  304. if (aot_frame) {
  305. /* Restore the frame sp */
  306. restore_frame_sp_for_op_else(block, aot_frame);
  307. }
  308. /* Recover parameters of else branch */
  309. for (i = 0; i < block->param_count; i++)
  310. PUSH(block->else_param_phis[i], block->param_types[i]);
  311. SET_BUILDER_POS(block->llvm_else_block);
  312. *p_frame_ip = block->wasm_code_else + 1;
  313. return true;
  314. }
  315. *p_frame_ip = block->wasm_code_end + 1;
  316. SET_BUILDER_POS(block->llvm_end_block);
  317. /* Pop block, push its return value, and destroy the block */
  318. block = aot_block_stack_pop(&func_ctx->block_stack);
  319. if (aot_frame) {
  320. /* Restore the frame sp */
  321. restore_frame_sp_for_op_end(block, aot_frame);
  322. }
  323. func_type = func_ctx->aot_func->func_type;
  324. for (i = 0; i < block->result_count; i++) {
  325. bh_assert(block->result_phis[i]);
  326. if (block->label_type != LABEL_TYPE_FUNCTION) {
  327. PUSH(block->result_phis[i], block->result_types[i]);
  328. }
  329. else {
  330. /* Store extra return values to function parameters */
  331. if (i != 0) {
  332. LLVMValueRef res;
  333. uint32 param_index = func_type->param_count + i;
  334. if (!(res = LLVMBuildStore(
  335. comp_ctx->builder, block->result_phis[i],
  336. LLVMGetParam(func_ctx->func, param_index)))) {
  337. aot_set_last_error("llvm build store failed.");
  338. goto fail;
  339. }
  340. LLVMSetAlignment(res, 1);
  341. }
  342. }
  343. }
  344. if (block->label_type == LABEL_TYPE_FUNCTION) {
  345. if (block->result_count) {
  346. /* Return the first return value */
  347. if (!(ret =
  348. LLVMBuildRet(comp_ctx->builder, block->result_phis[0]))) {
  349. aot_set_last_error("llvm build return failed.");
  350. goto fail;
  351. }
  352. #if WASM_ENABLE_DEBUG_AOT != 0
  353. if (return_location != NULL) {
  354. LLVMInstructionSetDebugLoc(ret, return_location);
  355. }
  356. #endif
  357. }
  358. else {
  359. if (!(ret = LLVMBuildRetVoid(comp_ctx->builder))) {
  360. aot_set_last_error("llvm build return void failed.");
  361. goto fail;
  362. }
  363. #if WASM_ENABLE_DEBUG_AOT != 0
  364. if (return_location != NULL) {
  365. LLVMInstructionSetDebugLoc(ret, return_location);
  366. }
  367. #endif
  368. }
  369. }
  370. aot_block_destroy(comp_ctx, block);
  371. return true;
  372. fail:
  373. return false;
  374. }
  375. static bool
  376. push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
  377. AOTFuncContext *func_ctx,
  378. AOTBlock *block)
  379. {
  380. uint32 i, param_index;
  381. LLVMValueRef value, br_inst;
  382. uint64 size;
  383. char name[32];
  384. LLVMBasicBlockRef block_curr = CURR_BLOCK();
  385. if (block->param_count) {
  386. size = sizeof(LLVMValueRef) * (uint64)block->param_count;
  387. if (size >= UINT32_MAX
  388. || !(block->param_phis = wasm_runtime_malloc((uint32)size))) {
  389. aot_set_last_error("allocate memory failed.");
  390. return false;
  391. }
  392. if (block->label_type == LABEL_TYPE_IF && !block->skip_wasm_code_else
  393. && !(block->else_param_phis = wasm_runtime_malloc((uint32)size))) {
  394. wasm_runtime_free(block->param_phis);
  395. block->param_phis = NULL;
  396. aot_set_last_error("allocate memory failed.");
  397. return false;
  398. }
  399. /* Create param phis */
  400. for (i = 0; i < block->param_count; i++) {
  401. SET_BUILDER_POS(block->llvm_entry_block);
  402. snprintf(name, sizeof(name), "%s%d_phi%d",
  403. block_name_prefix[block->label_type], block->block_index,
  404. i);
  405. if (!(block->param_phis[i] = LLVMBuildPhi(
  406. comp_ctx->builder, TO_LLVM_TYPE(block->param_types[i]),
  407. name))) {
  408. aot_set_last_error("llvm build phi failed.");
  409. goto fail;
  410. }
  411. if (block->label_type == LABEL_TYPE_IF
  412. && !block->skip_wasm_code_else && block->llvm_else_block) {
  413. /* Build else param phis */
  414. SET_BUILDER_POS(block->llvm_else_block);
  415. snprintf(name, sizeof(name), "else%d_phi%d", block->block_index,
  416. i);
  417. if (!(block->else_param_phis[i] = LLVMBuildPhi(
  418. comp_ctx->builder,
  419. TO_LLVM_TYPE(block->param_types[i]), name))) {
  420. aot_set_last_error("llvm build phi failed.");
  421. goto fail;
  422. }
  423. }
  424. }
  425. /* At this point, the branch instruction was already built to jump to
  426. * the new BB, to avoid generating zext instruction from the popped
  427. * operand that would come after branch instruction, we should position
  428. * the builder before the last branch instruction */
  429. br_inst = LLVMGetLastInstruction(block_curr);
  430. bh_assert(LLVMGetInstructionOpcode(br_inst) == LLVMBr);
  431. LLVMPositionBuilderBefore(comp_ctx->builder, br_inst);
  432. /* Pop param values from current block's
  433. * value stack and add to param phis.
  434. */
  435. for (i = 0; i < block->param_count; i++) {
  436. param_index = block->param_count - 1 - i;
  437. POP(value, block->param_types[param_index]);
  438. if (block->llvm_entry_block)
  439. /* Only add incoming phis if the entry block was created */
  440. ADD_TO_PARAM_PHIS(block, value, param_index);
  441. if (block->label_type == LABEL_TYPE_IF
  442. && !block->skip_wasm_code_else) {
  443. if (block->llvm_else_block) {
  444. /* has else branch, add to else param phis */
  445. LLVMAddIncoming(block->else_param_phis[param_index], &value,
  446. &block_curr, 1);
  447. }
  448. else {
  449. /* no else branch, add to result phis */
  450. CREATE_RESULT_VALUE_PHIS(block);
  451. ADD_TO_RESULT_PHIS(block, value, param_index);
  452. }
  453. }
  454. }
  455. }
  456. /* Push the new block to block stack */
  457. aot_block_stack_push(&func_ctx->block_stack, block);
  458. if (comp_ctx->aot_frame) {
  459. block->frame_sp_begin = block->frame_sp_max_reached =
  460. comp_ctx->aot_frame->sp;
  461. }
  462. /* Push param phis to the new block */
  463. for (i = 0; i < block->param_count; i++) {
  464. if (block->llvm_entry_block)
  465. /* Push param phis if the entry basic block was created */
  466. PUSH(block->param_phis[i], block->param_types[i]);
  467. else {
  468. bh_assert(block->label_type == LABEL_TYPE_IF
  469. && block->llvm_else_block && block->else_param_phis
  470. && !block->skip_wasm_code_else);
  471. /* Push else param phis if we start to translate the
  472. else branch */
  473. PUSH(block->else_param_phis[i], block->param_types[i]);
  474. }
  475. }
  476. return true;
  477. fail:
  478. if (block->param_phis) {
  479. wasm_runtime_free(block->param_phis);
  480. block->param_phis = NULL;
  481. }
  482. if (block->else_param_phis) {
  483. wasm_runtime_free(block->else_param_phis);
  484. block->else_param_phis = NULL;
  485. }
  486. return false;
  487. }
  488. bool
  489. aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  490. uint8 **p_frame_ip, uint8 *frame_ip_end, uint32 label_type,
  491. uint32 param_count, uint8 *param_types,
  492. uint32 result_count, uint8 *result_types)
  493. {
  494. BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
  495. AOTBlock *block;
  496. uint8 *else_addr, *end_addr;
  497. LLVMValueRef value;
  498. char name[32];
  499. /* Check block stack */
  500. if (!func_ctx->block_stack.block_list_end) {
  501. aot_set_last_error("WASM block stack underflow.");
  502. return false;
  503. }
  504. memset(block_addr_cache, 0, sizeof(block_addr_cache));
  505. /* Get block info */
  506. if (!(wasm_loader_find_block_addr(
  507. NULL, (BlockAddr *)block_addr_cache, *p_frame_ip, frame_ip_end,
  508. (uint8)label_type, &else_addr, &end_addr))) {
  509. aot_set_last_error("find block end addr failed.");
  510. return false;
  511. }
  512. /* Allocate memory */
  513. if (!(block = wasm_runtime_malloc(sizeof(AOTBlock)))) {
  514. aot_set_last_error("allocate memory failed.");
  515. return false;
  516. }
  517. memset(block, 0, sizeof(AOTBlock));
  518. if (param_count
  519. && !(block->param_types = wasm_runtime_malloc(param_count))) {
  520. aot_set_last_error("allocate memory failed.");
  521. goto fail;
  522. }
  523. if (result_count) {
  524. if (!(block->result_types = wasm_runtime_malloc(result_count))) {
  525. aot_set_last_error("allocate memory failed.");
  526. goto fail;
  527. }
  528. }
  529. /* Init aot block data */
  530. block->label_type = label_type;
  531. block->param_count = param_count;
  532. if (param_count) {
  533. bh_memcpy_s(block->param_types, param_count, param_types, param_count);
  534. }
  535. block->result_count = result_count;
  536. if (result_count) {
  537. bh_memcpy_s(block->result_types, result_count, result_types,
  538. result_count);
  539. }
  540. block->wasm_code_else = else_addr;
  541. block->wasm_code_end = end_addr;
  542. block->block_index = func_ctx->block_stack.block_index[label_type];
  543. func_ctx->block_stack.block_index[label_type]++;
  544. if (comp_ctx->aot_frame) {
  545. if (label_type != LABEL_TYPE_BLOCK && comp_ctx->enable_gc
  546. && !aot_gen_commit_values(comp_ctx->aot_frame)) {
  547. goto fail;
  548. }
  549. }
  550. if (label_type == LABEL_TYPE_BLOCK || label_type == LABEL_TYPE_LOOP) {
  551. /* Create block */
  552. format_block_name(name, sizeof(name), block->block_index, label_type,
  553. LABEL_BEGIN);
  554. CREATE_BLOCK(block->llvm_entry_block, name);
  555. MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
  556. /* Jump to the entry block */
  557. BUILD_BR(block->llvm_entry_block);
  558. if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx, block))
  559. goto fail;
  560. /* Start to translate the block */
  561. SET_BUILDER_POS(block->llvm_entry_block);
  562. if (label_type == LABEL_TYPE_LOOP)
  563. aot_checked_addr_list_destroy(func_ctx);
  564. }
  565. else if (label_type == LABEL_TYPE_IF) {
  566. POP_COND(value);
  567. if (LLVMIsUndef(value)
  568. #if LLVM_VERSION_NUMBER >= 12
  569. || LLVMIsPoison(value)
  570. #endif
  571. ) {
  572. if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INTEGER_OVERFLOW,
  573. false, NULL, NULL))) {
  574. goto fail;
  575. }
  576. aot_block_destroy(comp_ctx, block);
  577. return aot_handle_next_reachable_block(comp_ctx, func_ctx,
  578. p_frame_ip);
  579. }
  580. if (!LLVMIsEfficientConstInt(value)) {
  581. /* Compare value is not constant, create condition br IR */
  582. /* Create entry block */
  583. format_block_name(name, sizeof(name), block->block_index,
  584. label_type, LABEL_BEGIN);
  585. CREATE_BLOCK(block->llvm_entry_block, name);
  586. MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
  587. /* Create end block */
  588. format_block_name(name, sizeof(name), block->block_index,
  589. label_type, LABEL_END);
  590. CREATE_BLOCK(block->llvm_end_block, name);
  591. MOVE_BLOCK_AFTER(block->llvm_end_block, block->llvm_entry_block);
  592. if (else_addr) {
  593. /* Create else block */
  594. format_block_name(name, sizeof(name), block->block_index,
  595. label_type, LABEL_ELSE);
  596. CREATE_BLOCK(block->llvm_else_block, name);
  597. MOVE_BLOCK_AFTER(block->llvm_else_block,
  598. block->llvm_entry_block);
  599. /* Create condition br IR */
  600. BUILD_COND_BR(value, block->llvm_entry_block,
  601. block->llvm_else_block);
  602. }
  603. else {
  604. /* Create condition br IR */
  605. BUILD_COND_BR(value, block->llvm_entry_block,
  606. block->llvm_end_block);
  607. block->is_reachable = true;
  608. }
  609. if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx,
  610. block))
  611. goto fail;
  612. /* Start to translate if branch of BLOCK if */
  613. SET_BUILDER_POS(block->llvm_entry_block);
  614. }
  615. else {
  616. if ((int32)LLVMConstIntGetZExtValue(value) != 0) {
  617. /* Compare value is not 0, condition is true, else branch of
  618. BLOCK if cannot be reached */
  619. block->skip_wasm_code_else = true;
  620. /* Create entry block */
  621. format_block_name(name, sizeof(name), block->block_index,
  622. label_type, LABEL_BEGIN);
  623. CREATE_BLOCK(block->llvm_entry_block, name);
  624. MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
  625. /* Jump to the entry block */
  626. BUILD_BR(block->llvm_entry_block);
  627. if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx,
  628. block))
  629. goto fail;
  630. /* Start to translate the if branch */
  631. SET_BUILDER_POS(block->llvm_entry_block);
  632. }
  633. else {
  634. /* Compare value is not 0, condition is false, if branch of
  635. BLOCK if cannot be reached */
  636. if (else_addr) {
  637. /* Create else block */
  638. format_block_name(name, sizeof(name), block->block_index,
  639. label_type, LABEL_ELSE);
  640. CREATE_BLOCK(block->llvm_else_block, name);
  641. MOVE_BLOCK_AFTER_CURR(block->llvm_else_block);
  642. /* Jump to the else block */
  643. BUILD_BR(block->llvm_else_block);
  644. if (!push_aot_block_to_stack_and_pass_params(
  645. comp_ctx, func_ctx, block))
  646. goto fail;
  647. /* Start to translate the else branch */
  648. SET_BUILDER_POS(block->llvm_else_block);
  649. *p_frame_ip = else_addr + 1;
  650. }
  651. else {
  652. /* skip the block */
  653. aot_block_destroy(comp_ctx, block);
  654. *p_frame_ip = end_addr + 1;
  655. }
  656. }
  657. }
  658. }
  659. else {
  660. aot_set_last_error("Invalid block type.");
  661. goto fail;
  662. }
  663. return true;
  664. fail:
  665. aot_block_destroy(comp_ctx, block);
  666. return false;
  667. }
  668. bool
  669. aot_compile_op_else(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  670. uint8 **p_frame_ip)
  671. {
  672. AOTBlock *block = func_ctx->block_stack.block_list_end;
  673. LLVMValueRef value;
  674. AOTCompFrame *aot_frame = comp_ctx->aot_frame;
  675. char name[32];
  676. uint32 i, result_index;
  677. /* Check block */
  678. if (!block) {
  679. aot_set_last_error("WASM block stack underflow.");
  680. return false;
  681. }
  682. if (block->label_type != LABEL_TYPE_IF
  683. || (!block->skip_wasm_code_else && !block->llvm_else_block)) {
  684. aot_set_last_error("Invalid WASM block type.");
  685. return false;
  686. }
  687. /* Create end block if needed */
  688. if (!block->llvm_end_block) {
  689. format_block_name(name, sizeof(name), block->block_index,
  690. block->label_type, LABEL_END);
  691. CREATE_BLOCK(block->llvm_end_block, name);
  692. if (block->llvm_else_block)
  693. MOVE_BLOCK_AFTER(block->llvm_end_block, block->llvm_else_block);
  694. else
  695. MOVE_BLOCK_AFTER_CURR(block->llvm_end_block);
  696. }
  697. block->is_reachable = true;
  698. /* Comes from the if branch of BLOCK if */
  699. CREATE_RESULT_VALUE_PHIS(block);
  700. for (i = 0; i < block->result_count; i++) {
  701. result_index = block->result_count - 1 - i;
  702. POP(value, block->result_types[result_index]);
  703. ADD_TO_RESULT_PHIS(block, value, result_index);
  704. }
  705. if (aot_frame) {
  706. bh_assert(block->frame_sp_begin == aot_frame->sp);
  707. if (comp_ctx->enable_gc && !aot_gen_commit_values(aot_frame)) {
  708. goto fail;
  709. }
  710. }
  711. /* Jump to end block */
  712. BUILD_BR(block->llvm_end_block);
  713. if (!block->skip_wasm_code_else && block->llvm_else_block) {
  714. /* Clear value stack, recover param values
  715. and start to translate else branch. */
  716. aot_value_stack_destroy(comp_ctx, &block->value_stack);
  717. if (comp_ctx->aot_frame) {
  718. clear_frame_locals(aot_frame);
  719. restore_frame_sp_for_op_else(block, aot_frame);
  720. }
  721. for (i = 0; i < block->param_count; i++)
  722. PUSH(block->else_param_phis[i], block->param_types[i]);
  723. SET_BUILDER_POS(block->llvm_else_block);
  724. aot_checked_addr_list_destroy(func_ctx);
  725. return true;
  726. }
  727. /* No else branch or no need to translate else branch */
  728. block->is_reachable = true;
  729. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  730. fail:
  731. return false;
  732. }
  733. bool
  734. aot_compile_op_end(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  735. uint8 **p_frame_ip)
  736. {
  737. AOTBlock *block;
  738. LLVMValueRef value;
  739. LLVMBasicBlockRef next_llvm_end_block;
  740. char name[32];
  741. uint32 i, result_index;
  742. /* Check block stack */
  743. if (!(block = func_ctx->block_stack.block_list_end)) {
  744. aot_set_last_error("WASM block stack underflow.");
  745. return false;
  746. }
  747. /* Create the end block */
  748. if (!block->llvm_end_block) {
  749. format_block_name(name, sizeof(name), block->block_index,
  750. block->label_type, LABEL_END);
  751. CREATE_BLOCK(block->llvm_end_block, name);
  752. if ((next_llvm_end_block = find_next_llvm_end_block(block)))
  753. MOVE_BLOCK_BEFORE(block->llvm_end_block, next_llvm_end_block);
  754. }
  755. if (comp_ctx->aot_frame) {
  756. if (block->label_type != LABEL_TYPE_FUNCTION && comp_ctx->enable_gc
  757. && !aot_gen_commit_values(comp_ctx->aot_frame)) {
  758. return false;
  759. }
  760. }
  761. /* Handle block result values */
  762. CREATE_RESULT_VALUE_PHIS(block);
  763. for (i = 0; i < block->result_count; i++) {
  764. value = NULL;
  765. result_index = block->result_count - 1 - i;
  766. POP(value, block->result_types[result_index]);
  767. bh_assert(value);
  768. ADD_TO_RESULT_PHIS(block, value, result_index);
  769. }
  770. if (comp_ctx->aot_frame) {
  771. bh_assert(comp_ctx->aot_frame->sp == block->frame_sp_begin);
  772. }
  773. /* Jump to the end block */
  774. BUILD_BR(block->llvm_end_block);
  775. block->is_reachable = true;
  776. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  777. fail:
  778. return false;
  779. }
  780. bool
  781. check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  782. bool check_terminate_and_suspend)
  783. {
  784. LLVMValueRef terminate_addr, terminate_flags, flag, offset, res;
  785. LLVMBasicBlockRef terminate_block, non_terminate_block;
  786. AOTFuncType *aot_func_type = func_ctx->aot_func->func_type;
  787. bool is_shared_memory =
  788. comp_ctx->comp_data->memories[0].flags & 0x02 ? true : false;
  789. /* Only need to check the suspend flags when memory is shared since
  790. shared memory must be enabled for multi-threading */
  791. if (!is_shared_memory) {
  792. return true;
  793. }
  794. /* Offset of suspend_flags */
  795. offset = I32_FIVE;
  796. if (!(terminate_addr = LLVMBuildInBoundsGEP2(
  797. comp_ctx->builder, OPQ_PTR_TYPE, func_ctx->exec_env, &offset, 1,
  798. "terminate_addr"))) {
  799. aot_set_last_error("llvm build in bounds gep failed");
  800. return false;
  801. }
  802. if (!(terminate_addr =
  803. LLVMBuildBitCast(comp_ctx->builder, terminate_addr,
  804. INT32_PTR_TYPE, "terminate_addr_ptr"))) {
  805. aot_set_last_error("llvm build bit cast failed");
  806. return false;
  807. }
  808. if (!(terminate_flags =
  809. LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, terminate_addr,
  810. "terminate_flags"))) {
  811. aot_set_last_error("llvm build LOAD failed");
  812. return false;
  813. }
  814. /* Set terminate_flags memory access to volatile, so that the value
  815. will always be loaded from memory rather than register */
  816. LLVMSetVolatile(terminate_flags, true);
  817. if (!(flag = LLVMBuildAnd(comp_ctx->builder, terminate_flags, I32_ONE,
  818. "termination_flag"))) {
  819. aot_set_last_error("llvm build AND failed");
  820. return false;
  821. }
  822. CREATE_BLOCK(non_terminate_block, "non_terminate");
  823. MOVE_BLOCK_AFTER_CURR(non_terminate_block);
  824. CREATE_BLOCK(terminate_block, "terminate");
  825. MOVE_BLOCK_AFTER_CURR(terminate_block);
  826. BUILD_ICMP(LLVMIntEQ, flag, I32_ZERO, res, "flag_terminate");
  827. BUILD_COND_BR(res, non_terminate_block, terminate_block);
  828. /* Move builder to terminate block */
  829. SET_BUILDER_POS(terminate_block);
  830. if (!aot_build_zero_function_ret(comp_ctx, func_ctx, aot_func_type)) {
  831. goto fail;
  832. }
  833. /* Move builder to non terminate block */
  834. SET_BUILDER_POS(non_terminate_block);
  835. return true;
  836. fail:
  837. return false;
  838. }
  839. bool
  840. aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  841. uint32 br_depth, uint8 **p_frame_ip)
  842. {
  843. AOTBlock *block_dst;
  844. LLVMValueRef value_ret, value_param;
  845. LLVMBasicBlockRef next_llvm_end_block;
  846. char name[32];
  847. uint32 i, param_index, result_index;
  848. if (!(block_dst = get_target_block(func_ctx, br_depth))) {
  849. return false;
  850. }
  851. if (comp_ctx->aot_frame) {
  852. if (comp_ctx->enable_gc && !aot_gen_commit_values(comp_ctx->aot_frame))
  853. return false;
  854. if (block_dst->label_type == LABEL_TYPE_LOOP) {
  855. if (comp_ctx->enable_thread_mgr) {
  856. /* Commit sp when GC is enabled, don't commit ip */
  857. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame,
  858. comp_ctx->enable_gc, false))
  859. return false;
  860. }
  861. }
  862. else {
  863. if (comp_ctx->aot_frame->sp > block_dst->frame_sp_max_reached)
  864. block_dst->frame_sp_max_reached = comp_ctx->aot_frame->sp;
  865. }
  866. }
  867. /* Terminate or suspend current thread only when this is a backward jump */
  868. if (comp_ctx->enable_thread_mgr
  869. && block_dst->label_type == LABEL_TYPE_LOOP) {
  870. if (!check_suspend_flags(comp_ctx, func_ctx, true))
  871. return false;
  872. }
  873. if (block_dst->label_type == LABEL_TYPE_LOOP) {
  874. /* Dest block is Loop block */
  875. /* Handle Loop parameters */
  876. for (i = 0; i < block_dst->param_count; i++) {
  877. param_index = block_dst->param_count - 1 - i;
  878. POP(value_param, block_dst->param_types[param_index]);
  879. ADD_TO_PARAM_PHIS(block_dst, value_param, param_index);
  880. }
  881. BUILD_BR(block_dst->llvm_entry_block);
  882. }
  883. else {
  884. /* Dest block is Block/If/Function block */
  885. /* Create the end block */
  886. if (!block_dst->llvm_end_block) {
  887. format_block_name(name, sizeof(name), block_dst->block_index,
  888. block_dst->label_type, LABEL_END);
  889. CREATE_BLOCK(block_dst->llvm_end_block, name);
  890. if ((next_llvm_end_block = find_next_llvm_end_block(block_dst)))
  891. MOVE_BLOCK_BEFORE(block_dst->llvm_end_block,
  892. next_llvm_end_block);
  893. }
  894. block_dst->is_reachable = true;
  895. /* Handle result values */
  896. CREATE_RESULT_VALUE_PHIS(block_dst);
  897. for (i = 0; i < block_dst->result_count; i++) {
  898. result_index = block_dst->result_count - 1 - i;
  899. POP(value_ret, block_dst->result_types[result_index]);
  900. ADD_TO_RESULT_PHIS(block_dst, value_ret, result_index);
  901. }
  902. /* Jump to the end block */
  903. BUILD_BR(block_dst->llvm_end_block);
  904. }
  905. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  906. fail:
  907. return false;
  908. }
  909. static bool
  910. aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  911. uint32 br_depth, LLVMValueRef value_cmp,
  912. uint8 **p_frame_ip)
  913. {
  914. AOTBlock *block_dst;
  915. LLVMValueRef value, *values = NULL;
  916. LLVMBasicBlockRef llvm_else_block, next_llvm_end_block;
  917. char name[32];
  918. uint32 i, param_index, result_index;
  919. uint64 size;
  920. if (!(block_dst = get_target_block(func_ctx, br_depth))) {
  921. return false;
  922. }
  923. if (comp_ctx->aot_frame) {
  924. if (comp_ctx->enable_gc && !aot_gen_commit_values(comp_ctx->aot_frame))
  925. return false;
  926. if (block_dst->label_type == LABEL_TYPE_LOOP) {
  927. if (comp_ctx->enable_thread_mgr) {
  928. /* Commit sp when GC is enabled, don't commit ip */
  929. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame,
  930. comp_ctx->enable_gc, false))
  931. return false;
  932. }
  933. }
  934. else {
  935. if (comp_ctx->aot_frame->sp > block_dst->frame_sp_max_reached)
  936. block_dst->frame_sp_max_reached = comp_ctx->aot_frame->sp;
  937. }
  938. }
  939. /* Terminate or suspend current thread only when this is
  940. a backward jump */
  941. if (comp_ctx->enable_thread_mgr
  942. && block_dst->label_type == LABEL_TYPE_LOOP) {
  943. if (!check_suspend_flags(comp_ctx, func_ctx, true))
  944. return false;
  945. }
  946. if (LLVMIsUndef(value_cmp)
  947. #if LLVM_VERSION_NUMBER >= 12
  948. || LLVMIsPoison(value_cmp)
  949. #endif
  950. ) {
  951. if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INTEGER_OVERFLOW,
  952. false, NULL, NULL))) {
  953. goto fail;
  954. }
  955. return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  956. }
  957. if (!LLVMIsEfficientConstInt(value_cmp)) {
  958. /* Compare value is not constant, create condition br IR */
  959. /* Create llvm else block */
  960. CREATE_BLOCK(llvm_else_block, "br_if_else");
  961. MOVE_BLOCK_AFTER_CURR(llvm_else_block);
  962. if (block_dst->label_type == LABEL_TYPE_LOOP) {
  963. /* Dest block is Loop block */
  964. /* Handle Loop parameters */
  965. if (block_dst->param_count) {
  966. size = sizeof(LLVMValueRef) * (uint64)block_dst->param_count;
  967. if (size >= UINT32_MAX
  968. || !(values = wasm_runtime_malloc((uint32)size))) {
  969. aot_set_last_error("allocate memory failed.");
  970. goto fail;
  971. }
  972. for (i = 0; i < block_dst->param_count; i++) {
  973. param_index = block_dst->param_count - 1 - i;
  974. POP(value, block_dst->param_types[param_index]);
  975. ADD_TO_PARAM_PHIS(block_dst, value, param_index);
  976. values[param_index] = value;
  977. }
  978. for (i = 0; i < block_dst->param_count; i++) {
  979. PUSH(values[i], block_dst->param_types[i]);
  980. }
  981. wasm_runtime_free(values);
  982. values = NULL;
  983. }
  984. BUILD_COND_BR(value_cmp, block_dst->llvm_entry_block,
  985. llvm_else_block);
  986. /* Move builder to else block */
  987. SET_BUILDER_POS(llvm_else_block);
  988. }
  989. else {
  990. /* Dest block is Block/If/Function block */
  991. /* Create the end block */
  992. if (!block_dst->llvm_end_block) {
  993. format_block_name(name, sizeof(name), block_dst->block_index,
  994. block_dst->label_type, LABEL_END);
  995. CREATE_BLOCK(block_dst->llvm_end_block, name);
  996. if ((next_llvm_end_block = find_next_llvm_end_block(block_dst)))
  997. MOVE_BLOCK_BEFORE(block_dst->llvm_end_block,
  998. next_llvm_end_block);
  999. }
  1000. /* Set reachable flag and create condition br IR */
  1001. block_dst->is_reachable = true;
  1002. /* Handle result values */
  1003. if (block_dst->result_count) {
  1004. size = sizeof(LLVMValueRef) * (uint64)block_dst->result_count;
  1005. if (size >= UINT32_MAX
  1006. || !(values = wasm_runtime_malloc((uint32)size))) {
  1007. aot_set_last_error("allocate memory failed.");
  1008. goto fail;
  1009. }
  1010. CREATE_RESULT_VALUE_PHIS(block_dst);
  1011. for (i = 0; i < block_dst->result_count; i++) {
  1012. result_index = block_dst->result_count - 1 - i;
  1013. POP(value, block_dst->result_types[result_index]);
  1014. values[result_index] = value;
  1015. ADD_TO_RESULT_PHIS(block_dst, value, result_index);
  1016. }
  1017. for (i = 0; i < block_dst->result_count; i++) {
  1018. PUSH(values[i], block_dst->result_types[i]);
  1019. }
  1020. wasm_runtime_free(values);
  1021. values = NULL;
  1022. }
  1023. /* Condition jump to end block */
  1024. BUILD_COND_BR(value_cmp, block_dst->llvm_end_block,
  1025. llvm_else_block);
  1026. /* Move builder to else block */
  1027. SET_BUILDER_POS(llvm_else_block);
  1028. }
  1029. }
  1030. else {
  1031. if ((int32)LLVMConstIntGetZExtValue(value_cmp) != 0) {
  1032. /* Compare value is not 0, condition is true, same as op_br */
  1033. return aot_compile_op_br(comp_ctx, func_ctx, br_depth, p_frame_ip);
  1034. }
  1035. else {
  1036. /* Compare value is not 0, condition is false, skip br_if */
  1037. return true;
  1038. }
  1039. }
  1040. return true;
  1041. fail:
  1042. if (values)
  1043. wasm_runtime_free(values);
  1044. return false;
  1045. }
  1046. bool
  1047. aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  1048. uint32 br_depth, uint8 **p_frame_ip)
  1049. {
  1050. LLVMValueRef value_cmp;
  1051. POP_COND(value_cmp);
  1052. return aot_compile_conditional_br(comp_ctx, func_ctx, br_depth, value_cmp,
  1053. p_frame_ip);
  1054. fail:
  1055. return false;
  1056. }
  1057. bool
  1058. aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  1059. uint32 *br_depths, uint32 br_count, uint8 **p_frame_ip)
  1060. {
  1061. uint32 i, j;
  1062. LLVMValueRef value_switch, value_cmp, value_case, value, *values = NULL;
  1063. LLVMBasicBlockRef default_llvm_block = NULL, target_llvm_block;
  1064. LLVMBasicBlockRef next_llvm_end_block;
  1065. AOTBlock *target_block;
  1066. uint32 br_depth, depth_idx;
  1067. uint32 param_index, result_index;
  1068. uint64 size;
  1069. char name[32];
  1070. POP_I32(value_cmp);
  1071. if (LLVMIsUndef(value_cmp)
  1072. #if LLVM_VERSION_NUMBER >= 12
  1073. || LLVMIsPoison(value_cmp)
  1074. #endif
  1075. ) {
  1076. if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INTEGER_OVERFLOW,
  1077. false, NULL, NULL))) {
  1078. goto fail;
  1079. }
  1080. return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  1081. }
  1082. /*
  1083. * if (value_cmp > br_count)
  1084. * value_cmp = br_count;
  1085. */
  1086. LLVMValueRef br_count_value = I32_CONST(br_count);
  1087. CHECK_LLVM_CONST(br_count_value);
  1088. LLVMValueRef clap_value_cmp_cond =
  1089. LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, value_cmp, br_count_value,
  1090. "cmp_w_br_count");
  1091. if (!clap_value_cmp_cond) {
  1092. aot_set_last_error("llvm build icmp failed.");
  1093. return false;
  1094. }
  1095. value_cmp = LLVMBuildSelect(comp_ctx->builder, clap_value_cmp_cond,
  1096. br_count_value, value_cmp, "clap_value_cmp");
  1097. if (!value_cmp) {
  1098. aot_set_last_error("llvm build select failed.");
  1099. return false;
  1100. }
  1101. if (!LLVMIsEfficientConstInt(value_cmp)) {
  1102. if (comp_ctx->aot_frame) {
  1103. if (comp_ctx->enable_gc
  1104. && !aot_gen_commit_values(comp_ctx->aot_frame))
  1105. return false;
  1106. if (comp_ctx->enable_thread_mgr) {
  1107. /* Commit sp when GC is enabled, don't commit ip */
  1108. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame,
  1109. comp_ctx->enable_gc, false))
  1110. return false;
  1111. }
  1112. for (i = 0; i <= br_count; i++) {
  1113. target_block = get_target_block(func_ctx, br_depths[i]);
  1114. if (!target_block)
  1115. return false;
  1116. if (target_block->label_type != LABEL_TYPE_LOOP) {
  1117. if (comp_ctx->aot_frame->sp
  1118. > target_block->frame_sp_max_reached)
  1119. target_block->frame_sp_max_reached =
  1120. comp_ctx->aot_frame->sp;
  1121. }
  1122. }
  1123. }
  1124. if (comp_ctx->enable_thread_mgr) {
  1125. for (i = 0; i <= br_count; i++) {
  1126. target_block = get_target_block(func_ctx, br_depths[i]);
  1127. if (!target_block)
  1128. return false;
  1129. /* Terminate or suspend current thread only when this is a
  1130. backward jump */
  1131. if (target_block->label_type == LABEL_TYPE_LOOP) {
  1132. if (!check_suspend_flags(comp_ctx, func_ctx, true))
  1133. return false;
  1134. break;
  1135. }
  1136. }
  1137. }
  1138. /* Compare value is not constant, create switch IR */
  1139. for (i = 0; i <= br_count; i++) {
  1140. target_block = get_target_block(func_ctx, br_depths[i]);
  1141. if (!target_block)
  1142. return false;
  1143. if (target_block->label_type != LABEL_TYPE_LOOP) {
  1144. /* Dest block is Block/If/Function block */
  1145. /* Create the end block */
  1146. if (!target_block->llvm_end_block) {
  1147. format_block_name(name, sizeof(name),
  1148. target_block->block_index,
  1149. target_block->label_type, LABEL_END);
  1150. CREATE_BLOCK(target_block->llvm_end_block, name);
  1151. if ((next_llvm_end_block =
  1152. find_next_llvm_end_block(target_block)))
  1153. MOVE_BLOCK_BEFORE(target_block->llvm_end_block,
  1154. next_llvm_end_block);
  1155. }
  1156. /* Handle result values */
  1157. if (target_block->result_count) {
  1158. size = sizeof(LLVMValueRef)
  1159. * (uint64)target_block->result_count;
  1160. if (size >= UINT32_MAX
  1161. || !(values = wasm_runtime_malloc((uint32)size))) {
  1162. aot_set_last_error("allocate memory failed.");
  1163. goto fail;
  1164. }
  1165. CREATE_RESULT_VALUE_PHIS(target_block);
  1166. for (j = 0; j < target_block->result_count; j++) {
  1167. result_index = target_block->result_count - 1 - j;
  1168. POP(value, target_block->result_types[result_index]);
  1169. values[result_index] = value;
  1170. ADD_TO_RESULT_PHIS(target_block, value, result_index);
  1171. }
  1172. for (j = 0; j < target_block->result_count; j++) {
  1173. PUSH(values[j], target_block->result_types[j]);
  1174. }
  1175. wasm_runtime_free(values);
  1176. values = NULL;
  1177. }
  1178. target_block->is_reachable = true;
  1179. if (i == br_count)
  1180. default_llvm_block = target_block->llvm_end_block;
  1181. }
  1182. else {
  1183. /* Handle Loop parameters */
  1184. if (target_block->param_count) {
  1185. size = sizeof(LLVMValueRef)
  1186. * (uint64)target_block->param_count;
  1187. if (size >= UINT32_MAX
  1188. || !(values = wasm_runtime_malloc((uint32)size))) {
  1189. aot_set_last_error("allocate memory failed.");
  1190. goto fail;
  1191. }
  1192. for (j = 0; j < target_block->param_count; j++) {
  1193. param_index = target_block->param_count - 1 - j;
  1194. POP(value, target_block->param_types[param_index]);
  1195. values[param_index] = value;
  1196. ADD_TO_PARAM_PHIS(target_block, value, param_index);
  1197. }
  1198. for (j = 0; j < target_block->param_count; j++) {
  1199. PUSH(values[j], target_block->param_types[j]);
  1200. }
  1201. wasm_runtime_free(values);
  1202. values = NULL;
  1203. }
  1204. if (i == br_count)
  1205. default_llvm_block = target_block->llvm_entry_block;
  1206. }
  1207. }
  1208. /* Create switch IR */
  1209. if (!(value_switch = LLVMBuildSwitch(comp_ctx->builder, value_cmp,
  1210. default_llvm_block, br_count))) {
  1211. aot_set_last_error("llvm build switch failed.");
  1212. return false;
  1213. }
  1214. /* Add each case for switch IR */
  1215. for (i = 0; i < br_count; i++) {
  1216. value_case = I32_CONST(i);
  1217. CHECK_LLVM_CONST(value_case);
  1218. target_block = get_target_block(func_ctx, br_depths[i]);
  1219. if (!target_block)
  1220. return false;
  1221. target_llvm_block = target_block->label_type != LABEL_TYPE_LOOP
  1222. ? target_block->llvm_end_block
  1223. : target_block->llvm_entry_block;
  1224. LLVMAddCase(value_switch, value_case, target_llvm_block);
  1225. }
  1226. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  1227. }
  1228. else {
  1229. /* Compare value is constant, create br IR */
  1230. depth_idx = (uint32)LLVMConstIntGetZExtValue(value_cmp);
  1231. br_depth = br_depths[br_count];
  1232. if (depth_idx < br_count) {
  1233. br_depth = br_depths[depth_idx];
  1234. }
  1235. return aot_compile_op_br(comp_ctx, func_ctx, br_depth, p_frame_ip);
  1236. }
  1237. fail:
  1238. if (values)
  1239. wasm_runtime_free(values);
  1240. return false;
  1241. }
  1242. bool
  1243. aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  1244. uint8 **p_frame_ip)
  1245. {
  1246. AOTBlock *block_func = func_ctx->block_stack.block_list_head;
  1247. LLVMValueRef value;
  1248. LLVMValueRef ret;
  1249. AOTFuncType *func_type;
  1250. uint32 i, param_index, result_index;
  1251. #if WASM_ENABLE_DEBUG_AOT != 0
  1252. LLVMMetadataRef return_location;
  1253. #endif
  1254. bh_assert(block_func);
  1255. func_type = func_ctx->aot_func->func_type;
  1256. #if WASM_ENABLE_DEBUG_AOT != 0
  1257. return_location = dwarf_gen_location(
  1258. comp_ctx, func_ctx,
  1259. (*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code);
  1260. #endif
  1261. if (comp_ctx->aux_stack_frame_type
  1262. && comp_ctx->call_stack_features.frame_per_function
  1263. && !aot_free_frame_per_function_frame_for_aot_func(comp_ctx,
  1264. func_ctx)) {
  1265. return false;
  1266. }
  1267. if (block_func->result_count) {
  1268. /* Store extra result values to function parameters */
  1269. for (i = 0; i < block_func->result_count - 1; i++) {
  1270. LLVMValueRef res;
  1271. result_index = block_func->result_count - 1 - i;
  1272. POP(value, block_func->result_types[result_index]);
  1273. param_index = func_type->param_count + result_index;
  1274. if (!(res = LLVMBuildStore(
  1275. comp_ctx->builder, value,
  1276. LLVMGetParam(func_ctx->func, param_index)))) {
  1277. aot_set_last_error("llvm build store failed.");
  1278. goto fail;
  1279. }
  1280. LLVMSetAlignment(res, 1);
  1281. }
  1282. /* Return the first result value */
  1283. POP(value, block_func->result_types[0]);
  1284. if (!(ret = LLVMBuildRet(comp_ctx->builder, value))) {
  1285. aot_set_last_error("llvm build return failed.");
  1286. goto fail;
  1287. }
  1288. #if WASM_ENABLE_DEBUG_AOT != 0
  1289. LLVMInstructionSetDebugLoc(ret, return_location);
  1290. #endif
  1291. }
  1292. else {
  1293. if (!(ret = LLVMBuildRetVoid(comp_ctx->builder))) {
  1294. aot_set_last_error("llvm build return void failed.");
  1295. goto fail;
  1296. }
  1297. #if WASM_ENABLE_DEBUG_AOT != 0
  1298. LLVMInstructionSetDebugLoc(ret, return_location);
  1299. #endif
  1300. }
  1301. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  1302. fail:
  1303. return false;
  1304. }
  1305. bool
  1306. aot_compile_op_unreachable(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  1307. uint8 **p_frame_ip)
  1308. {
  1309. if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_UNREACHABLE, false, NULL,
  1310. NULL))
  1311. return false;
  1312. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  1313. }
  1314. bool
  1315. aot_handle_next_reachable_block(AOTCompContext *comp_ctx,
  1316. AOTFuncContext *func_ctx, uint8 **p_frame_ip)
  1317. {
  1318. return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
  1319. }
  1320. #if WASM_ENABLE_GC != 0
  1321. static bool
  1322. commit_gc_and_check_suspend_flags(AOTCompContext *comp_ctx,
  1323. AOTFuncContext *func_ctx, uint32 br_depth)
  1324. {
  1325. AOTBlock *block_dst;
  1326. if (!(block_dst = get_target_block(func_ctx, br_depth))) {
  1327. return false;
  1328. }
  1329. if (comp_ctx->aot_frame) {
  1330. /* Note that GC is enabled, no need to check it again */
  1331. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  1332. return false;
  1333. if (block_dst->label_type == LABEL_TYPE_LOOP) {
  1334. if (comp_ctx->enable_thread_mgr) {
  1335. /* Note that GC is enabled, no need to check it again */
  1336. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, false))
  1337. return false;
  1338. }
  1339. }
  1340. else {
  1341. if (comp_ctx->aot_frame->sp > block_dst->frame_sp_max_reached)
  1342. block_dst->frame_sp_max_reached = comp_ctx->aot_frame->sp;
  1343. }
  1344. }
  1345. /* Terminate or suspend current thread only when this is
  1346. a backward jump */
  1347. if (comp_ctx->enable_thread_mgr
  1348. && block_dst->label_type == LABEL_TYPE_LOOP) {
  1349. if (!check_suspend_flags(comp_ctx, func_ctx, true))
  1350. return false;
  1351. }
  1352. return true;
  1353. }
  1354. static bool
  1355. compile_gc_cond_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  1356. uint32 br_depth, LLVMValueRef value_cmp)
  1357. {
  1358. AOTBlock *block_dst;
  1359. LLVMValueRef value, *values = NULL;
  1360. LLVMBasicBlockRef llvm_else_block, next_llvm_end_block;
  1361. char name[32];
  1362. uint32 i, param_index, result_index;
  1363. uint64 size;
  1364. if (!(block_dst = get_target_block(func_ctx, br_depth))) {
  1365. return false;
  1366. }
  1367. /* Create llvm else block */
  1368. CREATE_BLOCK(llvm_else_block, "br_if_else");
  1369. MOVE_BLOCK_AFTER_CURR(llvm_else_block);
  1370. if (block_dst->label_type == LABEL_TYPE_LOOP) {
  1371. /* Dest block is Loop block */
  1372. /* Handle Loop parameters */
  1373. if (block_dst->param_count) {
  1374. size = sizeof(LLVMValueRef) * (uint64)block_dst->param_count;
  1375. if (size >= UINT32_MAX
  1376. || !(values = wasm_runtime_malloc((uint32)size))) {
  1377. aot_set_last_error("allocate memory failed.");
  1378. goto fail;
  1379. }
  1380. for (i = 0; i < block_dst->param_count; i++) {
  1381. param_index = block_dst->param_count - 1 - i;
  1382. POP(value, block_dst->param_types[param_index]);
  1383. ADD_TO_PARAM_PHIS(block_dst, value, param_index);
  1384. values[param_index] = value;
  1385. }
  1386. for (i = 0; i < block_dst->param_count; i++) {
  1387. PUSH(values[i], block_dst->param_types[i]);
  1388. }
  1389. wasm_runtime_free(values);
  1390. values = NULL;
  1391. }
  1392. BUILD_COND_BR(value_cmp, block_dst->llvm_entry_block, llvm_else_block);
  1393. /* Move builder to else block */
  1394. SET_BUILDER_POS(llvm_else_block);
  1395. }
  1396. else {
  1397. /* Dest block is Block/If/Function block */
  1398. /* Create the end block */
  1399. if (!block_dst->llvm_end_block) {
  1400. format_block_name(name, sizeof(name), block_dst->block_index,
  1401. block_dst->label_type, LABEL_END);
  1402. CREATE_BLOCK(block_dst->llvm_end_block, name);
  1403. if ((next_llvm_end_block = find_next_llvm_end_block(block_dst)))
  1404. MOVE_BLOCK_BEFORE(block_dst->llvm_end_block,
  1405. next_llvm_end_block);
  1406. }
  1407. /* Set reachable flag and create condition br IR */
  1408. block_dst->is_reachable = true;
  1409. /* Handle result values */
  1410. if (block_dst->result_count) {
  1411. size = sizeof(LLVMValueRef) * (uint64)block_dst->result_count;
  1412. if (size >= UINT32_MAX
  1413. || !(values = wasm_runtime_malloc((uint32)size))) {
  1414. aot_set_last_error("allocate memory failed.");
  1415. goto fail;
  1416. }
  1417. CREATE_RESULT_VALUE_PHIS(block_dst);
  1418. for (i = 0; i < block_dst->result_count; i++) {
  1419. result_index = block_dst->result_count - 1 - i;
  1420. POP(value, block_dst->result_types[result_index]);
  1421. values[result_index] = value;
  1422. ADD_TO_RESULT_PHIS(block_dst, value, result_index);
  1423. }
  1424. for (i = 0; i < block_dst->result_count; i++) {
  1425. PUSH(values[i], block_dst->result_types[i]);
  1426. }
  1427. wasm_runtime_free(values);
  1428. values = NULL;
  1429. }
  1430. /* Condition jump to end block */
  1431. BUILD_COND_BR(value_cmp, block_dst->llvm_end_block, llvm_else_block);
  1432. /* Move builder to else block */
  1433. SET_BUILDER_POS(llvm_else_block);
  1434. }
  1435. return true;
  1436. fail:
  1437. if (values)
  1438. wasm_runtime_free(values);
  1439. return false;
  1440. }
  1441. bool
  1442. aot_compile_op_br_on_null(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  1443. uint32 br_depth, uint8 **p_frame_ip)
  1444. {
  1445. LLVMValueRef gc_obj, value_cmp;
  1446. if (!commit_gc_and_check_suspend_flags(comp_ctx, func_ctx, br_depth)) {
  1447. return false;
  1448. }
  1449. POP_GC_REF(gc_obj);
  1450. if (!(value_cmp =
  1451. LLVMBuildIsNull(comp_ctx->builder, gc_obj, "cmp_gc_obj"))) {
  1452. aot_set_last_error("llvm build isnull failed.");
  1453. goto fail;
  1454. }
  1455. if (!compile_gc_cond_br(comp_ctx, func_ctx, br_depth, value_cmp)) {
  1456. goto fail;
  1457. }
  1458. PUSH_GC_REF(gc_obj);
  1459. return true;
  1460. fail:
  1461. return false;
  1462. }
  1463. bool
  1464. aot_compile_op_br_on_non_null(AOTCompContext *comp_ctx,
  1465. AOTFuncContext *func_ctx, uint32 br_depth,
  1466. uint8 **p_frame_ip)
  1467. {
  1468. LLVMValueRef gc_obj, value_cmp;
  1469. if (!commit_gc_and_check_suspend_flags(comp_ctx, func_ctx, br_depth)) {
  1470. return false;
  1471. }
  1472. GET_GC_REF_FROM_STACK(gc_obj);
  1473. if (!(value_cmp =
  1474. LLVMBuildIsNotNull(comp_ctx->builder, gc_obj, "cmp_gc_obj"))) {
  1475. aot_set_last_error("llvm build isnotnull failed.");
  1476. goto fail;
  1477. }
  1478. if (!compile_gc_cond_br(comp_ctx, func_ctx, br_depth, value_cmp)) {
  1479. goto fail;
  1480. }
  1481. POP_GC_REF(gc_obj);
  1482. return true;
  1483. fail:
  1484. return false;
  1485. }
  1486. bool
  1487. aot_compile_op_br_on_cast(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  1488. int32 heap_type, bool nullable, bool br_on_fail,
  1489. uint32 br_depth, uint8 **p_frame_ip)
  1490. {
  1491. LLVMValueRef gc_obj, is_null, castable, not_castable, br_if_phi;
  1492. LLVMBasicBlockRef block_curr, block_non_null, block_br_if;
  1493. if (!commit_gc_and_check_suspend_flags(comp_ctx, func_ctx, br_depth)) {
  1494. return false;
  1495. }
  1496. GET_GC_REF_FROM_STACK(gc_obj);
  1497. block_curr = CURR_BLOCK();
  1498. CREATE_BLOCK(block_non_null, "obj_non_null");
  1499. MOVE_BLOCK_AFTER_CURR(block_non_null);
  1500. CREATE_BLOCK(block_br_if, "br_if");
  1501. MOVE_BLOCK_AFTER(block_br_if, block_non_null);
  1502. SET_BUILDER_POS(block_br_if);
  1503. if (!(br_if_phi =
  1504. LLVMBuildPhi(comp_ctx->builder, INT1_TYPE, "br_if_phi"))) {
  1505. aot_set_last_error("llvm build phi failed.");
  1506. goto fail;
  1507. }
  1508. SET_BUILDER_POS(block_curr);
  1509. if (!(is_null = LLVMBuildIsNull(comp_ctx->builder, gc_obj, "is_null"))) {
  1510. aot_set_last_error("llvm build isnull failed.");
  1511. goto fail;
  1512. }
  1513. BUILD_COND_BR(is_null, block_br_if, block_non_null);
  1514. if ((!br_on_fail && nullable) || (br_on_fail && !nullable)) {
  1515. LLVMAddIncoming(br_if_phi, &I1_ONE, &block_curr, 1);
  1516. }
  1517. else { /* (!br_on_fail && !nullable) || (br_on_fail && nullable)) */
  1518. LLVMAddIncoming(br_if_phi, &I1_ZERO, &block_curr, 1);
  1519. }
  1520. SET_BUILDER_POS(block_non_null);
  1521. if (heap_type >= 0) {
  1522. if (!aot_call_aot_obj_is_instance_of(comp_ctx, func_ctx, gc_obj,
  1523. I32_CONST(heap_type), &castable))
  1524. goto fail;
  1525. }
  1526. else {
  1527. if (!aot_call_wasm_obj_is_type_of(comp_ctx, func_ctx, gc_obj,
  1528. I32_CONST(heap_type), &castable))
  1529. goto fail;
  1530. }
  1531. if (!br_on_fail) {
  1532. if (!(castable = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, castable,
  1533. I8_ZERO, "castable"))) {
  1534. aot_set_last_error("llvm build icmp failed.");
  1535. return false;
  1536. }
  1537. LLVMAddIncoming(br_if_phi, &castable, &block_non_null, 1);
  1538. }
  1539. else {
  1540. if (!(not_castable = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ,
  1541. castable, I8_ZERO, "castable"))) {
  1542. aot_set_last_error("llvm build icmp failed.");
  1543. return false;
  1544. }
  1545. LLVMAddIncoming(br_if_phi, &not_castable, &block_non_null, 1);
  1546. }
  1547. BUILD_BR(block_br_if);
  1548. SET_BUILDER_POS(block_br_if);
  1549. if (!compile_gc_cond_br(comp_ctx, func_ctx, br_depth, br_if_phi)) {
  1550. goto fail;
  1551. }
  1552. return true;
  1553. fail:
  1554. return false;
  1555. }
  1556. #endif /* End of WASM_ENABLE_GC != 0 */