| ... | @@ -1406,7 +1406,8 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in | ... | @@ -1406,7 +1406,8 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in |
| 1406 | } | 1406 | } |
| 1407 | | 1407 | |
| 1408 | static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, | 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 | assert(incoming_count != 0); | 1412 | assert(incoming_count != 0); |
| 1412 | assert(incoming_count != SIZE_MAX); | 1413 | assert(incoming_count != SIZE_MAX); |
| ... | @@ -1415,6 +1416,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source | ... | @@ -1415,6 +1416,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source |
| 1415 | phi_instruction->incoming_count = incoming_count; | 1416 | phi_instruction->incoming_count = incoming_count; |
| 1416 | phi_instruction->incoming_blocks = incoming_blocks; | 1417 | phi_instruction->incoming_blocks = incoming_blocks; |
| 1417 | phi_instruction->incoming_values = incoming_values; | 1418 | phi_instruction->incoming_values = incoming_values; |
| | 1419 | phi_instruction->peer_parent = peer_parent; |
| 1418 | | 1420 | |
| 1419 | for (size_t i = 0; i < incoming_count; i += 1) { | 1421 | for (size_t i = 0; i < incoming_count; i += 1) { |
| 1420 | ir_ref_bb(incoming_blocks[i]); | 1422 | ir_ref_bb(incoming_blocks[i]); |
| ... | @@ -3700,7 +3702,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3700,7 +3702,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3700 | } | 3702 | } |
| 3701 | | 3703 | |
| 3702 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); | 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 | } else { | 3707 | } else { |
| 3705 | incoming_blocks.append(irb->current_basic_block); | 3708 | incoming_blocks.append(irb->current_basic_block); |
| 3706 | incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node))); | 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,7 +3713,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3710 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); | 3713 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3711 | ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); | 3714 | ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); |
| 3712 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); | 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 | } else { | 3718 | } else { |
| 3715 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); | 3719 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3716 | return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node))); | 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,7 +3799,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node |
| 3795 | incoming_blocks[0] = post_val1_block; | 3799 | incoming_blocks[0] = post_val1_block; |
| 3796 | incoming_blocks[1] = post_val2_block; | 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 | static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { | 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,7 +3841,7 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod |
| 3837 | incoming_blocks[0] = post_val1_block; | 3841 | incoming_blocks[0] = post_val1_block; |
| 3838 | incoming_blocks[1] = post_val2_block; | 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 | static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_inst, | 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,7 +3915,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3911 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); | 3915 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 3912 | incoming_blocks[0] = after_null_block; | 3916 | incoming_blocks[0] = after_null_block; |
| 3913 | incoming_blocks[1] = after_ok_block; | 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 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); | 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,7 +5431,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5427 | incoming_blocks[0] = after_then_block; | 5431 | incoming_blocks[0] = after_then_block; |
| 5428 | incoming_blocks[1] = after_else_block; | 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 | return ir_expr_wrap(irb, scope, phi, result_loc); | 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,9 +5472,10 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction * |
| 5468 | // We needed a pointer to a value, but we got a value. So we create | 5472 | // We needed a pointer to a value, but we got a value. So we create |
| 5469 | // an instruction which just makes a pointer of it. | 5473 | // an instruction which just makes a pointer of it. |
| 5470 | return ir_build_ref(irb, scope, value->source_node, value, false, false); | 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 | static PtrLen star_token_to_ptr_len(TokenId token_id) { | 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,7 +5936,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5931 | incoming_values.append(void_else_result); | 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 | return ir_expr_wrap(irb, scope, phi, result_loc); | 5941 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5936 | } else if (var_symbol != nullptr) { | 5942 | } else if (var_symbol != nullptr) { |
| 5937 | ir_set_cursor_at_end_and_append_block(irb, cond_block); | 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,7 +6028,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6022 | incoming_values.append(void_else_result); | 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 | return ir_expr_wrap(irb, scope, phi, result_loc); | 6033 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6027 | } else { | 6034 | } else { |
| 6028 | ir_set_cursor_at_end_and_append_block(irb, cond_block); | 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,7 +6107,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6100 | incoming_values.append(void_else_result); | 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 | return ir_expr_wrap(irb, scope, phi, result_loc); | 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,7 +6238,8 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 6230 | incoming_values.append(void_else_value); | 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 | return ir_expr_wrap(irb, parent_scope, phi, result_loc); | 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,7 +6604,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6595 | incoming_blocks[0] = after_then_block; | 6604 | incoming_blocks[0] = after_then_block; |
| 6596 | incoming_blocks[1] = after_else_block; | 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 | return ir_expr_wrap(irb, scope, phi, result_loc); | 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,7 +6699,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6690 | incoming_blocks[0] = after_then_block; | 6699 | incoming_blocks[0] = after_then_block; |
| 6691 | incoming_blocks[1] = after_else_block; | 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 | return ir_expr_wrap(irb, scope, phi, result_loc); | 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,7 +6994,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6985 | if (incoming_blocks.length == 0) { | 6994 | if (incoming_blocks.length == 0) { |
| 6986 | result_instruction = ir_build_const_void(irb, scope, node); | 6995 | result_instruction = ir_build_const_void(irb, scope, node); |
| 6987 | } else { | 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 | return ir_expr_wrap(irb, scope, result_instruction, result_loc); | 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,7 +7283,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 7273 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); | 7283 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 7274 | incoming_blocks[0] = after_err_block; | 7284 | incoming_blocks[0] = after_err_block; |
| 7275 | incoming_blocks[1] = after_ok_block; | 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 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); | 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,7 +7968,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7958 | incoming_values[0] = const_bool_true; | 7968 | incoming_values[0] = const_bool_true; |
| 7959 | incoming_blocks[1] = post_cancel_awaiter_block; | 7969 | incoming_blocks[1] = post_cancel_awaiter_block; |
| 7960 | incoming_values[1] = const_bool_false; | 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 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); | 7973 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); |
| 7963 | 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)); | 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,7 +8091,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 8080 | case NodeTypeContinue: | 8091 | case NodeTypeContinue: |
| 8081 | return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); | 8092 | return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); |
| 8082 | case NodeTypeUnreachable: | 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 | case NodeTypeDefer: | 8095 | case NodeTypeDefer: |
| 8085 | return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); | 8096 | return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); |
| 8086 | case NodeTypeSliceExpr: | 8097 | case NodeTypeSliceExpr: |
| ... | @@ -8337,7 +8348,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -8337,7 +8348,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8337 | incoming_values[0] = const_bool_false; | 8348 | incoming_values[0] = const_bool_false; |
| 8338 | incoming_blocks[1] = irb->exec->coro_normal_final; | 8349 | incoming_blocks[1] = irb->exec->coro_normal_final; |
| 8339 | incoming_values[1] = const_bool_true; | 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 | IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); | 8353 | IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); |
| 8343 | IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); | 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,7 +8356,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8345 | merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); | 8356 | merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); |
| 8346 | merge_incoming_blocks[1] = irb->exec->coro_normal_final; | 8357 | merge_incoming_blocks[1] = irb->exec->coro_normal_final; |
| 8347 | merge_incoming_values[1] = await_handle_in_block; | 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 | Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME); | 8361 | Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME); |
| 8351 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, | 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,16 +10748,27 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons |
| 10737 | static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, | 10748 | static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, |
| 10738 | IrSuspendPosition *suspend_pos) | 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 | suspend_pos->basic_block_index = ira->old_bb_index; | 10757 | suspend_pos->basic_block_index = ira->old_bb_index; |
| 10741 | suspend_pos->instruction_index = ira->instruction_index; | 10758 | suspend_pos->instruction_index = ira->instruction_index; |
| 10742 | | 10759 | |
| 10743 | ira->old_bb_index = next_bb->index; | 10760 | ira->old_irb.current_basic_block->suspended = true; |
| 10744 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); | 10761 | |
| 10745 | assert(ira->old_irb.current_basic_block == next_bb); | 10762 | // null next_bb means that the caller plans to call ira_resume before returning |
| 10746 | ira->instruction_index = 0; | 10763 | if (next_bb != nullptr) { |
| 10747 | ira->const_predecessor_bb = nullptr; | 10764 | ira->old_bb_index = next_bb->index; |
| 10748 | next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction); | 10765 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 10749 | ira->new_irb.current_basic_block = next_bb->other; | 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 | return ira->codegen->unreach_instruction; | 10772 | return ira->codegen->unreach_instruction; |
| 10751 | } | 10773 | } |
| 10752 | | 10774 | |
| ... | @@ -10754,6 +10776,7 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { | ... | @@ -10754,6 +10776,7 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 10754 | IrSuspendPosition pos = ira->resume_stack.pop(); | 10776 | IrSuspendPosition pos = ira->resume_stack.pop(); |
| 10755 | ira->old_bb_index = pos.basic_block_index; | 10777 | ira->old_bb_index = pos.basic_block_index; |
| 10756 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); | 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 | ira->instruction_index = pos.instruction_index; | 10780 | ira->instruction_index = pos.instruction_index; |
| 10758 | ira->const_predecessor_bb = nullptr; | 10781 | ira->const_predecessor_bb = nullptr; |
| 10759 | ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; | 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,7 +10785,10 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 10762 | } | 10785 | } |
| 10763 | | 10786 | |
| 10764 | static void ir_finish_bb(IrAnalyze *ira) { | 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 | ira->instruction_index += 1; | 10792 | ira->instruction_index += 1; |
| 10767 | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { | 10793 | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { |
| 10768 | IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); | 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,11 +10806,18 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 10780 | for (;;) { | 10806 | for (;;) { |
| 10781 | while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { | 10807 | while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { |
| 10782 | IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); | 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 | ira->old_bb_index += 1; | 10810 | ira->old_bb_index += 1; |
| 10785 | continue; | 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 | ira->old_bb_index += 1; | 10821 | ira->old_bb_index += 1; |
| 10789 | continue; | 10822 | continue; |
| 10790 | } | 10823 | } |
| ... | @@ -10796,12 +10829,19 @@ static void ir_finish_bb(IrAnalyze *ira) { | ... | @@ -10796,12 +10829,19 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 10796 | return; | 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 | ira->new_irb.current_basic_block = old_bb->other; | 10835 | ira->new_irb.current_basic_block = old_bb->other; |
| 10800 | ir_start_bb(ira, old_bb, nullptr); | 10836 | ir_start_bb(ira, old_bb, nullptr); |
| 10801 | return; | 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 | return; | 10843 | return; |
| | 10844 | } |
| 10805 | need_repeat = false; | 10845 | need_repeat = false; |
| 10806 | ira->old_bb_index = 0; | 10846 | ira->old_bb_index = 0; |
| 10807 | continue; | 10847 | continue; |
| ... | @@ -14775,43 +14815,11 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s | ... | @@ -14775,43 +14815,11 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s |
| 14775 | return nullptr; | 14815 | return nullptr; |
| 14776 | | 14816 | |
| 14777 | if (peer_parent->resolved_type == nullptr) { | 14817 | if (peer_parent->resolved_type == nullptr) { |
| 14778 | IrInstruction *suspended_inst = ira_suspend(ira, suspend_source_instr, | 14818 | ResultLocPeer *last_peer = &peer_parent->peers[peer_parent->peer_count - 1]; |
| 14779 | result_peer->next_bb, &result_peer->suspend_pos); | 14819 | if (last_peer->next_bb->suspend_instruction_ref == nullptr) { |
| 14780 | bool last_one = result_peer->seen_before || | 14820 | last_peer->next_bb->suspend_instruction_ref = suspend_source_instr; |
| 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 | } | | |
| 14809 | } | 14821 | } |
| 14810 | ZigType *expected_type = ir_result_loc_expected_type(ira, suspend_source_instr, peer_parent->parent); | 14822 | return ira_suspend(ira, suspend_source_instr, result_peer->next_bb, &result_peer->suspend_pos); |
| 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); | | |
| 14815 | } | 14823 | } |
| 14816 | | 14824 | |
| 14817 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, | 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,7 +16167,7 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 16159 | if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) | 16167 | if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) |
| 16160 | return ir_unreach_error(ira); | 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 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); | 16171 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); |
| 16164 | | 16172 | |
| 16165 | IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); | 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,6 +16262,45 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16254 | zig_unreachable(); | 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 | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; | 16304 | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; |
| 16258 | ZigList<IrInstruction*> new_incoming_values = {0}; | 16305 | ZigList<IrInstruction*> new_incoming_values = {0}; |
| 16259 | | 16306 | |
| ... | @@ -16342,7 +16389,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -16342,7 +16389,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16342 | | 16389 | |
| 16343 | IrInstruction *result = ir_build_phi(&ira->new_irb, | 16390 | IrInstruction *result = ir_build_phi(&ira->new_irb, |
| 16344 | phi_instruction->base.scope, phi_instruction->base.source_node, | 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 | result->value.type = resolved_type; | 16393 | result->value.type = resolved_type; |
| 16347 | | 16394 | |
| 16348 | if (all_stack_ptrs) { | 16395 | if (all_stack_ptrs) { |
| ... | @@ -24019,7 +24066,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct | ... | @@ -24019,7 +24066,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 24019 | if (type_is_invalid(value->value.type)) | 24066 | if (type_is_invalid(value->value.type)) |
| 24020 | return ira->codegen->invalid_instruction; | 24067 | return ira->codegen->invalid_instruction; |
| 24021 | | 24068 | |
| 24022 | bool want_resolve_result = instruction->result_loc->written; | 24069 | bool want_resolve_result; |
| 24023 | if (instruction->result_loc->written) { | 24070 | if (instruction->result_loc->written) { |
| 24024 | if (instruction->result_loc->scope_elide != nullptr && instr_is_comptime(value)) { | 24071 | if (instruction->result_loc->scope_elide != nullptr && instr_is_comptime(value)) { |
| 24025 | want_resolve_result = true; | 24072 | want_resolve_result = true; |