| ... | ... | @@ -1406,7 +1406,8 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in |
| 1406 | 1406 | } |
| 1407 | 1407 | |
| 1408 | 1408 | static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1409 | | size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values) |
| 1409 | size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values, |
| 1410 | ResultLocPeerParent *peer_parent) |
| 1410 | 1411 | { |
| 1411 | 1412 | assert(incoming_count != 0); |
| 1412 | 1413 | assert(incoming_count != SIZE_MAX); |
| ... | ... | @@ -1415,6 +1416,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source |
| 1415 | 1416 | phi_instruction->incoming_count = incoming_count; |
| 1416 | 1417 | phi_instruction->incoming_blocks = incoming_blocks; |
| 1417 | 1418 | phi_instruction->incoming_values = incoming_values; |
| 1419 | phi_instruction->peer_parent = peer_parent; |
| 1418 | 1420 | |
| 1419 | 1421 | for (size_t i = 0; i < incoming_count; i += 1) { |
| 1420 | 1422 | ir_ref_bb(incoming_blocks[i]); |
| ... | ... | @@ -3700,7 +3702,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3700 | 3702 | } |
| 3701 | 3703 | |
| 3702 | 3704 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); |
| 3703 | | return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 3705 | return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, |
| 3706 | incoming_blocks.items, incoming_values.items, nullptr); |
| 3704 | 3707 | } else { |
| 3705 | 3708 | incoming_blocks.append(irb->current_basic_block); |
| 3706 | 3709 | incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node))); |
| ... | ... | @@ -3710,7 +3713,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3710 | 3713 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3711 | 3714 | ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); |
| 3712 | 3715 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); |
| 3713 | | return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 3716 | return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, |
| 3717 | incoming_blocks.items, incoming_values.items, nullptr); |
| 3714 | 3718 | } else { |
| 3715 | 3719 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3716 | 3720 | return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node))); |
| ... | ... | @@ -3795,7 +3799,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node |
| 3795 | 3799 | incoming_blocks[0] = post_val1_block; |
| 3796 | 3800 | incoming_blocks[1] = post_val2_block; |
| 3797 | 3801 | |
| 3798 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 3802 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 3799 | 3803 | } |
| 3800 | 3804 | |
| 3801 | 3805 | static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -3837,7 +3841,7 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod |
| 3837 | 3841 | incoming_blocks[0] = post_val1_block; |
| 3838 | 3842 | incoming_blocks[1] = post_val2_block; |
| 3839 | 3843 | |
| 3840 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 3844 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 3841 | 3845 | } |
| 3842 | 3846 | |
| 3843 | 3847 | static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_inst, |
| ... | ... | @@ -3911,7 +3915,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3911 | 3915 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 3912 | 3916 | incoming_blocks[0] = after_null_block; |
| 3913 | 3917 | incoming_blocks[1] = after_ok_block; |
| 3914 | | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 3918 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 3915 | 3919 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 3916 | 3920 | } |
| 3917 | 3921 | |
| ... | ... | @@ -5427,7 +5431,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5427 | 5431 | incoming_blocks[0] = after_then_block; |
| 5428 | 5432 | incoming_blocks[1] = after_else_block; |
| 5429 | 5433 | |
| 5430 | | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 5434 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 5431 | 5435 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5432 | 5436 | } |
| 5433 | 5437 | |
| ... | ... | @@ -5468,9 +5472,10 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction * |
| 5468 | 5472 | // We needed a pointer to a value, but we got a value. So we create |
| 5469 | 5473 | // an instruction which just makes a pointer of it. |
| 5470 | 5474 | return ir_build_ref(irb, scope, value->source_node, value, false, false); |
| 5475 | } else { |
| 5476 | return ir_expr_wrap(irb, scope, value, result_loc); |
| 5471 | 5477 | } |
| 5472 | 5478 | |
| 5473 | | return ir_expr_wrap(irb, scope, value, result_loc); |
| 5474 | 5479 | } |
| 5475 | 5480 | |
| 5476 | 5481 | static PtrLen star_token_to_ptr_len(TokenId token_id) { |
| ... | ... | @@ -5931,7 +5936,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5931 | 5936 | incoming_values.append(void_else_result); |
| 5932 | 5937 | } |
| 5933 | 5938 | |
| 5934 | | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 5939 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 5940 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 5935 | 5941 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5936 | 5942 | } else if (var_symbol != nullptr) { |
| 5937 | 5943 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| ... | ... | @@ -6022,7 +6028,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6022 | 6028 | incoming_values.append(void_else_result); |
| 6023 | 6029 | } |
| 6024 | 6030 | |
| 6025 | | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6031 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6032 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6026 | 6033 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6027 | 6034 | } else { |
| 6028 | 6035 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| ... | ... | @@ -6100,7 +6107,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6100 | 6107 | incoming_values.append(void_else_result); |
| 6101 | 6108 | } |
| 6102 | 6109 | |
| 6103 | | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6110 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6111 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6104 | 6112 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6105 | 6113 | } |
| 6106 | 6114 | } |
| ... | ... | @@ -6230,7 +6238,8 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 6230 | 6238 | incoming_values.append(void_else_value); |
| 6231 | 6239 | } |
| 6232 | 6240 | |
| 6233 | | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6241 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, |
| 6242 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6234 | 6243 | return ir_expr_wrap(irb, parent_scope, phi, result_loc); |
| 6235 | 6244 | } |
| 6236 | 6245 | |
| ... | ... | @@ -6595,7 +6604,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6595 | 6604 | incoming_blocks[0] = after_then_block; |
| 6596 | 6605 | incoming_blocks[1] = after_else_block; |
| 6597 | 6606 | |
| 6598 | | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 6607 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 6599 | 6608 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6600 | 6609 | } |
| 6601 | 6610 | |
| ... | ... | @@ -6690,7 +6699,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6690 | 6699 | incoming_blocks[0] = after_then_block; |
| 6691 | 6700 | incoming_blocks[1] = after_else_block; |
| 6692 | 6701 | |
| 6693 | | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 6702 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 6694 | 6703 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6695 | 6704 | } |
| 6696 | 6705 | |
| ... | ... | @@ -6985,7 +6994,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6985 | 6994 | if (incoming_blocks.length == 0) { |
| 6986 | 6995 | result_instruction = ir_build_const_void(irb, scope, node); |
| 6987 | 6996 | } else { |
| 6988 | | result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6997 | result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6998 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6989 | 6999 | } |
| 6990 | 7000 | return ir_expr_wrap(irb, scope, result_instruction, result_loc); |
| 6991 | 7001 | } |
| ... | ... | @@ -7273,7 +7283,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 7273 | 7283 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 7274 | 7284 | incoming_blocks[0] = after_err_block; |
| 7275 | 7285 | incoming_blocks[1] = after_ok_block; |
| 7276 | | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 7286 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 7277 | 7287 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 7278 | 7288 | } |
| 7279 | 7289 | |
| ... | ... | @@ -7958,7 +7968,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7958 | 7968 | incoming_values[0] = const_bool_true; |
| 7959 | 7969 | incoming_blocks[1] = post_cancel_awaiter_block; |
| 7960 | 7970 | incoming_values[1] = const_bool_false; |
| 7961 | | IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 7971 | IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, |
| 7972 | nullptr); |
| 7962 | 7973 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); |
| 7963 | 7974 | ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false)); |
| 7964 | 7975 | |
| ... | ... | @@ -8080,7 +8091,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 8080 | 8091 | case NodeTypeContinue: |
| 8081 | 8092 | return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); |
| 8082 | 8093 | case NodeTypeUnreachable: |
| 8083 | | return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval, result_loc); |
| 8094 | return ir_build_unreachable(irb, scope, node); |
| 8084 | 8095 | case NodeTypeDefer: |
| 8085 | 8096 | return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); |
| 8086 | 8097 | case NodeTypeSliceExpr: |
| ... | ... | @@ -8337,7 +8348,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8337 | 8348 | incoming_values[0] = const_bool_false; |
| 8338 | 8349 | incoming_blocks[1] = irb->exec->coro_normal_final; |
| 8339 | 8350 | incoming_values[1] = const_bool_true; |
| 8340 | | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 8351 | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 8341 | 8352 | |
| 8342 | 8353 | IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); |
| 8343 | 8354 | IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); |
| ... | ... | @@ -8345,7 +8356,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8345 | 8356 | merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); |
| 8346 | 8357 | merge_incoming_blocks[1] = irb->exec->coro_normal_final; |
| 8347 | 8358 | merge_incoming_values[1] = await_handle_in_block; |
| 8348 | | IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values); |
| 8359 | IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values, nullptr); |
| 8349 | 8360 | |
| 8350 | 8361 | Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME); |
| 8351 | 8362 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, |
| ... | ... | @@ -10737,16 +10748,27 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons |
| 10737 | 10748 | static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, |
| 10738 | 10749 | IrSuspendPosition *suspend_pos) |
| 10739 | 10750 | { |
| 10751 | // reserve block position |
| 10752 | if (!ira->new_irb.current_basic_block->already_appended) { |
| 10753 | ira->new_irb.current_basic_block->already_appended = true; |
| 10754 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| 10755 | } |
| 10756 | |
| 10740 | 10757 | suspend_pos->basic_block_index = ira->old_bb_index; |
| 10741 | 10758 | suspend_pos->instruction_index = ira->instruction_index; |
| 10742 | 10759 | |
| 10743 | | ira->old_bb_index = next_bb->index; |
| 10744 | | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 10745 | | assert(ira->old_irb.current_basic_block == next_bb); |
| 10746 | | ira->instruction_index = 0; |
| 10747 | | ira->const_predecessor_bb = nullptr; |
| 10748 | | next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction); |
| 10749 | | ira->new_irb.current_basic_block = next_bb->other; |
| 10760 | ira->old_irb.current_basic_block->suspended = true; |
| 10761 | |
| 10762 | // null next_bb means that the caller plans to call ira_resume before returning |
| 10763 | if (next_bb != nullptr) { |
| 10764 | ira->old_bb_index = next_bb->index; |
| 10765 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 10766 | assert(ira->old_irb.current_basic_block == next_bb); |
| 10767 | ira->instruction_index = 0; |
| 10768 | ira->const_predecessor_bb = nullptr; |
| 10769 | next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction); |
| 10770 | ira->new_irb.current_basic_block = next_bb->other; |
| 10771 | } |
| 10750 | 10772 | return ira->codegen->unreach_instruction; |
| 10751 | 10773 | } |
| 10752 | 10774 | |
| ... | ... | @@ -10754,6 +10776,7 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 10754 | 10776 | IrSuspendPosition pos = ira->resume_stack.pop(); |
| 10755 | 10777 | ira->old_bb_index = pos.basic_block_index; |
| 10756 | 10778 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 10779 | ira->old_irb.current_basic_block->suspended = false; |
| 10757 | 10780 | ira->instruction_index = pos.instruction_index; |
| 10758 | 10781 | ira->const_predecessor_bb = nullptr; |
| 10759 | 10782 | ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; |
| ... | ... | @@ -10762,7 +10785,10 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 10762 | 10785 | } |
| 10763 | 10786 | |
| 10764 | 10787 | static void ir_finish_bb(IrAnalyze *ira) { |
| 10765 | | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| 10788 | if (!ira->new_irb.current_basic_block->already_appended) { |
| 10789 | ira->new_irb.current_basic_block->already_appended = true; |
| 10790 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| 10791 | } |
| 10766 | 10792 | ira->instruction_index += 1; |
| 10767 | 10793 | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { |
| 10768 | 10794 | IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); |
| ... | ... | @@ -10780,11 +10806,18 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 10780 | 10806 | for (;;) { |
| 10781 | 10807 | while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { |
| 10782 | 10808 | IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 10783 | | if (old_bb->other == nullptr) { |
| 10809 | if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) { |
| 10784 | 10810 | ira->old_bb_index += 1; |
| 10785 | 10811 | continue; |
| 10786 | 10812 | } |
| 10787 | | if (old_bb->other->instruction_list.length != 0 || ira->old_bb_index == my_old_bb_index) { |
| 10813 | // If it's the block we just finished, or |
| 10814 | // if it's already a finished block, or |
| 10815 | // if it's a suspended block, |
| 10816 | // then skip it |
| 10817 | if (ira->old_bb_index == my_old_bb_index || |
| 10818 | old_bb->suspended || |
| 10819 | (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0)) |
| 10820 | { |
| 10788 | 10821 | ira->old_bb_index += 1; |
| 10789 | 10822 | continue; |
| 10790 | 10823 | } |
| ... | ... | @@ -10796,12 +10829,19 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 10796 | 10829 | return; |
| 10797 | 10830 | } |
| 10798 | 10831 | |
| 10832 | if (old_bb->other == nullptr) { |
| 10833 | old_bb->other = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); |
| 10834 | } |
| 10799 | 10835 | ira->new_irb.current_basic_block = old_bb->other; |
| 10800 | 10836 | ir_start_bb(ira, old_bb, nullptr); |
| 10801 | 10837 | return; |
| 10802 | 10838 | } |
| 10803 | | if (!need_repeat) |
| 10839 | if (!need_repeat) { |
| 10840 | if (ira->resume_stack.length != 0) { |
| 10841 | ira_resume(ira); |
| 10842 | } |
| 10804 | 10843 | return; |
| 10844 | } |
| 10805 | 10845 | need_repeat = false; |
| 10806 | 10846 | ira->old_bb_index = 0; |
| 10807 | 10847 | continue; |
| ... | ... | @@ -14775,43 +14815,11 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s |
| 14775 | 14815 | return nullptr; |
| 14776 | 14816 | |
| 14777 | 14817 | if (peer_parent->resolved_type == nullptr) { |
| 14778 | | IrInstruction *suspended_inst = ira_suspend(ira, suspend_source_instr, |
| 14779 | | result_peer->next_bb, &result_peer->suspend_pos); |
| 14780 | | bool last_one = result_peer->seen_before || |
| 14781 | | result_peer == &peer_parent->peers[peer_parent->peer_count - 1]; |
| 14782 | | result_peer->seen_before = true; |
| 14783 | | if (!last_one) { |
| 14784 | | return suspended_inst; |
| 14785 | | } |
| 14786 | | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count); |
| 14787 | | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| 14788 | | ResultLocPeer *this_peer = &peer_parent->peers[i]; |
| 14789 | | ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1]; |
| 14790 | | |
| 14791 | | IrInstruction *gen_instruction = this_peer->base.gen_instruction; |
| 14792 | | if (gen_instruction == nullptr) { |
| 14793 | | // unreachable instructions will cause implicit_elem_type to be null |
| 14794 | | if (this_peer->base.implicit_elem_type == nullptr) { |
| 14795 | | instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction); |
| 14796 | | } else { |
| 14797 | | instructions[i] = ir_const(ira, this_peer->base.source_instruction, |
| 14798 | | this_peer->base.implicit_elem_type); |
| 14799 | | instructions[i]->value.special = ConstValSpecialRuntime; |
| 14800 | | } |
| 14801 | | } else { |
| 14802 | | instructions[i] = gen_instruction; |
| 14803 | | } |
| 14804 | | if (opposite_peer->base.implicit_elem_type != nullptr && |
| 14805 | | opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) |
| 14806 | | { |
| 14807 | | ira->resume_stack.append(opposite_peer->suspend_pos); |
| 14808 | | } |
| 14818 | ResultLocPeer *last_peer = &peer_parent->peers[peer_parent->peer_count - 1]; |
| 14819 | if (last_peer->next_bb->suspend_instruction_ref == nullptr) { |
| 14820 | last_peer->next_bb->suspend_instruction_ref = suspend_source_instr; |
| 14809 | 14821 | } |
| 14810 | | ZigType *expected_type = ir_result_loc_expected_type(ira, suspend_source_instr, peer_parent->parent); |
| 14811 | | peer_parent->resolved_type = ir_resolve_peer_types(ira, |
| 14812 | | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| 14813 | | peer_parent->peer_count); |
| 14814 | | return ira_resume(ira); |
| 14822 | return ira_suspend(ira, suspend_source_instr, result_peer->next_bb, &result_peer->suspend_pos); |
| 14815 | 14823 | } |
| 14816 | 14824 | |
| 14817 | 14825 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| ... | ... | @@ -16159,7 +16167,7 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 16159 | 16167 | if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) |
| 16160 | 16168 | return ir_unreach_error(ira); |
| 16161 | 16169 | |
| 16162 | | if (is_comptime || old_dest_block->ref_count == 1) |
| 16170 | if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) |
| 16163 | 16171 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); |
| 16164 | 16172 | |
| 16165 | 16173 | IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); |
| ... | ... | @@ -16254,6 +16262,45 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16254 | 16262 | zig_unreachable(); |
| 16255 | 16263 | } |
| 16256 | 16264 | |
| 16265 | ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; |
| 16266 | if (peer_parent != nullptr && peer_parent->resolved_type == nullptr) { |
| 16267 | // Suspend the phi first so that it gets resumed last |
| 16268 | IrSuspendPosition suspend_pos; |
| 16269 | ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); |
| 16270 | ira->resume_stack.append(suspend_pos); |
| 16271 | |
| 16272 | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count); |
| 16273 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| 16274 | ResultLocPeer *this_peer = &peer_parent->peers[i]; |
| 16275 | ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1]; |
| 16276 | |
| 16277 | IrInstruction *gen_instruction = this_peer->base.gen_instruction; |
| 16278 | if (gen_instruction == nullptr) { |
| 16279 | // unreachable instructions will cause implicit_elem_type to be null |
| 16280 | if (this_peer->base.implicit_elem_type == nullptr) { |
| 16281 | instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction); |
| 16282 | } else { |
| 16283 | instructions[i] = ir_const(ira, this_peer->base.source_instruction, |
| 16284 | this_peer->base.implicit_elem_type); |
| 16285 | instructions[i]->value.special = ConstValSpecialRuntime; |
| 16286 | } |
| 16287 | } else { |
| 16288 | instructions[i] = gen_instruction; |
| 16289 | } |
| 16290 | if (opposite_peer->base.implicit_elem_type != nullptr && |
| 16291 | opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) |
| 16292 | { |
| 16293 | ira->resume_stack.append(opposite_peer->suspend_pos); |
| 16294 | } |
| 16295 | } |
| 16296 | ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent); |
| 16297 | peer_parent->resolved_type = ir_resolve_peer_types(ira, |
| 16298 | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| 16299 | peer_parent->peer_count); |
| 16300 | |
| 16301 | return ira_resume(ira); |
| 16302 | } |
| 16303 | |
| 16257 | 16304 | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; |
| 16258 | 16305 | ZigList<IrInstruction*> new_incoming_values = {0}; |
| 16259 | 16306 | |
| ... | ... | @@ -16342,7 +16389,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16342 | 16389 | |
| 16343 | 16390 | IrInstruction *result = ir_build_phi(&ira->new_irb, |
| 16344 | 16391 | phi_instruction->base.scope, phi_instruction->base.source_node, |
| 16345 | | new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items); |
| 16392 | new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, nullptr); |
| 16346 | 16393 | result->value.type = resolved_type; |
| 16347 | 16394 | |
| 16348 | 16395 | if (all_stack_ptrs) { |
| ... | ... | @@ -24019,7 +24066,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 24019 | 24066 | if (type_is_invalid(value->value.type)) |
| 24020 | 24067 | return ira->codegen->invalid_instruction; |
| 24021 | 24068 | |
| 24022 | | bool want_resolve_result = instruction->result_loc->written; |
| 24069 | bool want_resolve_result; |
| 24023 | 24070 | if (instruction->result_loc->written) { |
| 24024 | 24071 | if (instruction->result_loc->scope_elide != nullptr && instr_is_comptime(value)) { |
| 24025 | 24072 | want_resolve_result = true; |