From 1ccc68f307d4a2208118a8798d43119d63b53e05 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 3 Nov 2023 12:08:33 -0700 Subject: [PATCH] frontend: rip out Decl dependencies This incremental compilation logic will need to be reworked so that it does not depend on buried pointers - that is, long-lived pointers that are owned by non-top-level objects such as Decl. In the meantime, this fixes memory leaks since the memory management of these dependencies has bitrotted. --- src/Compilation.zig | 1 - src/Module.zig | 119 +------------------------------------------- src/Sema.zig | 34 ------------- 3 files changed, 2 insertions(+), 152 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 954acd44b7..f51500cf43 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2266,7 +2266,6 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void const decl_index = module.deletion_set.keys()[0]; const decl = module.declPtr(decl_index); assert(decl.deletion_flag); - assert(decl.dependants.count() == 0); assert(decl.zir_decl_index != .none); try module.clearDecl(decl_index, null); diff --git a/src/Module.zig b/src/Module.zig index b051ced66f..707ff41615 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -463,13 +463,6 @@ pub const Decl = struct { /// What kind of a declaration is this. kind: Kind, - /// The shallow set of other decls whose typed_value could possibly change if this Decl's - /// typed_value is modified. - dependants: DepsTable = .{}, - /// The shallow set of other decls whose typed_value changing indicates that this Decl's - /// typed_value may need to be regenerated. - dependencies: DepsTable = .{}, - pub const Kind = enum { @"usingnamespace", @"test", @@ -2626,8 +2619,6 @@ pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void { mod.destroyNamespace(i); } } - decl.dependants.deinit(gpa); - decl.dependencies.deinit(gpa); } ip.destroyDecl(gpa, decl_index); @@ -3278,16 +3269,6 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void { // prior to re-analysis. try mod.deleteDeclExports(decl_index); - // Dependencies will be re-discovered, so we remove them here prior to re-analysis. - for (decl.dependencies.keys()) |dep_index| { - const dep = mod.declPtr(dep_index); - dep.removeDependant(decl_index); - if (dep.dependants.count() == 0 and !dep.deletion_flag) { - try mod.markDeclForDeletion(dep_index); - } - } - decl.dependencies.clearRetainingCapacity(); - break :blk true; }, @@ -3331,33 +3312,8 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void { }; if (subsequent_analysis) { - // Update all dependents which have at least this level of dependency. - // If our type remained the same and we're a function, only update - // decls which depend on our body; otherwise, update all dependents. - const update_level: Decl.DepType = if (!type_changed and decl.ty.zigTypeTag(mod) == .Fn) .function_body else .normal; - - for (decl.dependants.keys(), decl.dependants.values()) |dep_index, dep_type| { - if (@intFromEnum(dep_type) < @intFromEnum(update_level)) continue; - - const dep = mod.declPtr(dep_index); - switch (dep.analysis) { - .unreferenced => unreachable, - .in_progress => continue, // already doing analysis, ok - .outdated => continue, // already queued for update - - .file_failure, - .dependency_failure, - .sema_failure, - .sema_failure_retryable, - .liveness_failure, - .codegen_failure, - .codegen_failure_retryable, - .complete, - => if (dep.generation != mod.generation) { - try mod.markOutdatedDecl(dep_index); - }, - } - } + _ = type_changed; + @panic("TODO re-implement incremental compilation"); } } @@ -3938,37 +3894,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { return type_changed; } -/// Returns the depender's index of the dependee. -pub fn declareDeclDependency(mod: *Module, depender_index: Decl.Index, dependee_index: Decl.Index) !void { - return mod.declareDeclDependencyType(depender_index, dependee_index, .normal); -} - -/// Returns the depender's index of the dependee. -pub fn declareDeclDependencyType(mod: *Module, depender_index: Decl.Index, dependee_index: Decl.Index, dep_type: Decl.DepType) !void { - if (depender_index == dependee_index) return; - - const depender = mod.declPtr(depender_index); - const dependee = mod.declPtr(dependee_index); - - if (depender.dependencies.get(dependee_index)) |cur_type| { - if (@intFromEnum(cur_type) >= @intFromEnum(dep_type)) { - // We already have this dependency (or stricter) marked - return; - } - } - - if (dependee.deletion_flag) { - dependee.deletion_flag = false; - assert(mod.deletion_set.swapRemove(dependee_index)); - } - - try depender.dependencies.ensureUnusedCapacity(mod.gpa, 1); - try dependee.dependants.ensureUnusedCapacity(mod.gpa, 1); - - dependee.dependants.putAssumeCapacity(depender_index, dep_type); - depender.dependencies.putAssumeCapacity(dependee_index, dep_type); -} - pub const ImportFileResult = struct { file: *File, is_new: bool, @@ -4508,36 +4433,11 @@ pub fn clearDecl( const decl = mod.declPtr(decl_index); const gpa = mod.gpa; - try mod.deletion_set.ensureUnusedCapacity(gpa, decl.dependencies.count()); if (outdated_decls) |map| { _ = map.swapRemove(decl_index); - try map.ensureUnusedCapacity(decl.dependants.count()); } - // Remove itself from its dependencies. - for (decl.dependencies.keys()) |dep_index| { - const dep = mod.declPtr(dep_index); - dep.removeDependant(decl_index); - if (dep.dependants.count() == 0 and !dep.deletion_flag) { - // We don't recursively perform a deletion here, because during the update, - // another reference to it may turn up. - dep.deletion_flag = true; - mod.deletion_set.putAssumeCapacity(dep_index, {}); - } - } - decl.dependencies.clearRetainingCapacity(); - - // Anything that depends on this deleted decl needs to be re-analyzed. - for (decl.dependants.keys()) |dep_index| { - const dep = mod.declPtr(dep_index); - dep.removeDependency(decl_index); - if (outdated_decls) |map| { - map.putAssumeCapacity(dep_index, {}); - } - } - decl.dependants.clearRetainingCapacity(); - if (mod.failed_decls.fetchSwapRemove(decl_index)) |kv| { kv.value.destroy(gpa); } @@ -4598,19 +4498,7 @@ fn markDeclForDeletion(mod: *Module, decl_index: Decl.Index) !void { /// Cancel the creation of an anon decl and delete any references to it. /// If other decls depend on this decl, they must be aborted first. pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void { - const decl = mod.declPtr(decl_index); - assert(!mod.declIsRoot(decl_index)); - - // An aborted decl must not have dependants -- they must have - // been aborted first and removed from this list. - assert(decl.dependants.count() == 0); - - for (decl.dependencies.keys()) |dep_index| { - const dep = mod.declPtr(dep_index); - dep.removeDependant(decl_index); - } - mod.destroyDecl(decl_index); } @@ -5694,9 +5582,6 @@ pub fn populateTestFunctions( .storage = .{ .elems = test_fn_vals }, } })).toValue(), }); - for (array_decl_dependencies.items) |array_decl_dependency| { - try mod.declareDeclDependency(array_decl_index, array_decl_dependency); - } break :d array_decl_index; }; diff --git a/src/Sema.zig b/src/Sema.zig index 325bd8e645..5dec7cf0a8 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -4006,7 +4006,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com .inferred_alloc_comptime => { const iac = sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime; const decl_index = iac.decl_index; - try mod.declareDeclDependency(sema.owner_decl_index, decl_index); const decl = mod.declPtr(decl_index); if (iac.is_const) _ = try decl.internValue(mod); @@ -6411,7 +6410,6 @@ fn lookupInNamespace( const namespace_decl_index = namespace.getDeclIndex(mod); const namespace_decl = mod.declPtr(namespace_decl_index); if (namespace_decl.analysis == .file_failure) { - try mod.declareDeclDependency(sema.owner_decl_index, namespace_decl_index); return error.AnalysisFail; } @@ -6473,7 +6471,6 @@ fn lookupInNamespace( 0 => {}, 1 => { const decl_index = candidates.items[0]; - try mod.declareDeclDependency(sema.owner_decl_index, decl_index); return decl_index; }, else => { @@ -6491,14 +6488,9 @@ fn lookupInNamespace( }, } } else if (namespace.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .mod = mod })) |decl_index| { - try mod.declareDeclDependency(sema.owner_decl_index, decl_index); return decl_index; } - // TODO This dependency is too strong. Really, it should only be a dependency - // on the non-existence of `ident_name` in the namespace. We can lessen the number of - // outdated declarations by making this dependency more sophisticated. - try mod.declareDeclDependency(sema.owner_decl_index, namespace_decl_index); return null; } @@ -7318,8 +7310,6 @@ fn analyzeCall( ); defer ics.deinit(); - try mod.declareDeclDependencyType(ics.callee().owner_decl_index, module_fn.owner_decl, .function_body); - var child_block: Block = .{ .parent = null, .sema = sema, @@ -16856,7 +16846,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Fn"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, fn_info_decl_index); try sema.ensureDeclAnalyzed(fn_info_decl_index); const fn_info_decl = mod.declPtr(fn_info_decl_index); const fn_info_ty = fn_info_decl.val.toType(); @@ -16867,7 +16856,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai fn_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Param"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, param_info_decl_index); try sema.ensureDeclAnalyzed(param_info_decl_index); const param_info_decl = mod.declPtr(param_info_decl_index); const param_info_ty = param_info_decl.val.toType(); @@ -16967,7 +16955,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Int"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, int_info_decl_index); try sema.ensureDeclAnalyzed(int_info_decl_index); const int_info_decl = mod.declPtr(int_info_decl_index); const int_info_ty = int_info_decl.val.toType(); @@ -16996,7 +16983,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Float"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, float_info_decl_index); try sema.ensureDeclAnalyzed(float_info_decl_index); const float_info_decl = mod.declPtr(float_info_decl_index); const float_info_ty = float_info_decl.val.toType(); @@ -17029,7 +17015,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Pointer"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, decl_index); try sema.ensureDeclAnalyzed(decl_index); const decl = mod.declPtr(decl_index); break :t decl.val.toType(); @@ -17041,7 +17026,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai pointer_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Size"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, decl_index); try sema.ensureDeclAnalyzed(decl_index); const decl = mod.declPtr(decl_index); break :t decl.val.toType(); @@ -17085,7 +17069,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Array"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, array_field_ty_decl_index); try sema.ensureDeclAnalyzed(array_field_ty_decl_index); const array_field_ty_decl = mod.declPtr(array_field_ty_decl_index); break :t array_field_ty_decl.val.toType(); @@ -17117,7 +17100,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Vector"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, vector_field_ty_decl_index); try sema.ensureDeclAnalyzed(vector_field_ty_decl_index); const vector_field_ty_decl = mod.declPtr(vector_field_ty_decl_index); break :t vector_field_ty_decl.val.toType(); @@ -17147,7 +17129,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Optional"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, optional_field_ty_decl_index); try sema.ensureDeclAnalyzed(optional_field_ty_decl_index); const optional_field_ty_decl = mod.declPtr(optional_field_ty_decl_index); break :t optional_field_ty_decl.val.toType(); @@ -17175,7 +17156,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Error"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index); try sema.ensureDeclAnalyzed(set_field_ty_decl_index); const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index); break :t set_field_ty_decl.val.toType(); @@ -17274,7 +17254,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "ErrorUnion"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, error_union_field_ty_decl_index); try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index); const error_union_field_ty_decl = mod.declPtr(error_union_field_ty_decl_index); break :t error_union_field_ty_decl.val.toType(); @@ -17305,7 +17284,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "EnumField"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index); try sema.ensureDeclAnalyzed(enum_field_ty_decl_index); const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index); break :t enum_field_ty_decl.val.toType(); @@ -17390,7 +17368,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Enum"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, type_enum_ty_decl_index); try sema.ensureDeclAnalyzed(type_enum_ty_decl_index); const type_enum_ty_decl = mod.declPtr(type_enum_ty_decl_index); break :t type_enum_ty_decl.val.toType(); @@ -17423,7 +17400,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Union"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, type_union_ty_decl_index); try sema.ensureDeclAnalyzed(type_union_ty_decl_index); const type_union_ty_decl = mod.declPtr(type_union_ty_decl_index); break :t type_union_ty_decl.val.toType(); @@ -17436,7 +17412,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "UnionField"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index); try sema.ensureDeclAnalyzed(union_field_ty_decl_index); const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index); break :t union_field_ty_decl.val.toType(); @@ -17531,7 +17506,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "ContainerLayout"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, decl_index); try sema.ensureDeclAnalyzed(decl_index); const decl = mod.declPtr(decl_index); break :t decl.val.toType(); @@ -17565,7 +17539,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Struct"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, type_struct_ty_decl_index); try sema.ensureDeclAnalyzed(type_struct_ty_decl_index); const type_struct_ty_decl = mod.declPtr(type_struct_ty_decl_index); break :t type_struct_ty_decl.val.toType(); @@ -17578,7 +17551,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "StructField"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index); try sema.ensureDeclAnalyzed(struct_field_ty_decl_index); const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index); break :t struct_field_ty_decl.val.toType(); @@ -17751,7 +17723,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "ContainerLayout"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, decl_index); try sema.ensureDeclAnalyzed(decl_index); const decl = mod.declPtr(decl_index); break :t decl.val.toType(); @@ -17788,7 +17759,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai type_info_ty.getNamespaceIndex(mod).unwrap().?, try ip.getOrPutString(gpa, "Opaque"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, type_opaque_ty_decl_index); try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index); const type_opaque_ty_decl = mod.declPtr(type_opaque_ty_decl_index); break :t type_opaque_ty_decl.val.toType(); @@ -17832,7 +17802,6 @@ fn typeInfoDecls( type_info_ty.getNamespaceIndex(mod).unwrap().?, try mod.intern_pool.getOrPutString(gpa, "Declaration"), )).?; - try mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index); try sema.ensureDeclAnalyzed(declaration_ty_decl_index); const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index); break :t declaration_ty_decl.val.toType(); @@ -25237,7 +25206,6 @@ fn zirBuiltinExtern( new_decl.generation = mod.generation; } - try mod.declareDeclDependency(sema.owner_decl_index, new_decl_index); try sema.ensureDeclAnalyzed(new_decl_index); return Air.internedToRef((try mod.getCoerced((try mod.intern(.{ .ptr = .{ @@ -31640,7 +31608,6 @@ fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref /// this function with `analyze_fn_body` set to true. fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: bool) CompileError!Air.Inst.Ref { const mod = sema.mod; - try mod.declareDeclDependency(sema.owner_decl_index, decl_index); try sema.ensureDeclAnalyzed(decl_index); const decl = mod.declPtr(decl_index); @@ -36895,7 +36862,6 @@ fn analyzeComptimeAlloc( decl.alignment = alignment; try sema.comptime_mutable_decls.append(decl_index); - try mod.declareDeclDependency(sema.owner_decl_index, decl_index); return Air.internedToRef((try mod.intern(.{ .ptr = .{ .ty = ptr_type.toIntern(), .addr = .{ .mut_decl = .{