diff --git a/src/Compilation.zig b/src/Compilation.zig index ad184b2bc9..065b717931 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -848,6 +848,8 @@ const Job = union(enum) { /// This `Job` exists (instead of the `link.ZcuTask` being directly queued) to ensure that /// all types are resolved before the linker task is queued. /// If the backend does not support `Zcu.Feature.separate_thread`, codegen and linking happen immediately. + /// Before queueing this `Job`, increase the estimated total item count for both + /// `comp.zcu.?.codegen_prog_node` and `comp.link_prog_node`. codegen_func: struct { func: InternPool.Index, /// The AIR emitted from analyzing `func`; owned by this `Job` in `gpa`. @@ -857,12 +859,15 @@ const Job = union(enum) { /// This `Job` exists (instead of the `link.ZcuTask` being directly queued) to ensure that /// all types are resolved before the linker task is queued. /// If the backend does not support `Zcu.Feature.separate_thread`, the task is run immediately. + /// Before queueing this `Job`, increase the estimated total item count for `comp.link_prog_node`. link_nav: InternPool.Nav.Index, /// Queue a `link.ZcuTask` to emit debug information for this container type. /// This `Job` exists (instead of the `link.ZcuTask` being directly queued) to ensure that /// all types are resolved before the linker task is queued. /// If the backend does not support `Zcu.Feature.separate_thread`, the task is run immediately. + /// Before queueing this `Job`, increase the estimated total item count for `comp.link_prog_node`. link_type: InternPool.Index, + /// Before queueing this `Job`, increase the estimated total item count for `comp.link_prog_node`. update_line_number: InternPool.TrackedInst.Index, /// The `AnalUnit`, which is *not* a `func`, must be semantically analyzed. /// This may be its first time being analyzed, or it may be outdated. @@ -4592,11 +4597,17 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { const zcu = comp.zcu.?; const gpa = zcu.gpa; var air = func.air; - errdefer air.deinit(gpa); + errdefer { + zcu.codegen_prog_node.completeOne(); + comp.link_prog_node.completeOne(); + air.deinit(gpa); + } if (!air.typesFullyResolved(zcu)) { // Type resolution failed in a way which affects this function. This is a transitive // failure, but it doesn't need recording, because this function semantically depends // on the failed type, so when it is changed the function is updated. + zcu.codegen_prog_node.completeOne(); + comp.link_prog_node.completeOne(); air.deinit(gpa); return; } @@ -4606,7 +4617,6 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { .value = undefined, }; assert(zcu.pending_codegen_jobs.rmw(.Add, 1, .monotonic) > 0); // the "Code Generation" node hasn't been ended - zcu.codegen_prog_node.increaseEstimatedTotalItems(1); // This value is used as a heuristic to avoid queueing too much AIR/MIR at once (hence // using a lot of memory). If this would cause too many AIR bytes to be in-flight, we // will block on the `dispatchZcuLinkTask` call below. @@ -4640,6 +4650,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { if (nav.analysis != null) { const unit: InternPool.AnalUnit = .wrap(.{ .nav_val = nav_index }); if (zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit)) { + comp.link_prog_node.completeOne(); return; } } @@ -4648,6 +4659,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { // Type resolution failed in a way which affects this `Nav`. This is a transitive // failure, but it doesn't need recording, because this `Nav` semantically depends // on the failed type, so when it is changed the `Nav` will be updated. + comp.link_prog_node.completeOne(); return; } comp.dispatchZcuLinkTask(tid, .{ .link_nav = nav_index }); @@ -4659,6 +4671,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { // Type resolution failed in a way which affects this type. This is a transitive // failure, but it doesn't need recording, because this type semantically depends // on the failed type, so when that is changed, this type will be updated. + comp.link_prog_node.completeOne(); return; } comp.dispatchZcuLinkTask(tid, .{ .link_type = ty }); @@ -7460,7 +7473,6 @@ pub fn queuePrelinkTasks(comp: *Compilation, tasks: []const link.PrelinkTask) vo /// The reason for the double-queue here is that the first queue ensures any /// resolve_type_fully tasks are complete before this dispatch function is called. fn dispatchZcuLinkTask(comp: *Compilation, tid: usize, task: link.ZcuTask) void { - comp.link_prog_node.increaseEstimatedTotalItems(1); if (!comp.separateCodegenThreadOk()) { assert(tid == 0); if (task == .link_func) { diff --git a/src/Sema.zig b/src/Sema.zig index 310058a421..5b3e6419a6 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2992,6 +2992,7 @@ fn zirStructDecl( if (zcu.comp.config.use_llvm) break :codegen_type; if (block.ownerModule().strip) break :codegen_type; // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); } try sema.declareDependency(.{ .interned = wip_ty.index }); @@ -3266,6 +3267,7 @@ fn zirEnumDecl( if (zcu.comp.config.use_llvm) break :codegen_type; if (block.ownerModule().strip) break :codegen_type; // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); } return Air.internedToRef(wip_ty.index); @@ -3385,6 +3387,7 @@ fn zirUnionDecl( if (zcu.comp.config.use_llvm) break :codegen_type; if (block.ownerModule().strip) break :codegen_type; // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); } try sema.declareDependency(.{ .interned = wip_ty.index }); @@ -3473,6 +3476,7 @@ fn zirOpaqueDecl( if (zcu.comp.config.use_llvm) break :codegen_type; if (block.ownerModule().strip) break :codegen_type; // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); } try sema.addTypeReferenceEntry(src, wip_ty.index); @@ -20105,6 +20109,7 @@ fn structInitAnon( codegen_type: { if (zcu.comp.config.use_llvm) break :codegen_type; if (block.ownerModule().strip) break :codegen_type; + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip.index }); } if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index); @@ -21417,6 +21422,7 @@ fn reifyEnum( if (zcu.comp.config.use_llvm) break :codegen_type; if (block.ownerModule().strip) break :codegen_type; // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); } return Air.internedToRef(wip_ty.index); @@ -21671,6 +21677,7 @@ fn reifyUnion( if (zcu.comp.config.use_llvm) break :codegen_type; if (block.ownerModule().strip) break :codegen_type; // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); } try sema.declareDependency(.{ .interned = wip_ty.index }); @@ -22026,6 +22033,7 @@ fn reifyStruct( if (zcu.comp.config.use_llvm) break :codegen_type; if (block.ownerModule().strip) break :codegen_type; // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); } try sema.declareDependency(.{ .interned = wip_ty.index }); diff --git a/src/Sema/LowerZon.zig b/src/Sema/LowerZon.zig index b8064cefbf..8dfb710ac0 100644 --- a/src/Sema/LowerZon.zig +++ b/src/Sema/LowerZon.zig @@ -195,6 +195,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter codegen_type: { if (pt.zcu.comp.config.use_llvm) break :codegen_type; if (self.block.ownerModule().strip) break :codegen_type; + pt.zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try pt.zcu.comp.queueJob(.{ .link_type = wip.index }); } break :ty wip.finish(ip, new_namespace_index); diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 4ec6eebc46..4d90878420 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -1321,6 +1321,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr } // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_nav = nav_id }); } @@ -1717,6 +1718,8 @@ fn analyzeFuncBody( } // This job depends on any resolve_type_fully jobs queued up before it. + zcu.codegen_prog_node.increaseEstimatedTotalItems(1); + comp.link_prog_node.increaseEstimatedTotalItems(1); try comp.queueJob(.{ .codegen_func = .{ .func = func_index, .air = air, @@ -1799,6 +1802,7 @@ fn createFileRootStruct( codegen_type: { if (file.mod.?.strip) break :codegen_type; // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); } zcu.setFileRootType(file_index, wip_ty.index); @@ -3827,6 +3831,7 @@ pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) Allocator.Error! const result = try pt.zcu.intern_pool.getExtern(pt.zcu.gpa, pt.tid, key); if (result.new_nav.unwrap()) |nav| { // This job depends on any resolve_type_fully jobs queued up before it. + pt.zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try pt.zcu.comp.queueJob(.{ .link_nav = nav }); if (pt.zcu.comp.debugIncremental()) try pt.zcu.incremental_debug_state.newNav(pt.zcu, nav); } @@ -3974,6 +3979,7 @@ fn recreateStructType( codegen_type: { if (file.mod.?.strip) break :codegen_type; // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); } @@ -4066,6 +4072,7 @@ fn recreateUnionType( codegen_type: { if (file.mod.?.strip) break :codegen_type; // This job depends on any resolve_type_fully jobs queued up before it. + zcu.comp.link_prog_node.increaseEstimatedTotalItems(1); try zcu.comp.queueJob(.{ .link_type = wip_ty.index }); }