From 5f7a0bbabfde4eeb0ff4f40f0942ef710b6104a1 Mon Sep 17 00:00:00 2001 From: mlugg Date: Fri, 8 Aug 2025 09:13:38 +0100 Subject: [PATCH] Sema: fix unreasonable progress node numbers The "completed" count in the "Semantic Analysis" progress node had regressed since 0.14.0: the number got crazy big very fast, even on simple cases. For instance, an empty `pub fn main` got to ~59,000 where on 0.14 it only reached ~4,000. This was happening because I was unintentionally introducing a node every time type resolution was *requested*, even if (as is usually the case) it turned out to already be done. The fix is simply to start the progress node a little later, once we know we are actually doing semantic analysis. This brings the number for that empty test case down to ~5,000, which makes perfect sense. It won't exactly match 0.14, because the standard library has changed, and also because the compiler's progress output does have some *intentional* changes. --- src/Sema.zig | 30 ++++++++++++++++++++++++++++++ src/Type.zig | 6 ------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index d06545e164..8680ff0d05 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -34199,6 +34199,9 @@ pub fn resolveStructAlignment( if (struct_type.assumePointerAlignedIfWip(ip, ptr_align)) return; defer struct_type.clearAlignmentWip(ip); + // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis. + // It's just triggering *other* analysis, alongside a simple loop over already-resolved info. + var alignment: Alignment = .@"1"; for (0..struct_type.field_types.len) |i| { @@ -34229,6 +34232,9 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { try sema.resolveStructFieldTypes(ty.toIntern(), struct_type); + // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis. + // It's just triggering *other* analysis, alongside a simple loop over already-resolved info. + if (struct_type.layout == .@"packed") { sema.backingIntType(struct_type) catch |err| switch (err) { error.OutOfMemory, error.AnalysisFail => |e| return e, @@ -34532,6 +34538,9 @@ pub fn resolveUnionAlignment( try sema.resolveUnionFieldTypes(ty, union_type); + // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis. + // It's just triggering *other* analysis, alongside a simple loop over already-resolved info. + var max_align: Alignment = .@"1"; for (0..union_type.field_types.len) |field_index| { const field_ty: Type = .fromInterned(union_type.field_types.get(ip)[field_index]); @@ -34579,6 +34588,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { union_type.setStatus(ip, .layout_wip); + // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis. + // It's just triggering *other* analysis, alongside a simple loop over already-resolved info. + var max_size: u64 = 0; var max_align: Alignment = .@"1"; for (0..union_type.field_types.len) |field_index| { @@ -34695,6 +34707,9 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { if (struct_type.setFullyResolved(ip)) return; errdefer struct_type.clearFullyResolved(ip); + // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis. + // It's just triggering *other* analysis, alongside a simple loop over already-resolved info. + // After we have resolve struct layout we have to go over the fields again to // make sure pointer fields get their child types resolved as well. // See also similar code for unions. @@ -34720,6 +34735,9 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { .fully_resolved_wip, .fully_resolved => return, } + // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis. + // It's just triggering *other* analysis, alongside a simple loop over already-resolved info. + { // After we have resolve union layout we have to go over the fields again to // make sure pointer fields get their child types resolved as well. @@ -34762,6 +34780,10 @@ pub fn resolveStructFieldTypes( } defer struct_type.clearFieldTypesWip(ip); + // can't happen earlier than this because we only want the progress node if not already resolved + const tracked_unit = zcu.trackUnitSema(struct_type.name.toSlice(ip), null); + defer tracked_unit.end(zcu); + sema.structFields(struct_type) catch |err| switch (err) { error.AnalysisFail, error.OutOfMemory => |e| return e, error.ComptimeBreak, error.ComptimeReturn => unreachable, @@ -34791,6 +34813,10 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { } defer struct_type.clearInitsWip(ip); + // can't happen earlier than this because we only want the progress node if not already resolved + const tracked_unit = zcu.trackUnitSema(struct_type.name.toSlice(ip), null); + defer tracked_unit.end(zcu); + sema.structFieldInits(struct_type) catch |err| switch (err) { error.AnalysisFail, error.OutOfMemory => |e| return e, error.ComptimeBreak, error.ComptimeReturn => unreachable, @@ -34819,6 +34845,10 @@ pub fn resolveUnionFieldTypes(sema: *Sema, ty: Type, union_type: InternPool.Load => return, } + // can't happen earlier than this because we only want the progress node if not already resolved + const tracked_unit = zcu.trackUnitSema(union_type.name.toSlice(ip), null); + defer tracked_unit.end(zcu); + union_type.setStatus(ip, .field_types_wip); errdefer union_type.setStatus(ip, .none); sema.unionFields(ty.toIntern(), union_type) catch |err| switch (err) { diff --git a/src/Type.zig b/src/Type.zig index 0677b8d227..9316bec11e 100644 --- a/src/Type.zig +++ b/src/Type.zig @@ -3797,9 +3797,6 @@ fn resolveStructInner( return error.AnalysisFail; } - const tracked_unit = zcu.trackUnitSema(struct_obj.name.toSlice(&zcu.intern_pool), null); - defer tracked_unit.end(zcu); - if (zcu.comp.debugIncremental()) { const info = try zcu.incremental_debug_state.getUnitInfo(gpa, owner); info.last_update_gen = zcu.generation; @@ -3859,9 +3856,6 @@ fn resolveUnionInner( return error.AnalysisFail; } - const tracked_unit = zcu.trackUnitSema(union_obj.name.toSlice(&zcu.intern_pool), null); - defer tracked_unit.end(zcu); - if (zcu.comp.debugIncremental()) { const info = try zcu.incremental_debug_state.getUnitInfo(gpa, owner); info.last_update_gen = zcu.generation;