stage2: use import list from ZIR to queue up more AstGen tasks

This commit is contained in:
Andrew Kelley 2021-04-16 17:28:28 -07:00
parent a271f12a14
commit 5ff45b3f44
4 changed files with 50 additions and 7 deletions

View File

@ -1,6 +1,5 @@
* look for cached zir code
* save zir code to cache
* use list of imported strings to queue up more astgen tasks
* keep track of file dependencies/dependants
* unload files from memory when a dependency is dropped
* implement zir error notes

View File

@ -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 {

View File

@ -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(

View File

@ -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 {