authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-24 23:45:49+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-24 18:32:08-05:00
log63788b2a511eb87974065a052e2436b0c6202544
treeef11ed08dc3b7328ba5de9c778a1afe9e0d48744
parent52a2aa11e2768a5d7881377ddb7a053d81e4cff4

stage2: change how stale `store_to_block_ptr`s are detected

Instead of explicitly setting lhs to .none, check if the lhs instruction was analyzed. This simpler approach also handles stores from nested blocks correctly.

4 files changed, 19 insertions(+), 32 deletions(-)

src/AstGen.zig-27
...@@ -1760,19 +1760,6 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn...@@ -1760,19 +1760,6 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
1760 .block_ptr => {1760 .block_ptr => {
1761 const br = try parent_gz.addBreak(break_tag, block_inst, operand);1761 const br = try parent_gz.addBreak(break_tag, block_inst, operand);
1762 try block_gz.labeled_breaks.append(astgen.gpa, br);1762 try block_gz.labeled_breaks.append(astgen.gpa, br);
1763
1764 // if list grew as much as rvalue_rl_count, then a break
1765 // inside operand already saved the store_to_block_ptr
1766 const have_store_to_block = block_gz.rvalue_rl_count >
1767 block_gz.labeled_store_to_block_ptr_list.items.len;
1768 if (have_store_to_block) {
1769 const zir_tags = parent_gz.astgen.instructions.items(.tag);
1770 const zir_datas = parent_gz.astgen.instructions.items(.data);
1771 const store_inst = @intCast(u32, zir_tags.len - 2);
1772 assert(zir_tags[store_inst] == .store_to_block_ptr);
1773 assert(zir_datas[store_inst].bin.lhs == block_gz.rl_ptr);
1774 try block_gz.labeled_store_to_block_ptr_list.append(astgen.gpa, store_inst);
1775 }
1776 },1763 },
1777 .ptr => {1764 .ptr => {
1778 // In this case we don't have any mechanism to intercept it;1765 // In this case we don't have any mechanism to intercept it;
...@@ -1955,7 +1942,6 @@ fn labeledBlockExpr(...@@ -1955,7 +1942,6 @@ fn labeledBlockExpr(
1955 block_scope.setBreakResultLoc(rl);1942 block_scope.setBreakResultLoc(rl);
1956 defer block_scope.unstack();1943 defer block_scope.unstack();
1957 defer block_scope.labeled_breaks.deinit(astgen.gpa);1944 defer block_scope.labeled_breaks.deinit(astgen.gpa);
1958 defer block_scope.labeled_store_to_block_ptr_list.deinit(astgen.gpa);
19591945
1960 try blockExprStmts(&block_scope, &block_scope.base, statements);1946 try blockExprStmts(&block_scope, &block_scope.base, statements);
19611947
...@@ -1963,9 +1949,7 @@ fn labeledBlockExpr(...@@ -1963,9 +1949,7 @@ fn labeledBlockExpr(
1963 try astgen.appendErrorTok(label_token, "unused block label", .{});1949 try astgen.appendErrorTok(label_token, "unused block label", .{});
1964 }1950 }
19651951
1966 const zir_tags = gz.astgen.instructions.items(.tag);
1967 const zir_datas = gz.astgen.instructions.items(.data);1952 const zir_datas = gz.astgen.instructions.items(.data);
1968
1969 const strat = rl.strategy(&block_scope);1953 const strat = rl.strategy(&block_scope);
1970 switch (strat.tag) {1954 switch (strat.tag) {
1971 .break_void => {1955 .break_void => {
...@@ -1981,11 +1965,6 @@ fn labeledBlockExpr(...@@ -1981,11 +1965,6 @@ fn labeledBlockExpr(
1981 .break_operand => {1965 .break_operand => {
1982 // All break operands are values that did not use the result location pointer.1966 // All break operands are values that did not use the result location pointer.
1983 if (strat.elide_store_to_block_ptr_instructions) {1967 if (strat.elide_store_to_block_ptr_instructions) {
1984 for (block_scope.labeled_store_to_block_ptr_list.items) |inst| {
1985 // Mark as elided for removal below.
1986 assert(zir_tags[inst] == .store_to_block_ptr);
1987 zir_datas[inst].bin.lhs = .none;
1988 }
1989 try block_scope.setBlockBodyEliding(block_inst);1968 try block_scope.setBlockBodyEliding(block_inst);
1990 } else {1969 } else {
1991 try block_scope.setBlockBody(block_inst);1970 try block_scope.setBlockBody(block_inst);
...@@ -5322,7 +5301,6 @@ fn whileExpr(...@@ -5322,7 +5301,6 @@ fn whileExpr(
5322 loop_scope.setBreakResultLoc(rl);5301 loop_scope.setBreakResultLoc(rl);
5323 defer loop_scope.unstack();5302 defer loop_scope.unstack();
5324 defer loop_scope.labeled_breaks.deinit(astgen.gpa);5303 defer loop_scope.labeled_breaks.deinit(astgen.gpa);
5325 defer loop_scope.labeled_store_to_block_ptr_list.deinit(astgen.gpa);
53265304
5327 var continue_scope = parent_gz.makeSubBlock(&loop_scope.base);5305 var continue_scope = parent_gz.makeSubBlock(&loop_scope.base);
5328 defer continue_scope.unstack();5306 defer continue_scope.unstack();
...@@ -5573,7 +5551,6 @@ fn forExpr(...@@ -5573,7 +5551,6 @@ fn forExpr(
5573 loop_scope.setBreakResultLoc(rl);5551 loop_scope.setBreakResultLoc(rl);
5574 defer loop_scope.unstack();5552 defer loop_scope.unstack();
5575 defer loop_scope.labeled_breaks.deinit(astgen.gpa);5553 defer loop_scope.labeled_breaks.deinit(astgen.gpa);
5576 defer loop_scope.labeled_store_to_block_ptr_list.deinit(astgen.gpa);
55775554
5578 var cond_scope = parent_gz.makeSubBlock(&loop_scope.base);5555 var cond_scope = parent_gz.makeSubBlock(&loop_scope.base);
5579 defer cond_scope.unstack();5556 defer cond_scope.unstack();
...@@ -9553,10 +9530,6 @@ const GenZir = struct {...@@ -9553,10 +9530,6 @@ const GenZir = struct {
9553 /// Tracks `break :foo bar` instructions so they can possibly be elided later if9530 /// Tracks `break :foo bar` instructions so they can possibly be elided later if
9554 /// the labeled block ends up not needing a result location pointer.9531 /// the labeled block ends up not needing a result location pointer.
9555 labeled_breaks: ArrayListUnmanaged(Zir.Inst.Index) = .{},9532 labeled_breaks: ArrayListUnmanaged(Zir.Inst.Index) = .{},
9556 /// Tracks `store_to_block_ptr` instructions that correspond to break instructions
9557 /// so they can possibly be elided later if the labeled block ends up not needing
9558 /// a result location pointer.
9559 labeled_store_to_block_ptr_list: ArrayListUnmanaged(Zir.Inst.Index) = .{},
95609533
9561 suspend_node: Ast.Node.Index = 0,9534 suspend_node: Ast.Node.Index = 0,
9562 nosuspend_node: Ast.Node.Index = 0,9535 nosuspend_node: Ast.Node.Index = 0,
src/Sema.zig+3-5
...@@ -3247,12 +3247,10 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -3247,12 +3247,10 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
3247 defer tracy.end();3247 defer tracy.end();
32483248
3249 const bin_inst = sema.code.instructions.items(.data)[inst].bin;3249 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
3250 if (bin_inst.lhs == .none) {3250 const ptr = sema.inst_map.get(@enumToInt(bin_inst.lhs) - @as(u32, Zir.Inst.Ref.typed_value_map.len)) orelse {
3251 // This is an elided instruction, but AstGen was not smart enough3251 // This is an elided instruction, but AstGen was unable to omit it.
3252 // to omit it.
3253 return;3252 return;
3254 }3253 };
3255 const ptr = sema.resolveInst(bin_inst.lhs);
3256 const value = sema.resolveInst(bin_inst.rhs);3254 const value = sema.resolveInst(bin_inst.rhs);
3257 const ptr_ty = try Type.ptr(sema.arena, .{3255 const ptr_ty = try Type.ptr(sema.arena, .{
3258 .pointee_type = sema.typeOf(value),3256 .pointee_type = sema.typeOf(value),
test/behavior.zig+1
...@@ -103,6 +103,7 @@ test {...@@ -103,6 +103,7 @@ test {
103 {103 {
104 // Tests that pass for stage1, llvm backend, C backend104 // Tests that pass for stage1, llvm backend, C backend
105 _ = @import("behavior/bugs/9584.zig");105 _ = @import("behavior/bugs/9584.zig");
106 _ = @import("behavior/bugs/10970.zig");
106 _ = @import("behavior/cast_int.zig");107 _ = @import("behavior/cast_int.zig");
107 _ = @import("behavior/eval.zig");108 _ = @import("behavior/eval.zig");
108 _ = @import("behavior/int128.zig");109 _ = @import("behavior/int128.zig");
test/behavior/bugs/10970.zig created+15
...@@ -0,0 +1,15 @@
1const builtin = @import("builtin");
2
3fn retOpt() ?u32 {
4 return null;
5}
6test {
7 var cond = true;
8 const opt = while (cond) {
9 if (retOpt()) |opt| {
10 break opt;
11 }
12 break 1;
13 } else 2;
14 _ = opt;
15}