aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-03-24 20:45:14 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-03-24 20:45:14 -0700
commit01bfd835bb9613d21f09c0c4f5b905b077b3d5f9 (patch)
tree89a9fe2ca68d2055abebee9f17b2136f8e5997cf /src
parentea42ab34abc0408b66ce2c0212afd4f5705e8d43 (diff)
downloadzig-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.zig23
-rw-r--r--src/astgen.zig74
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(