authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-06 21:24:38+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-06 21:26:39+00:00
logb41a0b4768d368d81d0d33c779f919d8f315e622
tree36bcd210c4eedce2b3bb68fe6c097dc79219e84f
parent4c05a9a892d68749f3d7da26ee0e884158640720
signaturelock-open Commit is signed but in an unrecognized format.

Package.Module: deduplicate identical builtin modules

Previously, when multiple modules had builtin modules with identical sources, two distinct `Module`s and `File`s were created pointing at the same file path. This led to a bug later in the frontend. These modules are now deduplicated with a simple hashmap on the builtin source.

9 files changed, 41 insertions(+), 4 deletions(-)

src/Compilation.zig+4
......@@ -1325,6 +1325,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
13251325 .global = options.config,
13261326 .parent = options.root_mod,
13271327 .builtin_mod = options.root_mod.getBuiltinDependency(),
1328 .builtin_modules = null, // `builtin_mod` is set
13281329 });
13291330 try options.root_mod.deps.putNoClobber(arena, "compiler_rt", compiler_rt_mod);
13301331 }
......@@ -1429,6 +1430,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
14291430 .global = options.config,
14301431 .parent = options.root_mod,
14311432 .builtin_mod = options.root_mod.getBuiltinDependency(),
1433 .builtin_modules = null, // `builtin_mod` is set
14321434 });
14331435
14341436 const zcu = try arena.create(Module);
......@@ -6104,6 +6106,7 @@ fn buildOutputFromZig(
61046106 .cc_argv = &.{},
61056107 .parent = null,
61066108 .builtin_mod = null,
6109 .builtin_modules = null, // there is only one module in this compilation
61076110 });
61086111 const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
61096112 const target = comp.getTarget();
......@@ -6216,6 +6219,7 @@ pub fn build_crt_file(
62166219 .cc_argv = &.{},
62176220 .parent = null,
62186221 .builtin_mod = null,
6222 .builtin_modules = null, // there is only one module in this compilation
62196223 });
62206224
62216225 for (c_source_files) |*item| {
src/Package/Module.zig+15-1
......@@ -63,6 +63,11 @@ pub const CreateOptions = struct {
6363
6464 builtin_mod: ?*Package.Module,
6565
66 /// Allocated into the given `arena`. Should be shared across all module creations in a Compilation.
67 /// Ignored if `builtin_mod` is passed or if `!have_zcu`.
68 /// Otherwise, may be `null` only if this Compilation consists of a single module.
69 builtin_modules: ?*std.StringHashMapUnmanaged(*Module),
70
6671 pub const Paths = struct {
6772 root: Package.Path,
6873 /// Relative to `root`. May contain path separators.
......@@ -364,11 +369,20 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
364369 .wasi_exec_model = options.global.wasi_exec_model,
365370 }, arena);
366371
372 const new = if (options.builtin_modules) |builtins| new: {
373 const gop = try builtins.getOrPut(arena, generated_builtin_source);
374 if (gop.found_existing) break :b gop.value_ptr.*;
375 errdefer builtins.removeByPtr(gop.key_ptr);
376 const new = try arena.create(Module);
377 gop.value_ptr.* = new;
378 break :new new;
379 } else try arena.create(Module);
380 errdefer if (options.builtin_modules) |builtins| assert(builtins.remove(generated_builtin_source));
381
367382 const new_file = try arena.create(File);
368383
369384 const digest = Cache.HashHelper.oneShot(generated_builtin_source);
370385 const builtin_sub_path = try arena.dupe(u8, "b" ++ std.fs.path.sep_str ++ digest);
371 const new = try arena.create(Module);
372386 new.* = .{
373387 .root = .{
374388 .root_dir = options.global_cache_directory,
src/Sema.zig+1
......@@ -5858,6 +5858,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
58585858 .global = comp.config,
58595859 .parent = parent_mod,
58605860 .builtin_mod = parent_mod.getBuiltinDependency(),
5861 .builtin_modules = null, // `builtin_mod` is set
58615862 }) catch |err| switch (err) {
58625863 // None of these are possible because we are creating a package with
58635864 // the exact same configuration as the parent package, which already
src/glibc.zig+1
......@@ -1118,6 +1118,7 @@ fn buildSharedLib(
11181118 .cc_argv = &.{},
11191119 .parent = null,
11201120 .builtin_mod = null,
1121 .builtin_modules = null, // there is only one module in this compilation
11211122 });
11221123
11231124 const c_source_files = [1]Compilation.CSourceFile{
src/libcxx.zig+2
......@@ -181,6 +181,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
181181 .cc_argv = &.{},
182182 .parent = null,
183183 .builtin_mod = null,
184 .builtin_modules = null, // there is only one module in this compilation
184185 });
185186
186187 var c_source_files = try std.ArrayList(Compilation.CSourceFile).initCapacity(arena, libcxx_files.len);
......@@ -395,6 +396,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
395396 .cc_argv = &.{},
396397 .parent = null,
397398 .builtin_mod = null,
399 .builtin_modules = null, // there is only one module in this compilation
398400 });
399401
400402 var c_source_files = try std.ArrayList(Compilation.CSourceFile).initCapacity(arena, libcxxabi_files.len);
src/libtsan.zig+1
......@@ -92,6 +92,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) BuildError!v
9292 .cc_argv = &common_flags,
9393 .parent = null,
9494 .builtin_mod = null,
95 .builtin_modules = null, // there is only one module in this compilation
9596 }) catch |err| {
9697 comp.setMiscFailure(
9798 .libtsan,
src/libunwind.zig+1
......@@ -58,6 +58,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void {
5858 .cc_argv = &.{},
5959 .parent = null,
6060 .builtin_mod = null,
61 .builtin_modules = null, // there is only one module in this compilation
6162 });
6263
6364 const root_name = "unwind";
src/main.zig+15-3
......@@ -2697,7 +2697,9 @@ fn buildOutputType(
26972697 create_module.opts.emit_bin = emit_bin != .no;
26982698 create_module.opts.any_c_source_files = create_module.c_source_files.items.len != 0;
26992699
2700 const main_mod = try createModule(gpa, arena, &create_module, 0, null, zig_lib_directory);
2700 var builtin_modules: std.StringHashMapUnmanaged(*Package.Module) = .{};
2701 // `builtin_modules` allocated into `arena`, so no deinit
2702 const main_mod = try createModule(gpa, arena, &create_module, 0, null, zig_lib_directory, &builtin_modules);
27012703 for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| {
27022704 if (cli_mod.resolved == null)
27032705 fatal("module '{s}' declared but not used", .{key});
......@@ -2742,6 +2744,7 @@ fn buildOutputType(
27422744 .global = create_module.resolved_options,
27432745 .parent = main_mod,
27442746 .builtin_mod = main_mod.getBuiltinDependency(),
2747 .builtin_modules = null, // `builtin_mod` is specified
27452748 });
27462749 test_mod.deps = try main_mod.deps.clone(arena);
27472750 break :test_mod test_mod;
......@@ -2760,6 +2763,7 @@ fn buildOutputType(
27602763 .global = create_module.resolved_options,
27612764 .parent = main_mod,
27622765 .builtin_mod = main_mod.getBuiltinDependency(),
2766 .builtin_modules = null, // `builtin_mod` is specified
27632767 });
27642768
27652769 break :root_mod test_mod;
......@@ -3467,6 +3471,7 @@ fn createModule(
34673471 index: usize,
34683472 parent: ?*Package.Module,
34693473 zig_lib_directory: Cache.Directory,
3474 builtin_modules: *std.StringHashMapUnmanaged(*Package.Module),
34703475) Allocator.Error!*Package.Module {
34713476 const cli_mod = &create_module.modules.values()[index];
34723477 if (cli_mod.resolved) |m| return m;
......@@ -3919,6 +3924,7 @@ fn createModule(
39193924 .global = create_module.resolved_options,
39203925 .parent = parent,
39213926 .builtin_mod = null,
3927 .builtin_modules = builtin_modules,
39223928 }) catch |err| switch (err) {
39233929 error.ValgrindUnsupportedOnTarget => fatal("unable to create module '{s}': valgrind does not support the selected target CPU architecture", .{name}),
39243930 error.TargetRequiresSingleThreaded => fatal("unable to create module '{s}': the selected target does not support multithreading", .{name}),
......@@ -3941,7 +3947,7 @@ fn createModule(
39413947 for (cli_mod.deps) |dep| {
39423948 const dep_index = create_module.modules.getIndex(dep.value) orelse
39433949 fatal("module '{s}' depends on non-existent module '{s}'", .{ name, dep.key });
3944 const dep_mod = try createModule(gpa, arena, create_module, dep_index, mod, zig_lib_directory);
3950 const dep_mod = try createModule(gpa, arena, create_module, dep_index, mod, zig_lib_directory, builtin_modules);
39453951 try mod.deps.put(arena, dep.key, dep_mod);
39463952 }
39473953
......@@ -5237,6 +5243,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
52375243 .global = config,
52385244 .parent = null,
52395245 .builtin_mod = null,
5246 .builtin_modules = null, // all modules will inherit this one's builtin
52405247 });
52415248
52425249 const builtin_mod = root_mod.getBuiltinDependency();
......@@ -5253,6 +5260,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
52535260 .global = config,
52545261 .parent = root_mod,
52555262 .builtin_mod = builtin_mod,
5263 .builtin_modules = null, // `builtin_mod` is specified
52565264 });
52575265
52585266 var cleanup_build_dir: ?fs.Dir = null;
......@@ -5387,6 +5395,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
53875395 .global = config,
53885396 .parent = root_mod,
53895397 .builtin_mod = builtin_mod,
5398 .builtin_modules = null, // `builtin_mod` is specified
53905399 });
53915400 const hash_cloned = try arena.dupe(u8, &hash);
53925401 deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m);
......@@ -5636,6 +5645,7 @@ fn jitCmd(
56365645 .global = config,
56375646 .parent = null,
56385647 .builtin_mod = null,
5648 .builtin_modules = null, // all modules will inherit this one's builtin
56395649 });
56405650
56415651 if (options.depend_on_aro) {
......@@ -5658,6 +5668,7 @@ fn jitCmd(
56585668 .global = config,
56595669 .parent = null,
56605670 .builtin_mod = root_mod.getBuiltinDependency(),
5671 .builtin_modules = null, // `builtin_mod` is specified
56615672 });
56625673 try root_mod.deps.put(arena, "aro", aro_mod);
56635674 }
......@@ -7204,10 +7215,11 @@ fn createDependenciesModule(
72047215 },
72057216 .fully_qualified_name = "root.@dependencies",
72067217 .parent = main_mod,
7207 .builtin_mod = builtin_mod,
72087218 .cc_argv = &.{},
72097219 .inherited = .{},
72107220 .global = global_options,
7221 .builtin_mod = builtin_mod,
7222 .builtin_modules = null, // `builtin_mod` is specified
72117223 });
72127224 try main_mod.deps.put(arena, "@dependencies", deps_mod);
72137225 return deps_mod;
src/musl.zig+1
......@@ -250,6 +250,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
250250 .cc_argv = cc_argv,
251251 .parent = null,
252252 .builtin_mod = null,
253 .builtin_modules = null, // there is only one module in this compilation
253254 });
254255
255256 const sub_compilation = try Compilation.create(comp.gpa, arena, .{