authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 23:25:43-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 23:25:43-04:00
loga0427d29e4d3c47f470d88a4afdd0e87d3373325
tree103027c958819b5fa0de1eecf0b552270c4fd6a0
parent4582ec518f9984a26c68b8427a914bad6dc80c4a
signaturelock-open Commit is signed but in an unrecognized format.

fix peer result locations in the face of unreachable

```zig export fn entry() void { var nothing: ?*i32 = null; var whatever = if (nothing) |x1| i32(1) else unreachable; } ``` ```llvm define void @entry() #2 !dbg !35 { Entry: %nothing = alloca i32*, align 8 %whatever = alloca i32, align 4 store i32* null, i32** %nothing, align 8, !dbg !45 call void @llvm.dbg.declare(metadata i32** %nothing, metadata !39, metadata !DIExpression()), !dbg !45 %0 = load i32*, i32** %nothing, align 8, !dbg !46 %1 = icmp ne i32* %0, null, !dbg !46 br i1 %1, label %OptionalThen, label %OptionalElse, !dbg !46 OptionalThen: ; preds = %Entry call void @llvm.dbg.declare(metadata i32** %nothing, metadata !43, metadata !DIExpression()), !dbg !46 store i32 1, i32* %whatever, align 4, !dbg !47 br label %OptionalEndIf, !dbg !46 OptionalElse: ; preds = %Entry tail call fastcc void @panic(%"[]u8"* @1, %builtin.StackTrace* null), !dbg !48 unreachable, !dbg !48 OptionalEndIf: ; preds = %OptionalThen call void @llvm.dbg.declare(metadata i32* %whatever, metadata !44, metadata !DIExpression()), !dbg !49 ret void, !dbg !50 } ```

2 files changed, 122 insertions(+), 71 deletions(-)

src/all_types.hpp+5-1
...@@ -43,6 +43,7 @@ struct TldExport;...@@ -43,6 +43,7 @@ struct TldExport;
43struct IrAnalyze;43struct IrAnalyze;
44struct ResultLoc;44struct ResultLoc;
45struct ResultLocPeer;45struct ResultLocPeer;
46struct ResultLocPeerParent;
4647
47enum X64CABIClass {48enum X64CABIClass {
48 X64CABIClass_Unknown,49 X64CABIClass_Unknown,
...@@ -2163,6 +2164,9 @@ struct IrBasicBlock {...@@ -2163,6 +2164,9 @@ struct IrBasicBlock {
2163 // if the branch is comptime. The instruction points to the reason2164 // if the branch is comptime. The instruction points to the reason
2164 // the basic block must be comptime.2165 // the basic block must be comptime.
2165 IrInstruction *must_be_comptime_source_instr;2166 IrInstruction *must_be_comptime_source_instr;
2167 IrInstruction *suspend_instruction_ref;
2168 bool already_appended;
2169 bool suspended;
2166};2170};
21672171
2168// These instructions are in transition to having "pass 1" instructions2172// These instructions are in transition to having "pass 1" instructions
...@@ -2434,6 +2438,7 @@ struct IrInstructionPhi {...@@ -2434,6 +2438,7 @@ struct IrInstructionPhi {
2434 size_t incoming_count;2438 size_t incoming_count;
2435 IrBasicBlock **incoming_blocks;2439 IrBasicBlock **incoming_blocks;
2436 IrInstruction **incoming_values;2440 IrInstruction **incoming_values;
2441 ResultLocPeerParent *peer_parent;
2437};2442};
24382443
2439enum IrUnOp {2444enum IrUnOp {
...@@ -3646,7 +3651,6 @@ struct IrSuspendPosition {...@@ -3646,7 +3651,6 @@ struct IrSuspendPosition {
3646struct ResultLocPeer {3651struct ResultLocPeer {
3647 ResultLoc base;3652 ResultLoc base;
36483653
3649 bool seen_before;
3650 ResultLocPeerParent *parent;3654 ResultLocPeerParent *parent;
3651 IrBasicBlock *next_bb;3655 IrBasicBlock *next_bb;
3652 IrSuspendPosition suspend_pos;3656 IrSuspendPosition suspend_pos;
src/ir.cpp+117-70
...@@ -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}
14071407
1408static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node,1408static 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;
14181420
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 }
37013703
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;
37973801
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}
38003804
3801static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) {3805static 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;
38393843
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}
38423846
3843static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_inst,3847static 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}
39173921
...@@ -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;
54295433
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}
54335437
...@@ -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 create5472 // 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 }
54725478
5473 return ir_expr_wrap(irb, scope, value, result_loc);
5474}5479}
54755480
5476static PtrLen star_token_to_ptr_len(TokenId token_id) {5481static 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 }
59335938
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 }
60246030
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 }
61026109
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 }
62326240
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}
62366245
...@@ -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;
65976606
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}
66016610
...@@ -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;
66926701
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}
66966705
...@@ -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}
72797289
...@@ -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));
79647975
...@@ -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);
83418352
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);
83498360
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
10737static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb,10748static 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;
1074210759
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}
1075210774
...@@ -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}
1076310786
10764static void ir_finish_bb(IrAnalyze *ira) {10787static 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 }
1079810831
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;
1477614816
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 }
1481614824
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);
1616116169
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);
1616416172
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 }
1625616264
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};
1625916306
...@@ -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
1634216389
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;
1634716394
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;
2402124068
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;