diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-04-16 17:28:28 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-04-16 17:28:28 -0700 |
| commit | 5ff45b3f44e7f1272b655b366cee4089d0aa8509 (patch) | |
| tree | 7a2987020988e85f60eff90db71ca08a3bdf6864 /src | |
| parent | a271f12a149239ab6e6361423589687e32f64cda (diff) | |
| download | zig-5ff45b3f44e7f1272b655b366cee4089d0aa8509.tar.gz zig-5ff45b3f44e7f1272b655b366cee4089d0aa8509.zip | |
stage2: use import list from ZIR to queue up more AstGen tasks
Diffstat (limited to 'src')
| -rw-r--r-- | src/Compilation.zig | 31 | ||||
| -rw-r--r-- | src/Module.zig | 21 | ||||
| -rw-r--r-- | src/Sema.zig | 4 |
3 files changed, 50 insertions, 6 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 85a0820f05..3f0937c957 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -30,6 +30,7 @@ const c_codegen = @import("codegen/c.zig"); const ThreadPool = @import("ThreadPool.zig"); const WaitGroup = @import("WaitGroup.zig"); const libtsan = @import("libtsan.zig"); +const Zir = @import("Zir.zig"); /// General-purpose allocator. Used for both temporary and long-term storage. gpa: *Allocator, @@ -431,7 +432,6 @@ pub const AllErrors = struct { ) !void { assert(file.zir_loaded); assert(file.tree_loaded); - const Zir = @import("Zir.zig"); const payload_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.compile_errors)]; assert(payload_index != 0); @@ -2120,6 +2120,35 @@ fn workerAstGenFile( }; }, }; + + // Pre-emptively look for `@import` paths and queue them up. + // If we experience an error preemptively fetching the + // file, just ignore it and let it happen again later during Sema. + assert(file.zir_loaded); + const imports_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.imports)]; + if (imports_index != 0) { + const imports_len = file.zir.extra[imports_index]; + + for (file.zir.extra[imports_index + 1 ..][0..imports_len]) |str_index| { + const import_path = file.zir.nullTerminatedString(str_index); + + const import_result = blk: { + const lock = comp.mutex.acquire(); + defer lock.release(); + + break :blk mod.importFile(file.pkg, import_path) catch continue; + }; + if (import_result.is_new) { + wg.start(); + comp.thread_pool.spawn(workerAstGenFile, .{ + comp, import_result.file, prog_node, wg, + }) catch { + wg.finish(); + continue; + }; + } + } + } } pub fn obtainCObjectCacheManifest(comp: *const Compilation) Cache.Manifest { diff --git a/src/Module.zig b/src/Module.zig index 15434fe159..9ecd8bab51 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -2628,7 +2628,16 @@ pub fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !vo depender.dependencies.putAssumeCapacity(dependee, {}); } -pub fn importFile(mod: *Module, cur_pkg: *Package, import_string: []const u8) !*Scope.File { +pub const ImportFileResult = struct { + file: *Scope.File, + is_new: bool, +}; + +pub fn importFile( + mod: *Module, + cur_pkg: *Package, + import_string: []const u8, +) !ImportFileResult { const gpa = mod.gpa; const cur_pkg_dir_path = cur_pkg.root_src_directory.path orelse "."; @@ -2642,7 +2651,10 @@ pub fn importFile(mod: *Module, cur_pkg: *Package, import_string: []const u8) !* defer if (!keep_resolved_path) gpa.free(resolved_path); const gop = try mod.import_table.getOrPut(gpa, resolved_path); - if (gop.found_existing) return gop.entry.value; + if (gop.found_existing) return ImportFileResult{ + .file = gop.entry.value, + .is_new = false, + }; if (found_pkg == null) { const resolved_root_path = try std.fs.path.resolve(gpa, &[_][]const u8{cur_pkg_dir_path}); @@ -2671,7 +2683,10 @@ pub fn importFile(mod: *Module, cur_pkg: *Package, import_string: []const u8) !* .namespace = undefined, }; keep_resolved_path = true; - return new_file; + return ImportFileResult{ + .file = new_file, + .is_new = true, + }; } pub fn analyzeNamespace( diff --git a/src/Sema.zig b/src/Sema.zig index 5bc1241ae6..142d39f192 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -3904,7 +3904,7 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError! const src = inst_data.src(); const operand = inst_data.get(sema.code); - const file = mod.importFile(block.getFileScope().pkg, operand) catch |err| switch (err) { + const result = mod.importFile(block.getFileScope().pkg, operand) catch |err| switch (err) { error.ImportOutsidePkgPath => { return mod.fail(&block.base, src, "import of file outside package path: '{s}'", .{operand}); }, @@ -3914,7 +3914,7 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError! return mod.fail(&block.base, src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); }, }; - return mod.constType(sema.arena, src, file.namespace.ty); + return mod.constType(sema.arena, src, result.file.namespace.ty); } fn zirShl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { |
