From 60318a1e39897a0535cf7699c2e4ab6366d0687f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 15 Jul 2024 18:54:41 -0700 Subject: frontend: move updateZirRefs to be single-threaded for simplicity's sake. This makes it O(M) instead of O(N*M) where N is tracked insts and M is number of changed source files. --- src/Compilation.zig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 76dc42fc64..3d80cdb6a1 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3596,6 +3596,11 @@ fn performAllTheWorkInner( if (comp.module) |zcu| { const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = .main }; + if (comp.incremental) { + const update_zir_refs_node = main_progress_node.start("Update ZIR References", 0); + defer update_zir_refs_node.end(); + try pt.updateZirRefs(); + } try reportMultiModuleErrors(pt); try zcu.flushRetryableFailures(); zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); @@ -4306,7 +4311,7 @@ fn workerAstGenFile( defer child_prog_node.end(); const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) }; - pt.astGenFile(file, file_index, path_digest, root_decl) catch |err| switch (err) { + pt.astGenFile(file, path_digest, root_decl) catch |err| switch (err) { error.AnalysisFail => return, else => { file.status = .retryable_failure; -- cgit v1.2.3 From 8cb09db4e357c265ef3465fd736d36366d37a0a3 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 15 Jul 2024 19:05:55 -0700 Subject: update some Module references to Zcu instead I ended up reverting my real change, so here's a consolation prize instead. --- src/Compilation.zig | 2 +- src/Zcu.zig | 57 +++++++++++++++++++++++++++-------------------------- 2 files changed, 30 insertions(+), 29 deletions(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 3d80cdb6a1..8243bc3620 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3595,7 +3595,7 @@ fn performAllTheWorkInner( } if (comp.module) |zcu| { - const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = .main }; + const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main }; if (comp.incremental) { const update_zir_refs_node = main_progress_node.start("Update ZIR References", 0); defer update_zir_refs_node.end(); diff --git a/src/Zcu.zig b/src/Zcu.zig index 36b4c95571..dbc2e5a2c4 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -1,5 +1,8 @@ -//! Compilation of all Zig source code is represented by one `Module`. -//! Each `Compilation` has exactly one or zero `Module`, depending on whether +//! Zig Compilation Unit +//! +//! Compilation of all Zig source code is represented by one `Zcu`. +//! +//! Each `Compilation` has exactly one or zero `Zcu`, depending on whether //! there is or is not any zig source code, respectively. const std = @import("std"); @@ -13,8 +16,6 @@ const BigIntMutable = std.math.big.int.Mutable; const Target = std.Target; const Ast = std.zig.Ast; -/// Deprecated, use `Zcu`. -const Module = Zcu; const Zcu = @This(); const Compilation = @import("Compilation.zig"); const Cache = std.Build.Cache; @@ -2393,7 +2394,7 @@ pub const CompileError = error{ ComptimeBreak, }; -pub fn init(mod: *Module, thread_count: usize) !void { +pub fn init(mod: *Zcu, thread_count: usize) !void { const gpa = mod.gpa; try mod.intern_pool.init(gpa, thread_count); } @@ -2487,20 +2488,20 @@ pub fn deinit(zcu: *Zcu) void { zcu.intern_pool.deinit(gpa); } -pub fn declPtr(mod: *Module, index: Decl.Index) *Decl { +pub fn declPtr(mod: *Zcu, index: Decl.Index) *Decl { return mod.intern_pool.declPtr(index); } -pub fn namespacePtr(mod: *Module, index: Namespace.Index) *Namespace { +pub fn namespacePtr(mod: *Zcu, index: Namespace.Index) *Namespace { return mod.intern_pool.namespacePtr(index); } -pub fn namespacePtrUnwrap(mod: *Module, index: Namespace.OptionalIndex) ?*Namespace { +pub fn namespacePtrUnwrap(mod: *Zcu, index: Namespace.OptionalIndex) ?*Namespace { return mod.namespacePtr(index.unwrap() orelse return null); } /// Returns true if and only if the Decl is the top level struct associated with a File. -pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool { +pub fn declIsRoot(mod: *Zcu, decl_index: Decl.Index) bool { const decl = mod.declPtr(decl_index); const namespace = mod.namespacePtr(decl.src_namespace); if (namespace.parent != .none) return false; @@ -2940,7 +2941,7 @@ pub fn mapOldZirToNew( /// analyzed, and for ensuring it can exist at runtime (see /// `sema.fnHasRuntimeBits`). This function does *not* guarantee that the body /// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`. -pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index) !void { +pub fn ensureFuncBodyAnalysisQueued(mod: *Zcu, func_index: InternPool.Index) !void { const ip = &mod.intern_pool; const func = mod.funcInfo(func_index); const decl_index = func.owner_decl; @@ -3102,13 +3103,13 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit gop.value_ptr.* = @intCast(ref_idx); } -pub fn errorSetBits(mod: *Module) u16 { +pub fn errorSetBits(mod: *Zcu) u16 { if (mod.error_limit == 0) return 0; return std.math.log2_int_ceil(ErrorInt, mod.error_limit + 1); // +1 for no error } pub fn errNote( - mod: *Module, + mod: *Zcu, src_loc: LazySrcLoc, parent: *ErrorMsg, comptime format: []const u8, @@ -3138,7 +3139,7 @@ pub fn optimizeMode(zcu: *const Zcu) std.builtin.OptimizeMode { return zcu.root_mod.optimize_mode; } -fn lockAndClearFileCompileError(mod: *Module, file: *File) void { +fn lockAndClearFileCompileError(mod: *Zcu, file: *File) void { switch (file.status) { .success_zir, .retryable_failure => {}, .never_loaded, .parse_failure, .astgen_failure => { @@ -3172,7 +3173,7 @@ pub fn handleUpdateExports( }; } -pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void { +pub fn addGlobalAssembly(mod: *Zcu, decl_index: Decl.Index, source: []const u8) !void { const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index); if (gop.found_existing) { const new_value = try std.fmt.allocPrint(mod.gpa, "{s}\n{s}", .{ gop.value_ptr.*, source }); @@ -3226,7 +3227,7 @@ pub const AtomicPtrAlignmentDiagnostics = struct { // TODO this function does not take into account CPU features, which can affect // this value. Audit this! pub fn atomicPtrAlignment( - mod: *Module, + mod: *Zcu, ty: Type, diags: *AtomicPtrAlignmentDiagnostics, ) AtomicPtrAlignmentError!Alignment { @@ -3332,7 +3333,7 @@ pub fn atomicPtrAlignment( return error.BadType; } -pub fn declFileScope(mod: *Module, decl_index: Decl.Index) *File { +pub fn declFileScope(mod: *Zcu, decl_index: Decl.Index) *File { return mod.declPtr(decl_index).getFileScope(mod); } @@ -3340,7 +3341,7 @@ pub fn declFileScope(mod: *Module, decl_index: Decl.Index) *File { /// * `@TypeOf(.{})` /// * A struct which has no fields (`struct {}`). /// * Not a struct. -pub fn typeToStruct(mod: *Module, ty: Type) ?InternPool.LoadedStructType { +pub fn typeToStruct(mod: *Zcu, ty: Type) ?InternPool.LoadedStructType { if (ty.ip_index == .none) return null; const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.ip_index)) { @@ -3349,13 +3350,13 @@ pub fn typeToStruct(mod: *Module, ty: Type) ?InternPool.LoadedStructType { }; } -pub fn typeToPackedStruct(mod: *Module, ty: Type) ?InternPool.LoadedStructType { +pub fn typeToPackedStruct(mod: *Zcu, ty: Type) ?InternPool.LoadedStructType { const s = mod.typeToStruct(ty) orelse return null; if (s.layout != .@"packed") return null; return s; } -pub fn typeToUnion(mod: *Module, ty: Type) ?InternPool.LoadedUnionType { +pub fn typeToUnion(mod: *Zcu, ty: Type) ?InternPool.LoadedUnionType { if (ty.ip_index == .none) return null; const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.ip_index)) { @@ -3364,32 +3365,32 @@ pub fn typeToUnion(mod: *Module, ty: Type) ?InternPool.LoadedUnionType { }; } -pub fn typeToFunc(mod: *Module, ty: Type) ?InternPool.Key.FuncType { +pub fn typeToFunc(mod: *Zcu, ty: Type) ?InternPool.Key.FuncType { if (ty.ip_index == .none) return null; return mod.intern_pool.indexToFuncType(ty.toIntern()); } -pub fn funcOwnerDeclPtr(mod: *Module, func_index: InternPool.Index) *Decl { +pub fn funcOwnerDeclPtr(mod: *Zcu, func_index: InternPool.Index) *Decl { return mod.declPtr(mod.funcOwnerDeclIndex(func_index)); } -pub fn funcOwnerDeclIndex(mod: *Module, func_index: InternPool.Index) Decl.Index { +pub fn funcOwnerDeclIndex(mod: *Zcu, func_index: InternPool.Index) Decl.Index { return mod.funcInfo(func_index).owner_decl; } -pub fn iesFuncIndex(mod: *const Module, ies_index: InternPool.Index) InternPool.Index { +pub fn iesFuncIndex(mod: *const Zcu, ies_index: InternPool.Index) InternPool.Index { return mod.intern_pool.iesFuncIndex(ies_index); } -pub fn funcInfo(mod: *Module, func_index: InternPool.Index) InternPool.Key.Func { +pub fn funcInfo(mod: *Zcu, func_index: InternPool.Index) InternPool.Key.Func { return mod.intern_pool.indexToKey(func_index).func; } -pub fn toEnum(mod: *Module, comptime E: type, val: Value) E { +pub fn toEnum(mod: *Zcu, comptime E: type, val: Value) E { return mod.intern_pool.toEnum(E, val.toIntern()); } -pub fn isAnytypeParam(mod: *Module, func: InternPool.Index, index: u32) bool { +pub fn isAnytypeParam(mod: *Zcu, func: InternPool.Index, index: u32) bool { const file = mod.declPtr(func.owner_decl).getFileScope(mod); const tags = file.zir.instructions.items(.tag); @@ -3404,7 +3405,7 @@ pub fn isAnytypeParam(mod: *Module, func: InternPool.Index, index: u32) bool { }; } -pub fn getParamName(mod: *Module, func_index: InternPool.Index, index: u32) [:0]const u8 { +pub fn getParamName(mod: *Zcu, func_index: InternPool.Index, index: u32) [:0]const u8 { const func = mod.funcInfo(func_index); const file = mod.declPtr(func.owner_decl).getFileScope(mod); @@ -3441,7 +3442,7 @@ pub const UnionLayout = struct { }; /// Returns the index of the active field, given the current tag value -pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 { +pub fn unionTagFieldIndex(mod: *Zcu, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 { const ip = &mod.intern_pool; if (enum_tag.toIntern() == .none) return null; assert(ip.typeOf(enum_tag.toIntern()) == loaded_union.enum_tag_ty); -- cgit v1.2.3