Skip to content

Commit 497592c

Browse files
authored
Merge pull request #22303 from mlugg/131-new
compiler: analyze type and value of global declarations separately
2 parents af5e731 + 3afda43 commit 497592c

29 files changed

+3095
-2546
lines changed

lib/std/zig/AstGen.zig

+582-536
Large diffs are not rendered by default.

lib/std/zig/Zir.zig

+392-95
Large diffs are not rendered by default.

src/Compilation.zig

+52-29
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,15 @@ const Job = union(enum) {
348348
/// Corresponds to the task in `link.Task`.
349349
/// Only needed for backends that haven't yet been updated to not race against Sema.
350350
codegen_type: InternPool.Index,
351-
/// The `Cau` must be semantically analyzed (and possibly export itself).
351+
/// The `AnalUnit`, which is *not* a `func`, must be semantically analyzed.
352+
/// This may be its first time being analyzed, or it may be outdated.
353+
/// If the unit is a function, a `codegen_func` job will then be queued.
354+
analyze_comptime_unit: InternPool.AnalUnit,
355+
/// This function must be semantically analyzed.
352356
/// This may be its first time being analyzed, or it may be outdated.
353-
analyze_cau: InternPool.Cau.Index,
354-
/// Analyze the body of a runtime function.
355357
/// After analysis, a `codegen_func` job will be queued.
356358
/// These must be separate jobs to ensure any needed type resolution occurs *before* codegen.
359+
/// This job is separate from `analyze_comptime_unit` because it has a different priority.
357360
analyze_func: InternPool.Index,
358361
/// The main source file for the module needs to be analyzed.
359362
analyze_mod: *Package.Module,
@@ -2903,6 +2906,7 @@ const Header = extern struct {
29032906
file_deps_len: u32,
29042907
src_hash_deps_len: u32,
29052908
nav_val_deps_len: u32,
2909+
nav_ty_deps_len: u32,
29062910
namespace_deps_len: u32,
29072911
namespace_name_deps_len: u32,
29082912
first_dependency_len: u32,
@@ -2946,6 +2950,7 @@ pub fn saveState(comp: *Compilation) !void {
29462950
.file_deps_len = @intCast(ip.file_deps.count()),
29472951
.src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
29482952
.nav_val_deps_len = @intCast(ip.nav_val_deps.count()),
2953+
.nav_ty_deps_len = @intCast(ip.nav_ty_deps.count()),
29492954
.namespace_deps_len = @intCast(ip.namespace_deps.count()),
29502955
.namespace_name_deps_len = @intCast(ip.namespace_name_deps.count()),
29512956
.first_dependency_len = @intCast(ip.first_dependency.count()),
@@ -2976,6 +2981,8 @@ pub fn saveState(comp: *Compilation) !void {
29762981
addBuf(&bufs, mem.sliceAsBytes(ip.src_hash_deps.values()));
29772982
addBuf(&bufs, mem.sliceAsBytes(ip.nav_val_deps.keys()));
29782983
addBuf(&bufs, mem.sliceAsBytes(ip.nav_val_deps.values()));
2984+
addBuf(&bufs, mem.sliceAsBytes(ip.nav_ty_deps.keys()));
2985+
addBuf(&bufs, mem.sliceAsBytes(ip.nav_ty_deps.values()));
29792986
addBuf(&bufs, mem.sliceAsBytes(ip.namespace_deps.keys()));
29802987
addBuf(&bufs, mem.sliceAsBytes(ip.namespace_deps.values()));
29812988
addBuf(&bufs, mem.sliceAsBytes(ip.namespace_name_deps.keys()));
@@ -3141,8 +3148,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
31413148
}
31423149

31433150
const file_index = switch (anal_unit.unwrap()) {
3144-
.cau => |cau| zcu.namespacePtr(ip.getCau(cau).namespace).file_scope,
3145-
.func => |ip_index| (zcu.funcInfo(ip_index).zir_body_inst.resolveFull(ip) orelse continue).file,
3151+
.@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index.resolveFile(ip),
3152+
.nav_val, .nav_ty => |nav| ip.getNav(nav).analysis.?.zir_index.resolveFile(ip),
3153+
.type => |ty| Type.fromInterned(ty).typeDeclInst(zcu).?.resolveFile(ip),
3154+
.func => |ip_index| zcu.funcInfo(ip_index).zir_body_inst.resolveFile(ip),
31463155
};
31473156

31483157
// Skip errors for AnalUnits within files that had a parse failure.
@@ -3374,11 +3383,9 @@ pub fn addModuleErrorMsg(
33743383
const rt_file_path = try src.file_scope.fullPath(gpa);
33753384
defer gpa.free(rt_file_path);
33763385
const name = switch (ref.referencer.unwrap()) {
3377-
.cau => |cau| switch (ip.getCau(cau).owner.unwrap()) {
3378-
.nav => |nav| ip.getNav(nav).name.toSlice(ip),
3379-
.type => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip),
3380-
.none => "comptime",
3381-
},
3386+
.@"comptime" => "comptime",
3387+
.nav_val, .nav_ty => |nav| ip.getNav(nav).name.toSlice(ip),
3388+
.type => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip),
33823389
.func => |f| ip.getNav(zcu.funcInfo(f).owner_nav).name.toSlice(ip),
33833390
};
33843391
try ref_traces.append(gpa, .{
@@ -3641,10 +3648,14 @@ fn performAllTheWorkInner(
36413648
// If there's no work queued, check if there's anything outdated
36423649
// which we need to work on, and queue it if so.
36433650
if (try zcu.findOutdatedToAnalyze()) |outdated| {
3644-
switch (outdated.unwrap()) {
3645-
.cau => |cau| try comp.queueJob(.{ .analyze_cau = cau }),
3646-
.func => |func| try comp.queueJob(.{ .analyze_func = func }),
3647-
}
3651+
try comp.queueJob(switch (outdated.unwrap()) {
3652+
.func => |f| .{ .analyze_func = f },
3653+
.@"comptime",
3654+
.nav_ty,
3655+
.nav_val,
3656+
.type,
3657+
=> .{ .analyze_comptime_unit = outdated },
3658+
});
36483659
continue;
36493660
}
36503661
}
@@ -3667,13 +3678,13 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
36673678
.codegen_nav => |nav_index| {
36683679
const zcu = comp.zcu.?;
36693680
const nav = zcu.intern_pool.getNav(nav_index);
3670-
if (nav.analysis_owner.unwrap()) |cau| {
3671-
const unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
3681+
if (nav.analysis != null) {
3682+
const unit: InternPool.AnalUnit = .wrap(.{ .nav_val = nav_index });
36723683
if (zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit)) {
36733684
return;
36743685
}
36753686
}
3676-
assert(nav.status == .resolved);
3687+
assert(nav.status == .fully_resolved);
36773688
comp.dispatchCodegenTask(tid, .{ .codegen_nav = nav_index });
36783689
},
36793690
.codegen_func => |func| {
@@ -3688,36 +3699,48 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
36883699

36893700
const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));
36903701
defer pt.deactivate();
3691-
pt.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
3692-
error.OutOfMemory => return error.OutOfMemory,
3702+
3703+
pt.ensureFuncBodyUpToDate(func) catch |err| switch (err) {
3704+
error.OutOfMemory => |e| return e,
36933705
error.AnalysisFail => return,
36943706
};
36953707
},
3696-
.analyze_cau => |cau_index| {
3708+
.analyze_comptime_unit => |unit| {
3709+
const named_frame = tracy.namedFrame("analyze_comptime_unit");
3710+
defer named_frame.end();
3711+
36973712
const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));
36983713
defer pt.deactivate();
3699-
pt.ensureCauAnalyzed(cau_index) catch |err| switch (err) {
3700-
error.OutOfMemory => return error.OutOfMemory,
3714+
3715+
const maybe_err: Zcu.SemaError!void = switch (unit.unwrap()) {
3716+
.@"comptime" => |cu| pt.ensureComptimeUnitUpToDate(cu),
3717+
.nav_ty => |nav| pt.ensureNavTypeUpToDate(nav),
3718+
.nav_val => |nav| pt.ensureNavValUpToDate(nav),
3719+
.type => |ty| if (pt.ensureTypeUpToDate(ty)) |_| {} else |err| err,
3720+
.func => unreachable,
3721+
};
3722+
maybe_err catch |err| switch (err) {
3723+
error.OutOfMemory => |e| return e,
37013724
error.AnalysisFail => return,
37023725
};
3726+
37033727
queue_test_analysis: {
37043728
if (!comp.config.is_test) break :queue_test_analysis;
3729+
const nav = switch (unit.unwrap()) {
3730+
.nav_val => |nav| nav,
3731+
else => break :queue_test_analysis,
3732+
};
37053733

37063734
// Check if this is a test function.
37073735
const ip = &pt.zcu.intern_pool;
3708-
const cau = ip.getCau(cau_index);
3709-
const nav_index = switch (cau.owner.unwrap()) {
3710-
.none, .type => break :queue_test_analysis,
3711-
.nav => |nav| nav,
3712-
};
3713-
if (!pt.zcu.test_functions.contains(nav_index)) {
3736+
if (!pt.zcu.test_functions.contains(nav)) {
37143737
break :queue_test_analysis;
37153738
}
37163739

37173740
// Tests are always emitted in test binaries. The decl_refs are created by
37183741
// Zcu.populateTestFunctions, but this will not queue body analysis, so do
37193742
// that now.
3720-
try pt.zcu.ensureFuncBodyAnalysisQueued(ip.getNav(nav_index).status.resolved.val);
3743+
try pt.zcu.ensureFuncBodyAnalysisQueued(ip.getNav(nav).status.fully_resolved.val);
37213744
}
37223745
},
37233746
.resolve_type_fully => |ty| {

0 commit comments

Comments
 (0)