aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-04-16 17:28:28 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-04-16 17:28:28 -0700
commit5ff45b3f44e7f1272b655b366cee4089d0aa8509 (patch)
tree7a2987020988e85f60eff90db71ca08a3bdf6864 /src
parenta271f12a149239ab6e6361423589687e32f64cda (diff)
downloadzig-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.zig31
-rw-r--r--src/Module.zig21
-rw-r--r--src/Sema.zig4
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 {