aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig125
1 files changed, 78 insertions, 47 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 55e301c21c..d535a6d580 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -477,7 +477,7 @@ pub const Scope = struct {
switch (scope.tag) {
.file => return &scope.cast(File).?.tree,
.block => return &scope.cast(Block).?.src_decl.container.file_scope.tree,
- .gen_zir => return &scope.cast(GenZir).?.zir_code.decl.container.file_scope.tree,
+ .gen_zir => return scope.cast(GenZir).?.tree(),
.local_val => return &scope.cast(LocalVal).?.gen_zir.zir_code.decl.container.file_scope.tree,
.local_ptr => return &scope.cast(LocalPtr).?.gen_zir.zir_code.decl.container.file_scope.tree,
.container => return &scope.cast(Container).?.file_scope.tree,
@@ -983,6 +983,30 @@ pub const Scope = struct {
return gz.zir_code.decl.nodeSrcLoc(node_index);
}
+ pub fn tree(gz: *const GenZir) *const ast.Tree {
+ return &gz.zir_code.decl.container.file_scope.tree;
+ }
+
+ pub fn setBoolBrBody(gz: GenZir, inst: zir.Inst.Index) !void {
+ try gz.zir_code.extra.ensureCapacity(gz.zir_code.gpa, gz.zir_code.extra.items.len +
+ @typeInfo(zir.Inst.Block).Struct.fields.len + gz.instructions.items.len);
+ const zir_datas = gz.zir_code.instructions.items(.data);
+ zir_datas[inst].bool_br.payload_index = gz.zir_code.addExtraAssumeCapacity(
+ zir.Inst.Block{ .body_len = @intCast(u32, gz.instructions.items.len) },
+ );
+ gz.zir_code.extra.appendSliceAssumeCapacity(gz.instructions.items);
+ }
+
+ pub fn setBlockBody(gz: GenZir, inst: zir.Inst.Index) !void {
+ try gz.zir_code.extra.ensureCapacity(gz.zir_code.gpa, gz.zir_code.extra.items.len +
+ @typeInfo(zir.Inst.Block).Struct.fields.len + gz.instructions.items.len);
+ const zir_datas = gz.zir_code.instructions.items(.data);
+ zir_datas[inst].pl_node.payload_index = gz.zir_code.addExtraAssumeCapacity(
+ zir.Inst.Block{ .body_len = @intCast(u32, gz.instructions.items.len) },
+ );
+ gz.zir_code.extra.appendSliceAssumeCapacity(gz.instructions.items);
+ }
+
pub fn addFnTypeCc(gz: *GenZir, tag: zir.Inst.Tag, args: struct {
param_types: []const zir.Inst.Ref,
ret_ty: zir.Inst.Ref,
@@ -1044,73 +1068,62 @@ pub const Scope = struct {
return new_index + gz.zir_code.ref_start_index;
}
- pub fn addCondBr(
+ pub fn addCall(
gz: *GenZir,
- condition: zir.Inst.Ref,
- then_body: []const zir.Inst.Ref,
- else_body: []const zir.Inst.Ref,
+ tag: zir.Inst.Tag,
+ callee: zir.Inst.Ref,
+ args: []const zir.Inst.Ref,
/// Absolute node index. This function does the conversion to offset from Decl.
abs_node_index: ast.Node.Index,
- ) !zir.Inst.Ref {
+ ) !zir.Inst.Index {
+ assert(callee != 0);
+ assert(abs_node_index != 0);
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);
try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +
- @typeInfo(zir.Inst.CondBr).Struct.fields.len + then_body.len + else_body.len);
+ @typeInfo(zir.Inst.Call).Struct.fields.len + args.len);
- const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.CondBr{
- .condition = condition,
- .then_body_len = @intCast(u32, then_body.len),
- .else_body_len = @intCast(u32, else_body.len),
+ const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.Call{
+ .callee = callee,
+ .args_len = @intCast(u32, args.len),
});
- gz.zir_code.extra.appendSliceAssumeCapacity(then_body);
- gz.zir_code.extra.appendSliceAssumeCapacity(else_body);
+ gz.zir_code.extra.appendSliceAssumeCapacity(args);
const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);
gz.zir_code.instructions.appendAssumeCapacity(.{
- .tag = .condbr,
+ .tag = tag,
.data = .{ .pl_node = .{
.src_node = gz.zir_code.decl.nodeIndexToRelative(abs_node_index),
.payload_index = payload_index,
} },
});
gz.instructions.appendAssumeCapacity(new_index);
-
return new_index + gz.zir_code.ref_start_index;
}
- pub fn addCall(
+ /// Note that this returns a `zir.Inst.Index` not a ref.
+ /// Leaves the `payload_index` field undefined.
+ pub fn addBoolBr(
gz: *GenZir,
tag: zir.Inst.Tag,
- callee: zir.Inst.Ref,
- args: []const zir.Inst.Ref,
- /// Absolute node index. This function does the conversion to offset from Decl.
- abs_node_index: ast.Node.Index,
+ lhs: zir.Inst.Ref,
) !zir.Inst.Index {
- assert(callee != 0);
- assert(abs_node_index != 0);
+ assert(lhs != 0);
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);
- try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +
- @typeInfo(zir.Inst.Call).Struct.fields.len + args.len);
-
- const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.Call{
- .callee = callee,
- .args_len = @intCast(u32, args.len),
- });
- gz.zir_code.extra.appendSliceAssumeCapacity(args);
const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);
gz.zir_code.instructions.appendAssumeCapacity(.{
.tag = tag,
- .data = .{ .pl_node = .{
- .src_node = gz.zir_code.decl.nodeIndexToRelative(abs_node_index),
- .payload_index = payload_index,
+ .data = .{ .bool_br = .{
+ .lhs = lhs,
+ .payload_index = undefined,
} },
});
gz.instructions.appendAssumeCapacity(new_index);
- return new_index + gz.zir_code.ref_start_index;
+ return new_index;
}
pub fn addInt(gz: *GenZir, integer: u64) !zir.Inst.Ref {
@@ -1291,6 +1304,20 @@ pub const Scope = struct {
return new_index;
}
+ /// Note that this returns a `zir.Inst.Index` not a ref.
+ /// Leaves the `payload_index` field undefined.
+ pub fn addCondBr(gz: *GenZir, node: ast.Node.Index) !zir.Inst.Index {
+ const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);
+ try gz.zir_code.instructions.append(gz.zir_code.gpa, .{
+ .tag = .condbr,
+ .data = .{ .pl_node = .{
+ .src_node = gz.zir_code.decl.nodeIndexToRelative(node),
+ .payload_index = undefined,
+ } },
+ });
+ return new_index;
+ }
+
pub fn add(gz: *GenZir, inst: zir.Inst) !zir.Inst.Ref {
const gpa = gz.zir_code.gpa;
try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
@@ -1409,9 +1436,9 @@ pub const WipZirCode = struct {
.bitcast_result_ptr,
.bit_or,
.block,
- .block_flat,
.block_comptime,
- .block_comptime_flat,
+ .bool_br_and,
+ .bool_br_or,
.bool_not,
.bool_and,
.bool_or,
@@ -1461,9 +1488,6 @@ pub const WipZirCode = struct {
.ret_type,
.shl,
.shr,
- .store,
- .store_to_block_ptr,
- .store_to_inferred_ptr,
.str,
.sub,
.subwrap,
@@ -1497,7 +1521,6 @@ pub const WipZirCode = struct {
.slice_sentinel,
.import,
.typeof_peer,
- .resolve_inferred_alloc,
=> return false,
.breakpoint,
@@ -1509,6 +1532,7 @@ pub const WipZirCode = struct {
.ensure_err_payload_void,
.@"break",
.break_void_tok,
+ .break_flat,
.condbr,
.compile_error,
.ret_node,
@@ -1517,6 +1541,10 @@ pub const WipZirCode = struct {
.@"unreachable",
.loop,
.elided,
+ .store,
+ .store_to_block_ptr,
+ .store_to_inferred_ptr,
+ .resolve_inferred_alloc,
=> return true,
}
}
@@ -2150,7 +2178,7 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
};
defer block_scope.instructions.deinit(mod.gpa);
- try sema.root(&block_scope);
+ _ = try sema.root(&block_scope);
decl.analysis = .complete;
decl.generation = mod.generation;
@@ -2338,6 +2366,7 @@ fn astgenAndSemaFn(
const tag: zir.Inst.Tag = if (is_var_args) .fn_type_var_args else .fn_type;
break :fn_type try fn_type_scope.addFnType(tag, return_type_inst, param_types);
};
+ _ = try fn_type_scope.addUnNode(.break_flat, fn_type_inst, 0);
// We need the memory for the Type to go into the arena for the Decl
var decl_arena = std.heap.ArenaAllocator.init(mod.gpa);
@@ -2370,7 +2399,7 @@ fn astgenAndSemaFn(
};
defer block_scope.instructions.deinit(mod.gpa);
- const fn_type = try fn_type_sema.rootAsType(&block_scope, fn_type_inst);
+ const fn_type = try fn_type_sema.rootAsType(&block_scope);
if (body_node == 0) {
if (!is_extern) {
return mod.failNode(&block_scope.base, fn_proto.ast.fn_token, "non-extern function has no body", .{});
@@ -2650,6 +2679,7 @@ fn astgenAndSemaVarDecl(
init_result_loc,
var_decl.ast.init_node,
);
+ _ = try gen_scope.addUnNode(.break_flat, init_inst, var_decl.ast.init_node);
var code = try gen_scope.finish();
defer code.deinit(mod.gpa);
if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
@@ -2676,10 +2706,9 @@ fn astgenAndSemaVarDecl(
};
defer block_scope.instructions.deinit(mod.gpa);
- try sema.root(&block_scope);
-
+ const init_inst_zir_ref = try sema.root(&block_scope);
// The result location guarantees the type coercion.
- const analyzed_init_inst = try sema.resolveInst(init_inst);
+ const analyzed_init_inst = try sema.resolveInst(init_inst_zir_ref);
// The is_comptime in the Scope.Block guarantees the result is comptime-known.
const val = analyzed_init_inst.value().?;
@@ -2713,6 +2742,8 @@ fn astgenAndSemaVarDecl(
defer type_scope.instructions.deinit(mod.gpa);
const var_type = try astgen.typeExpr(mod, &type_scope.base, var_decl.ast.type_node);
+ _ = try type_scope.addUnNode(.break_flat, var_type, 0);
+
var code = try type_scope.finish();
defer code.deinit(mod.gpa);
if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
@@ -2739,7 +2770,7 @@ fn astgenAndSemaVarDecl(
};
defer block_scope.instructions.deinit(mod.gpa);
- const ty = try sema.rootAsType(&block_scope, var_type);
+ const ty = try sema.rootAsType(&block_scope);
break :vi .{
.ty = try ty.copy(&decl_arena.allocator),
@@ -3328,7 +3359,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !void {
func.state = .in_progress;
log.debug("set {s} to in_progress", .{decl.name});
- try sema.root(&inner_block);
+ _ = try sema.root(&inner_block);
const instructions = try arena.allocator.dupe(*ir.Inst, inner_block.instructions.items);
func.state = .success;