| ... | @@ -672,62 +672,62 @@ fn breakExpr( | ... | @@ -672,62 +672,62 @@ fn breakExpr( |
| 672 | rl: ResultLoc, | 672 | rl: ResultLoc, |
| 673 | node: ast.Node.Index, | 673 | node: ast.Node.Index, |
| 674 | ) InnerError!zir.Inst.Ref { | 674 | ) InnerError!zir.Inst.Ref { |
| 675 | if (true) @panic("TODO update for zir-memory-layout"); | | |
| 676 | const tree = parent_scope.tree(); | 675 | const tree = parent_scope.tree(); |
| 677 | const node_datas = tree.nodes.items(.data); | 676 | const node_datas = tree.nodes.items(.data); |
| 678 | const main_tokens = tree.nodes.items(.main_token); | 677 | const main_tokens = tree.nodes.items(.main_token); |
| 679 | | 678 | |
| | 679 | const break_token = main_tokens[node]; |
| 680 | const break_label = node_datas[node].lhs; | 680 | const break_label = node_datas[node].lhs; |
| 681 | const rhs = node_datas[node].rhs; | 681 | const rhs = node_datas[node].rhs; |
| 682 | | 682 | |
| | 683 | const parent_gz = parent_scope.getGenZir(); |
| | 684 | |
| 683 | // Look for the label in the scope. | 685 | // Look for the label in the scope. |
| 684 | var scope = parent_scope; | 686 | var scope = parent_scope; |
| 685 | while (true) { | 687 | while (true) { |
| 686 | switch (scope.tag) { | 688 | switch (scope.tag) { |
| 687 | .gen_zir => { | 689 | .gen_zir => { |
| 688 | const gen_zir = scope.cast(Scope.GenZir).?; | 690 | const block_gz = scope.getGenZir(); |
| 689 | | 691 | |
| 690 | const block_inst = blk: { | 692 | const block_inst = blk: { |
| 691 | if (break_label != 0) { | 693 | if (break_label != 0) { |
| 692 | if (gen_zir.label) |*label| { | 694 | if (block_gz.label) |*label| { |
| 693 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { | 695 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { |
| 694 | label.used = true; | 696 | label.used = true; |
| 695 | break :blk label.block_inst; | 697 | break :blk label.block_inst; |
| 696 | } | 698 | } |
| 697 | } | 699 | } |
| 698 | } else if (gen_zir.break_block) |inst| { | 700 | } else if (block_gz.break_block != 0) { |
| 699 | break :blk inst; | 701 | break :blk block_gz.break_block; |
| 700 | } | 702 | } |
| 701 | scope = gen_zir.parent; | 703 | scope = block_gz.parent; |
| 702 | continue; | 704 | continue; |
| 703 | }; | 705 | }; |
| 704 | | 706 | |
| 705 | if (rhs == 0) { | 707 | if (rhs == 0) { |
| 706 | const result = try addZirInstTag(mod, parent_scope, src, .break_void, .{ | 708 | const result = try parent_gz.addBreakVoid(block_gz, block_inst, node); |
| 707 | .block = block_inst, | 709 | return rvalue(mod, parent_scope, rl, result, node); |
| 708 | }); | | |
| 709 | return rvalue(mod, parent_scope, rl, result); | | |
| 710 | } | 710 | } |
| 711 | gen_zir.break_count += 1; | 711 | block_gz.break_count += 1; |
| 712 | const prev_rvalue_rl_count = gen_zir.rvalue_rl_count; | 712 | const prev_rvalue_rl_count = block_gz.rvalue_rl_count; |
| 713 | const operand = try expr(mod, parent_scope, gen_zir.break_result_loc, rhs); | 713 | const operand = try expr(mod, parent_scope, block_gz.break_result_loc, rhs); |
| 714 | const have_store_to_block = gen_zir.rvalue_rl_count != prev_rvalue_rl_count; | 714 | const have_store_to_block = block_gz.rvalue_rl_count != prev_rvalue_rl_count; |
| 715 | const br = try addZirInstTag(mod, parent_scope, src, .@"break", .{ | 715 | |
| 716 | .block = block_inst, | 716 | const br = try parent_gz.addBreak(block_inst, operand); |
| 717 | .operand = operand, | 717 | |
| 718 | }); | 718 | if (block_gz.break_result_loc == .block_ptr) { |
| 719 | if (gen_zir.break_result_loc == .block_ptr) { | 719 | try block_gz.labeled_breaks.append(mod.gpa, br); |
| 720 | try gen_zir.labeled_breaks.append(mod.gpa, br.castTag(.@"break").?); | | |
| 721 | | 720 | |
| 722 | if (have_store_to_block) { | 721 | if (have_store_to_block) { |
| 723 | const inst_list = parent_scope.getGenZir().instructions.items; | 722 | const zir_tags = parent_gz.zir_code.instructions.items(.tag); |
| 724 | const last_inst = inst_list[inst_list.len - 2]; | 723 | const zir_datas = parent_gz.zir_code.instructions.items(.data); |
| 725 | const store_inst = last_inst.castTag(.store_to_block_ptr).?; | 724 | const last_inst = zir_tags.len - 2; |
| 726 | assert(store_inst.positionals.lhs == gen_zir.rl_ptr.?); | 725 | assert(zir_tags[last_inst] == .store_to_block_ptr); |
| 727 | try gen_zir.labeled_store_to_block_ptr_list.append(mod.gpa, store_inst); | 726 | assert(zir_datas[last_inst].bin.lhs == block_gz.rl_ptr); |
| | 727 | try block_gz.labeled_store_to_block_ptr_list.append(mod.gpa, @intCast(zir.Inst.Ref, last_inst)); |
| 728 | } | 728 | } |
| 729 | } | 729 | } |
| 730 | return rvalue(mod, parent_scope, rl, br); | 730 | return rvalue(mod, parent_scope, rl, br, node); |
| 731 | }, | 731 | }, |
| 732 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, | 732 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 733 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, | 733 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| ... | @@ -735,7 +735,7 @@ fn breakExpr( | ... | @@ -735,7 +735,7 @@ fn breakExpr( |
| 735 | const label_name = try mod.identifierTokenString(parent_scope, break_label); | 735 | const label_name = try mod.identifierTokenString(parent_scope, break_label); |
| 736 | return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name}); | 736 | return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name}); |
| 737 | } else { | 737 | } else { |
| 738 | return mod.failTok(parent_scope, src, "break expression outside loop", .{}); | 738 | return mod.failTok(parent_scope, break_token, "break expression outside loop", .{}); |
| 739 | }, | 739 | }, |
| 740 | } | 740 | } |
| 741 | } | 741 | } |
| ... | @@ -1769,23 +1769,11 @@ fn finishThenElseBlock( | ... | @@ -1769,23 +1769,11 @@ fn finishThenElseBlock( |
| 1769 | switch (strat.tag) { | 1769 | switch (strat.tag) { |
| 1770 | .break_void => { | 1770 | .break_void => { |
| 1771 | if (!wzc.refIsNoReturn(then_result)) { | 1771 | if (!wzc.refIsNoReturn(then_result)) { |
| 1772 | _ = try then_scope.add(.{ | 1772 | _ = try then_scope.addBreakVoid(block_scope, then_break_block, then_src); |
| 1773 | .tag = .break_void_node, | | |
| 1774 | .data = .{ .break_void_node = .{ | | |
| 1775 | .src_node = wzc.decl.nodeIndexToRelative(then_src), | | |
| 1776 | .block_inst = then_break_block, | | |
| 1777 | } }, | | |
| 1778 | }); | | |
| 1779 | } | 1773 | } |
| 1780 | const elide_else = if (else_result != .none) wzc.refIsNoReturn(else_result) else false; | 1774 | const elide_else = if (else_result != .none) wzc.refIsNoReturn(else_result) else false; |
| 1781 | if (!elide_else) { | 1775 | if (!elide_else) { |
| 1782 | _ = try else_scope.add(.{ | 1776 | _ = try else_scope.addBreakVoid(block_scope, main_block, else_src); |
| 1783 | .tag = .break_void_node, | | |
| 1784 | .data = .{ .break_void_node = .{ | | |
| 1785 | .src_node = wzc.decl.nodeIndexToRelative(else_src), | | |
| 1786 | .block_inst = main_block, | | |
| 1787 | } }, | | |
| 1788 | }); | | |
| 1789 | } | 1777 | } |
| 1790 | assert(!strat.elide_store_to_block_ptr_instructions); | 1778 | assert(!strat.elide_store_to_block_ptr_instructions); |
| 1791 | try setCondBrPayload(condbr, cond, then_scope, else_scope); | 1779 | try setCondBrPayload(condbr, cond, then_scope, else_scope); |
| ... | @@ -1793,32 +1781,14 @@ fn finishThenElseBlock( | ... | @@ -1793,32 +1781,14 @@ fn finishThenElseBlock( |
| 1793 | }, | 1781 | }, |
| 1794 | .break_operand => { | 1782 | .break_operand => { |
| 1795 | if (!wzc.refIsNoReturn(then_result)) { | 1783 | if (!wzc.refIsNoReturn(then_result)) { |
| 1796 | _ = try then_scope.add(.{ | 1784 | _ = try then_scope.addBreak(then_break_block, then_result); |
| 1797 | .tag = .@"break", | | |
| 1798 | .data = .{ .@"break" = .{ | | |
| 1799 | .block_inst = then_break_block, | | |
| 1800 | .operand = then_result, | | |
| 1801 | } }, | | |
| 1802 | }); | | |
| 1803 | } | 1785 | } |
| 1804 | if (else_result != .none) { | 1786 | if (else_result != .none) { |
| 1805 | if (!wzc.refIsNoReturn(else_result)) { | 1787 | if (!wzc.refIsNoReturn(else_result)) { |
| 1806 | _ = try else_scope.add(.{ | 1788 | _ = try else_scope.addBreak(main_block, else_result); |
| 1807 | .tag = .@"break", | | |
| 1808 | .data = .{ .@"break" = .{ | | |
| 1809 | .block_inst = main_block, | | |
| 1810 | .operand = else_result, | | |
| 1811 | } }, | | |
| 1812 | }); | | |
| 1813 | } | 1789 | } |
| 1814 | } else { | 1790 | } else { |
| 1815 | _ = try else_scope.add(.{ | 1791 | _ = try else_scope.addBreakVoid(block_scope, main_block, else_src); |
| 1816 | .tag = .break_void_node, | | |
| 1817 | .data = .{ .break_void_node = .{ | | |
| 1818 | .src_node = wzc.decl.nodeIndexToRelative(else_src), | | |
| 1819 | .block_inst = main_block, | | |
| 1820 | } }, | | |
| 1821 | }); | | |
| 1822 | } | 1792 | } |
| 1823 | if (strat.elide_store_to_block_ptr_instructions) { | 1793 | if (strat.elide_store_to_block_ptr_instructions) { |
| 1824 | try setCondBrPayloadElideBlockStorePtr(condbr, cond, then_scope, else_scope); | 1794 | try setCondBrPayloadElideBlockStorePtr(condbr, cond, then_scope, else_scope); |