aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2024-02-02 03:19:23 +0000
committermlugg <mlugg@mlugg.co.uk>2024-02-04 18:38:39 +0000
commit7f4bd247c7735ccf277c9bba42222e014cacf856 (patch)
treeb47acb0631fc101995b03dd415efe587cec9738b /src/Sema.zig
parenta1b607acb5c1e9dd03760efd7078185e7628b29d (diff)
downloadzig-7f4bd247c7735ccf277c9bba42222e014cacf856.tar.gz
zig-7f4bd247c7735ccf277c9bba42222e014cacf856.zip
compiler: re-introduce dependencies for incremental compilation
Sema now tracks dependencies appropriately. Early logic in Zcu for resolving outdated decls/functions is in place. The setup used does not support `usingnamespace`; compilations using this construct are not yet supported by this incremental compilation model.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig86
1 files changed, 78 insertions, 8 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index e7f2677c8e..abbf7f69ec 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -2748,7 +2748,7 @@ pub fn getStructType(
const ty = try ip.getStructType(gpa, .{
.decl = decl,
.namespace = namespace.toOptional(),
- .zir_index = tracked_inst,
+ .zir_index = tracked_inst.toOptional(),
.layout = small.layout,
.known_non_opv = small.known_non_opv,
.is_tuple = small.is_tuple,
@@ -2789,6 +2789,12 @@ fn zirStructDecl(
new_decl.owns_tv = true;
errdefer mod.abortAnonDecl(new_decl_index);
+ try ip.addDependency(
+ sema.gpa,
+ InternPool.Depender.wrap(.{ .decl = new_decl_index }),
+ .{ .src_hash = try ip.trackZir(sema.gpa, block.getFileScope(mod), inst) },
+ );
+
const new_namespace_index = try mod.createNamespace(.{
.parent = block.namespace.toOptional(),
.ty = undefined,
@@ -2973,6 +2979,12 @@ fn zirEnumDecl(
new_decl.owns_tv = true;
errdefer if (!done) mod.abortAnonDecl(new_decl_index);
+ try mod.intern_pool.addDependency(
+ sema.gpa,
+ InternPool.Depender.wrap(.{ .decl = new_decl_index }),
+ .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
+ );
+
const new_namespace_index = try mod.createNamespace(.{
.parent = block.namespace.toOptional(),
.ty = undefined,
@@ -3008,6 +3020,7 @@ fn zirEnumDecl(
.auto
else
.explicit,
+ .zir_index = (try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst)).toOptional(),
});
if (sema.builtin_type_target_index != .none) {
mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, incomplete_enum.index);
@@ -3225,6 +3238,12 @@ fn zirUnionDecl(
new_decl.owns_tv = true;
errdefer mod.abortAnonDecl(new_decl_index);
+ try mod.intern_pool.addDependency(
+ sema.gpa,
+ InternPool.Depender.wrap(.{ .decl = new_decl_index }),
+ .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
+ );
+
const new_namespace_index = try mod.createNamespace(.{
.parent = block.namespace.toOptional(),
.ty = undefined,
@@ -3254,7 +3273,7 @@ fn zirUnionDecl(
},
.decl = new_decl_index,
.namespace = new_namespace_index,
- .zir_index = try mod.intern_pool.trackZir(gpa, block.getFileScope(mod), inst),
+ .zir_index = (try mod.intern_pool.trackZir(gpa, block.getFileScope(mod), inst)).toOptional(),
.fields_len = fields_len,
.enum_tag_ty = .none,
.field_types = &.{},
@@ -3318,6 +3337,12 @@ fn zirOpaqueDecl(
new_decl.owns_tv = true;
errdefer mod.abortAnonDecl(new_decl_index);
+ try mod.intern_pool.addDependency(
+ sema.gpa,
+ InternPool.Depender.wrap(.{ .decl = new_decl_index }),
+ .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
+ );
+
const new_namespace_index = try mod.createNamespace(.{
.parent = block.namespace.toOptional(),
.ty = undefined,
@@ -3329,6 +3354,7 @@ fn zirOpaqueDecl(
const opaque_ty = try mod.intern(.{ .opaque_type = .{
.decl = new_decl_index,
.namespace = new_namespace_index,
+ .zir_index = (try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst)).toOptional(),
} });
// TODO: figure out InternPool removals for incremental compilation
//errdefer mod.intern_pool.remove(opaque_ty);
@@ -7890,6 +7916,8 @@ fn instantiateGenericCall(
const generic_owner_func = mod.intern_pool.indexToKey(generic_owner).func;
const generic_owner_ty_info = mod.typeToFunc(Type.fromInterned(generic_owner_func.ty)).?;
+ try sema.declareDependency(.{ .src_hash = generic_owner_func.zir_body_inst });
+
// Even though there may already be a generic instantiation corresponding
// to this callsite, we must evaluate the expressions of the generic
// function signature with the values of the callsite plugged in.
@@ -13594,6 +13622,12 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
});
try sema.checkNamespaceType(block, lhs_src, container_type);
+ if (container_type.typeDeclInst(mod)) |type_decl_inst| {
+ try sema.declareDependency(.{ .namespace_name = .{
+ .namespace = type_decl_inst,
+ .name = decl_name,
+ } });
+ }
const namespace = container_type.getNamespaceIndex(mod).unwrap() orelse
return .bool_false;
@@ -17447,6 +17481,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const type_info_ty = try sema.getBuiltinType("Type");
const type_info_tag_ty = type_info_ty.unionTagType(mod).?;
+ if (ty.typeDeclInst(mod)) |type_decl_inst| {
+ try sema.declareDependency(.{ .namespace = type_decl_inst });
+ }
+
switch (ty.zigTypeTag(mod)) {
.Type,
.Void,
@@ -21313,6 +21351,7 @@ fn zirReify(
else
.explicit,
.tag_ty = int_tag_ty.toIntern(),
+ .zir_index = .none,
});
// TODO: figure out InternPool removals for incremental compilation
//errdefer ip.remove(incomplete_enum.index);
@@ -21410,6 +21449,7 @@ fn zirReify(
const opaque_ty = try mod.intern(.{ .opaque_type = .{
.decl = new_decl_index,
.namespace = new_namespace_index,
+ .zir_index = .none,
} });
// TODO: figure out InternPool removals for incremental compilation
//errdefer ip.remove(opaque_ty);
@@ -21628,7 +21668,7 @@ fn zirReify(
.namespace = new_namespace_index,
.enum_tag_ty = enum_tag_ty,
.fields_len = fields_len,
- .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst), // TODO: should reified types be handled differently?
+ .zir_index = .none,
.flags = .{
.layout = layout,
.status = .have_field_types,
@@ -21796,7 +21836,7 @@ fn reifyStruct(
const ty = try ip.getStructType(gpa, .{
.decl = new_decl_index,
.namespace = .none,
- .zir_index = try mod.intern_pool.trackZir(gpa, block.getFileScope(mod), inst), // TODO: should reified types be handled differently?
+ .zir_index = .none,
.layout = layout,
.known_non_opv = false,
.fields_len = fields_len,
@@ -26416,6 +26456,7 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void {
// owns the function.
try sema.ensureDeclAnalyzed(decl_index);
const tv = try mod.declPtr(decl_index).typedValue();
+ try sema.declareDependency(.{ .decl_val = decl_index });
assert(tv.ty.zigTypeTag(mod) == .Fn);
assert(try sema.fnHasRuntimeBits(tv.ty));
const func_index = tv.val.toIntern();
@@ -26837,6 +26878,13 @@ fn fieldVal(
const val = (try sema.resolveDefinedValue(block, object_src, dereffed_type)).?;
const child_type = val.toType();
+ if (child_type.typeDeclInst(mod)) |type_decl_inst| {
+ try sema.declareDependency(.{ .namespace_name = .{
+ .namespace = type_decl_inst,
+ .name = field_name,
+ } });
+ }
+
switch (try child_type.zigTypeTagOrPoison(mod)) {
.ErrorSet => {
switch (ip.indexToKey(child_type.toIntern())) {
@@ -27060,6 +27108,13 @@ fn fieldPtr(
const val = (sema.resolveDefinedValue(block, src, inner) catch unreachable).?;
const child_type = val.toType();
+ if (child_type.typeDeclInst(mod)) |type_decl_inst| {
+ try sema.declareDependency(.{ .namespace_name = .{
+ .namespace = type_decl_inst,
+ .name = field_name,
+ } });
+ }
+
switch (child_type.zigTypeTag(mod)) {
.ErrorSet => {
switch (ip.indexToKey(child_type.toIntern())) {
@@ -31129,6 +31184,7 @@ fn beginComptimePtrLoad(
const is_mutable = ptr.addr == .mut_decl;
const decl = mod.declPtr(decl_index);
const decl_tv = try decl.typedValue();
+ try sema.declareDependency(.{ .decl_val = decl_index });
if (decl.val.getVariable(mod) != null) return error.RuntimeLoad;
const layout_defined = decl.ty.hasWellDefinedLayout(mod);
@@ -32382,6 +32438,8 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn
const decl = mod.declPtr(decl_index);
const decl_tv = try decl.typedValue();
+ // TODO: if this is a `decl_ref`, only depend on decl type
+ try sema.declareDependency(.{ .decl_val = decl_index });
const ptr_ty = try sema.ptrType(.{
.child = decl_tv.ty.toIntern(),
.flags = .{
@@ -35678,7 +35736,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
break :blk accumulator;
};
- const zir_index = struct_type.zir_index.resolve(ip);
+ const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
assert(extended.opcode == .struct_decl);
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
@@ -36443,7 +36501,7 @@ fn semaStructFields(
const decl = mod.declPtr(decl_index);
const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace;
const zir = mod.namespacePtr(namespace_index).file_scope.zir;
- const zir_index = struct_type.zir_index.resolve(ip);
+ const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);
@@ -36714,7 +36772,7 @@ fn semaStructFieldInits(
const decl = mod.declPtr(decl_index);
const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace;
const zir = mod.namespacePtr(namespace_index).file_scope.zir;
- const zir_index = struct_type.zir_index.resolve(ip);
+ const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);
var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa);
@@ -36863,7 +36921,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
const ip = &mod.intern_pool;
const decl_index = union_type.decl;
const zir = mod.namespacePtr(union_type.namespace).file_scope.zir;
- const zir_index = union_type.zir_index.resolve(ip);
+ const zir_index = union_type.zir_index.unwrap().?.resolve(ip);
const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
assert(extended.opcode == .union_decl);
const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
@@ -37307,6 +37365,7 @@ fn generateUnionTagTypeNumbered(
.names = enum_field_names,
.values = enum_field_vals,
.tag_mode = .explicit,
+ .zir_index = .none,
});
new_decl.ty = Type.type;
@@ -37357,6 +37416,7 @@ fn generateUnionTagTypeSimple(
.names = enum_field_names,
.values = &.{},
.tag_mode = .auto,
+ .zir_index = .none,
});
const new_decl = mod.declPtr(new_decl_index);
@@ -38870,3 +38930,13 @@ fn ptrType(sema: *Sema, info: InternPool.Key.PtrType) CompileError!Type {
}
return sema.mod.ptrType(info);
}
+
+pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
+ const depender = InternPool.Depender.wrap(
+ if (sema.owner_func_index != .none)
+ .{ .func = sema.owner_func_index }
+ else
+ .{ .decl = sema.owner_decl_index },
+ );
+ try sema.mod.intern_pool.addDependency(sema.gpa, depender, dependee);
+}