diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-03-24 20:45:14 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-03-24 20:45:14 -0700 |
| commit | 01bfd835bb9613d21f09c0c4f5b905b077b3d5f9 (patch) | |
| tree | 89a9fe2ca68d2055abebee9f17b2136f8e5997cf /src | |
| parent | ea42ab34abc0408b66ce2c0212afd4f5705e8d43 (diff) | |
| download | zig-01bfd835bb9613d21f09c0c4f5b905b077b3d5f9.tar.gz zig-01bfd835bb9613d21f09c0c4f5b905b077b3d5f9.zip | |
stage2: clean up break / noreturn astgen
* Module.addBreak and addBreakVoid return zir.Inst.Index not Ref
because Index is the simpler type and we never need a Ref for these.
* astgen: make noreturn stuff return the unreachable_value and avoid
unnecessary calls to rvalue()
* breakExpr: avoid unnecessary access into the tokens array
* breakExpr: fix incorrect `@intCast` (previously this unsafely
casted an Index to a Ref)
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 23 | ||||
| -rw-r--r-- | src/astgen.zig | 74 |
2 files changed, 45 insertions, 52 deletions
diff --git a/src/Module.zig b/src/Module.zig index e3e8fa813b..0258e703cf 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -935,11 +935,11 @@ pub const Scope = struct { break_count: usize = 0, /// Tracks `break :foo bar` instructions so they can possibly be elided later if /// the labeled block ends up not needing a result location pointer. - labeled_breaks: std.ArrayListUnmanaged(zir.Inst.Ref) = .{}, + labeled_breaks: std.ArrayListUnmanaged(zir.Inst.Index) = .{}, /// Tracks `store_to_block_ptr` instructions that correspond to break instructions /// so they can possibly be elided later if the labeled block ends up not needing /// a result location pointer. - labeled_store_to_block_ptr_list: std.ArrayListUnmanaged(zir.Inst.Ref) = .{}, + labeled_store_to_block_ptr_list: std.ArrayListUnmanaged(zir.Inst.Index) = .{}, pub const Label = struct { token: ast.TokenIndex, @@ -1226,8 +1226,8 @@ pub const Scope = struct { gz: *GenZir, break_block: zir.Inst.Index, operand: zir.Inst.Ref, - ) !zir.Inst.Ref { - return try gz.add(.{ + ) !zir.Inst.Index { + return gz.addAsIndex(.{ .tag = .@"break", .data = .{ .@"break" = .{ .block_inst = break_block, @@ -1237,15 +1237,14 @@ pub const Scope = struct { } pub fn addBreakVoid( - inner_gz: *GenZir, - block_gz: *GenZir, + gz: *GenZir, break_block: zir.Inst.Index, node_index: ast.Node.Index, - ) !zir.Inst.Ref { - return try inner_gz.add(.{ + ) !zir.Inst.Index { + return gz.addAsIndex(.{ .tag = .break_void_node, .data = .{ .break_void_node = .{ - .src_node = block_gz.zir_code.decl.nodeIndexToRelative(node_index), + .src_node = gz.zir_code.decl.nodeIndexToRelative(node_index), .block_inst = break_block, } }, }); @@ -1339,6 +1338,10 @@ pub const Scope = struct { } pub fn add(gz: *GenZir, inst: zir.Inst) !zir.Inst.Ref { + return gz.zir_code.indexToRef(try gz.addAsIndex(inst)); + } + + pub fn addAsIndex(gz: *GenZir, inst: zir.Inst) !zir.Inst.Index { const gpa = gz.zir_code.gpa; try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1); @@ -1346,7 +1349,7 @@ pub const Scope = struct { const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); gz.zir_code.instructions.appendAssumeCapacity(inst); gz.instructions.appendAssumeCapacity(new_index); - return gz.zir_code.indexToRef(new_index); + return new_index; } }; diff --git a/src/astgen.zig b/src/astgen.zig index cbaa965dc5..ed9c4afd7e 100644 --- a/src/astgen.zig +++ b/src/astgen.zig @@ -411,13 +411,16 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In return callExpr(mod, scope, rl, node, tree.callFull(node)); }, - .unreachable_literal => return gz.add(.{ - .tag = .@"unreachable", - .data = .{ .@"unreachable" = .{ - .safety = true, - .src_node = gz.zir_code.decl.nodeIndexToRelative(node), - } }, - }), + .unreachable_literal => { + _ = try gz.addAsIndex(.{ + .tag = .@"unreachable", + .data = .{ .@"unreachable" = .{ + .safety = true, + .src_node = gz.zir_code.decl.nodeIndexToRelative(node), + } }, + }); + return zir.Inst.Ref.unreachable_value; + }, .@"return" => return ret(mod, scope, node), .field_access => return fieldAccess(mod, scope, rl, node), .float_literal => return floatLiteral(mod, scope, rl, node), @@ -602,8 +605,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In .tagged_union_enum_tag_trailing, => return containerDecl(mod, scope, rl, tree.taggedUnionEnumTag(node)), - .@"break" => return breakExpr(mod, scope, rl, node), - .@"continue" => return continueExpr(mod, scope, rl, node), + .@"break" => return breakExpr(mod, scope, node), + .@"continue" => return continueExpr(mod, scope, node), .grouped_expression => return expr(mod, scope, rl, node_datas[node].lhs), .array_type => return arrayType(mod, scope, rl, node), .array_type_sentinel => return arrayTypeSentinel(mod, scope, rl, node), @@ -666,28 +669,19 @@ pub fn comptimeExpr( return result; } -fn breakExpr( - mod: *Module, - parent_scope: *Scope, - rl: ResultLoc, - node: ast.Node.Index, -) InnerError!zir.Inst.Ref { - const tree = parent_scope.tree(); +fn breakExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref { + const parent_gz = parent_scope.getGenZir(); + const tree = parent_gz.tree(); const node_datas = tree.nodes.items(.data); - const main_tokens = tree.nodes.items(.main_token); - - const break_token = main_tokens[node]; const break_label = node_datas[node].lhs; const rhs = node_datas[node].rhs; - const parent_gz = parent_scope.getGenZir(); - // Look for the label in the scope. var scope = parent_scope; while (true) { switch (scope.tag) { .gen_zir => { - const block_gz = scope.getGenZir(); + const block_gz = scope.cast(Scope.GenZir).?; const block_inst = blk: { if (break_label != 0) { @@ -705,8 +699,8 @@ fn breakExpr( }; if (rhs == 0) { - const result = try parent_gz.addBreakVoid(block_gz, block_inst, node); - return rvalue(mod, parent_scope, rl, result, node); + _ = try parent_gz.addBreakVoid(block_inst, node); + return zir.Inst.Ref.unreachable_value; } block_gz.break_count += 1; const prev_rvalue_rl_count = block_gz.rvalue_rl_count; @@ -721,13 +715,13 @@ fn breakExpr( if (have_store_to_block) { const zir_tags = parent_gz.zir_code.instructions.items(.tag); const zir_datas = parent_gz.zir_code.instructions.items(.data); - const last_inst = zir_tags.len - 2; - assert(zir_tags[last_inst] == .store_to_block_ptr); - assert(zir_datas[last_inst].bin.lhs == block_gz.rl_ptr); - try block_gz.labeled_store_to_block_ptr_list.append(mod.gpa, @intCast(zir.Inst.Ref, last_inst)); + const store_inst = @intCast(u32, zir_tags.len - 2); + assert(zir_tags[store_inst] == .store_to_block_ptr); + assert(zir_datas[store_inst].bin.lhs == block_gz.rl_ptr); + try block_gz.labeled_store_to_block_ptr_list.append(mod.gpa, store_inst); } } - return rvalue(mod, parent_scope, rl, br, node); + return zir.Inst.Ref.unreachable_value; }, .local_val => scope = scope.cast(Scope.LocalVal).?.parent, .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, @@ -735,18 +729,13 @@ fn breakExpr( const label_name = try mod.identifierTokenString(parent_scope, break_label); return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name}); } else { - return mod.failTok(parent_scope, break_token, "break expression outside loop", .{}); + return mod.failNode(parent_scope, node, "break expression outside loop", .{}); }, } } } -fn continueExpr( - mod: *Module, - parent_scope: *Scope, - rl: ResultLoc, - node: ast.Node.Index, -) InnerError!zir.Inst.Ref { +fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref { if (true) @panic("TODO update for zir-memory-layout"); const tree = parent_scope.tree(); const node_datas = tree.nodes.items(.data); @@ -776,10 +765,10 @@ fn continueExpr( continue; } - const result = try addZirInstTag(mod, parent_scope, src, .break_void, .{ + _ = try addZirInstTag(mod, parent_scope, src, .break_void, .{ .block = continue_block, }); - return rvalue(mod, parent_scope, rl, result); + return zir.Inst.Ref.unreachable_value; }, .local_val => scope = scope.cast(Scope.LocalVal).?.parent, .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, @@ -1769,11 +1758,11 @@ fn finishThenElseBlock( switch (strat.tag) { .break_void => { if (!wzc.refIsNoReturn(then_result)) { - _ = try then_scope.addBreakVoid(block_scope, then_break_block, then_src); + _ = try then_scope.addBreakVoid(then_break_block, then_src); } const elide_else = if (else_result != .none) wzc.refIsNoReturn(else_result) else false; if (!elide_else) { - _ = try else_scope.addBreakVoid(block_scope, main_block, else_src); + _ = try else_scope.addBreakVoid(main_block, else_src); } assert(!strat.elide_store_to_block_ptr_instructions); try setCondBrPayload(condbr, cond, then_scope, else_scope); @@ -1788,7 +1777,7 @@ fn finishThenElseBlock( _ = try else_scope.addBreak(main_block, else_result); } } else { - _ = try else_scope.addBreakVoid(block_scope, main_block, else_src); + _ = try else_scope.addBreakVoid(main_block, else_src); } if (strat.elide_store_to_block_ptr_instructions) { try setCondBrPayloadElideBlockStorePtr(condbr, cond, then_scope, else_scope); @@ -2799,7 +2788,8 @@ fn ret(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Re }; break :operand try expr(mod, scope, rl, operand_node); } else .void_value; - return gz.addUnNode(.ret_node, operand, node); + _ = try gz.addUnNode(.ret_node, operand, node); + return zir.Inst.Ref.unreachable_value; } fn identifier( |
