Commit a7c05c06be
Changed files (11)
src/codegen/llvm.zig
@@ -469,7 +469,12 @@ pub const Object = struct {
_ = builder.buildRet(is_lt);
}
- pub fn flushModule(self: *Object, comp: *Compilation) !void {
+ pub fn flushModule(self: *Object, comp: *Compilation, prog_node: *std.Progress.Node) !void {
+ var sub_prog_node = prog_node.start("LLVM Emit Object", 0);
+ sub_prog_node.activate();
+ sub_prog_node.context.refresh();
+ defer sub_prog_node.end();
+
try self.genErrorNameTable(comp);
try self.genCmpLtErrorsLenFunction(comp);
src/link/C.zig
@@ -235,14 +235,18 @@ pub fn updateDeclLineNumber(self: *C, module: *Module, decl: *Module.Decl) !void
_ = decl;
}
-pub fn flush(self: *C, comp: *Compilation) !void {
- return self.flushModule(comp);
+pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void {
+ return self.flushModule(comp, prog_node);
}
-pub fn flushModule(self: *C, comp: *Compilation) !void {
+pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
+ var sub_prog_node = prog_node.start("Flush Module", 0);
+ sub_prog_node.activate();
+ defer sub_prog_node.end();
+
const gpa = comp.gpa;
const module = self.base.options.module.?;
src/link/Coff.zig
@@ -829,36 +829,40 @@ pub fn updateDeclExports(
}
}
-pub fn flush(self: *Coff, comp: *Compilation) !void {
+pub fn flush(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void {
if (self.base.options.emit == null) {
if (build_options.have_llvm) {
if (self.llvm_object) |llvm_object| {
- return try llvm_object.flushModule(comp);
+ return try llvm_object.flushModule(comp, prog_node);
}
}
return;
}
if (build_options.have_llvm and self.base.options.use_lld) {
- return self.linkWithLLD(comp);
+ return self.linkWithLLD(comp, prog_node);
} else {
switch (self.base.options.effectiveOutputMode()) {
.Exe, .Obj => {},
.Lib => return error.TODOImplementWritingLibFiles,
}
- return self.flushModule(comp);
+ return self.flushModule(comp, prog_node);
}
}
-pub fn flushModule(self: *Coff, comp: *Compilation) !void {
+pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
if (build_options.have_llvm) {
if (self.llvm_object) |llvm_object| {
- return try llvm_object.flushModule(comp);
+ return try llvm_object.flushModule(comp, prog_node);
}
}
+ var sub_prog_node = prog_node.start("COFF Flush", 0);
+ sub_prog_node.activate();
+ defer sub_prog_node.end();
+
if (self.text_section_size_dirty) {
// Write the new raw size in the .text header
var buf: [4]u8 = undefined;
@@ -892,7 +896,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void {
}
}
-fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
+fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
@@ -924,7 +928,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
}
}
- try self.flushModule(comp);
+ try self.flushModule(comp, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? });
@@ -933,6 +937,11 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
}
} else null;
+ var sub_prog_node = prog_node.start("LLD Link", 0);
+ sub_prog_node.activate();
+ sub_prog_node.context.refresh();
+ defer sub_prog_node.end();
+
const is_lib = self.base.options.output_mode == .Lib;
const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe;
src/link/Elf.zig
@@ -929,35 +929,39 @@ pub fn populateMissingMetadata(self: *Elf) !void {
}
}
-pub fn flush(self: *Elf, comp: *Compilation) !void {
+pub fn flush(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
if (self.base.options.emit == null) {
if (build_options.have_llvm) {
if (self.llvm_object) |llvm_object| {
- return try llvm_object.flushModule(comp);
+ return try llvm_object.flushModule(comp, prog_node);
}
}
return;
}
const use_lld = build_options.have_llvm and self.base.options.use_lld;
if (use_lld) {
- return self.linkWithLLD(comp);
+ return self.linkWithLLD(comp, prog_node);
}
switch (self.base.options.output_mode) {
- .Exe, .Obj => return self.flushModule(comp),
+ .Exe, .Obj => return self.flushModule(comp, prog_node),
.Lib => return error.TODOImplementWritingLibFiles,
}
}
-pub fn flushModule(self: *Elf, comp: *Compilation) !void {
+pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
if (build_options.have_llvm) {
if (self.llvm_object) |llvm_object| {
- return try llvm_object.flushModule(comp);
+ return try llvm_object.flushModule(comp, prog_node);
}
}
+ var sub_prog_node = prog_node.start("ELF Flush", 0);
+ sub_prog_node.activate();
+ defer sub_prog_node.end();
+
// TODO This linker code currently assumes there is only 1 compilation unit and it
// corresponds to the Zig source code.
const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
@@ -1204,7 +1208,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
assert(!self.debug_strtab_dirty);
}
-fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
+fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
@@ -1236,7 +1240,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
}
}
- try self.flushModule(comp);
+ try self.flushModule(comp, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? });
@@ -1245,6 +1249,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
}
} else null;
+ var sub_prog_node = prog_node.start("LLD Link", 0);
+ sub_prog_node.activate();
+ sub_prog_node.context.refresh();
+ defer sub_prog_node.end();
+
const is_obj = self.base.options.output_mode == .Obj;
const is_lib = self.base.options.output_mode == .Lib;
const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
src/link/MachO.zig
@@ -419,33 +419,34 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
return self;
}
-pub fn flush(self: *MachO, comp: *Compilation) !void {
+pub fn flush(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void {
if (self.base.options.emit == null) {
if (build_options.have_llvm) {
if (self.llvm_object) |llvm_object| {
- try llvm_object.flushModule(comp);
+ try llvm_object.flushModule(comp, prog_node);
}
}
return;
}
+
if (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Static) {
if (build_options.have_llvm) {
- return self.base.linkAsArchive(comp);
+ return self.base.linkAsArchive(comp, prog_node);
} else {
log.err("TODO: non-LLVM archiver for MachO object files", .{});
return error.TODOImplementWritingStaticLibFiles;
}
}
- try self.flushModule(comp);
+ try self.flushModule(comp, prog_node);
}
-pub fn flushModule(self: *MachO, comp: *Compilation) !void {
+pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
if (!use_stage1 and self.base.options.output_mode == .Obj)
- return self.flushObject(comp);
+ return self.flushObject(comp, prog_node);
var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
defer arena_allocator.deinit();
@@ -482,7 +483,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
const obj_basename = self.base.intermediary_basename orelse break :blk null;
- try self.flushObject(comp);
+ try self.flushObject(comp, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, obj_basename });
@@ -491,6 +492,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
}
} else null;
+ var sub_prog_node = prog_node.start("MachO Flush", 0);
+ sub_prog_node.activate();
+ defer sub_prog_node.end();
+
const is_lib = self.base.options.output_mode == .Lib;
const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe;
@@ -1111,13 +1116,13 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
self.cold_start = false;
}
-pub fn flushObject(self: *MachO, comp: *Compilation) !void {
+pub fn flushObject(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
if (build_options.have_llvm)
if (self.llvm_object) |llvm_object|
- return llvm_object.flushModule(comp);
+ return llvm_object.flushModule(comp, prog_node);
return error.TODOImplementWritingObjFiles;
}
src/link/NvPtx.zig
@@ -97,11 +97,11 @@ pub fn freeDecl(self: *NvPtx, decl: *Module.Decl) void {
return self.llvm_object.freeDecl(decl);
}
-pub fn flush(self: *NvPtx, comp: *Compilation) !void {
- return self.flushModule(comp);
+pub fn flush(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) !void {
+ return self.flushModule(comp, prog_node);
}
-pub fn flushModule(self: *NvPtx, comp: *Compilation) !void {
+pub fn flushModule(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) !void {
if (!build_options.have_llvm) return;
if (build_options.skip_non_native) {
@panic("Attempted to compile for architecture that was disabled by build configuration");
@@ -117,5 +117,5 @@ pub fn flushModule(self: *NvPtx, comp: *Compilation) !void {
};
hack_comp.bin_file.options.emit = null;
}
- return try self.llvm_object.flushModule(hack_comp);
+ return try self.llvm_object.flushModule(hack_comp, prog_node);
}
src/link/Plan9.zig
@@ -351,7 +351,7 @@ fn updateFinish(self: *Plan9, decl: *Module.Decl) !void {
}
}
-pub fn flush(self: *Plan9, comp: *Compilation) !void {
+pub fn flush(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) !void {
assert(!self.base.options.use_lld);
switch (self.base.options.effectiveOutputMode()) {
@@ -360,7 +360,7 @@ pub fn flush(self: *Plan9, comp: *Compilation) !void {
.Obj => return error.TODOImplementPlan9Objs,
.Lib => return error.TODOImplementWritingLibFiles,
}
- return self.flushModule(comp);
+ return self.flushModule(comp, prog_node);
}
pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void {
@@ -387,7 +387,7 @@ fn declCount(self: *Plan9) usize {
return self.data_decl_table.count() + fn_decl_count;
}
-pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
+pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) !void {
if (build_options.skip_non_native and builtin.object_format != .plan9) {
@panic("Attempted to compile for object format that was disabled by build configuration");
}
@@ -396,6 +396,10 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
const tracy = trace(@src());
defer tracy.end();
+ var sub_prog_node = prog_node.start("Flush Module", 0);
+ sub_prog_node.activate();
+ defer sub_prog_node.end();
+
log.debug("flushModule", .{});
defer assert(self.hdr.entry != 0x0);
src/link/SpirV.zig
@@ -174,15 +174,15 @@ pub fn freeDecl(self: *SpirV, decl: *Module.Decl) void {
self.decl_table.swapRemoveAt(index);
}
-pub fn flush(self: *SpirV, comp: *Compilation) !void {
+pub fn flush(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) !void {
if (build_options.have_llvm and self.base.options.use_lld) {
return error.LLD_LinkingIsTODO_ForSpirV; // TODO: LLD Doesn't support SpirV at all.
} else {
- return self.flushModule(comp);
+ return self.flushModule(comp, prog_node);
}
}
-pub fn flushModule(self: *SpirV, comp: *Compilation) !void {
+pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) !void {
if (build_options.skip_non_native) {
@panic("Attempted to compile for architecture that was disabled by build configuration");
}
@@ -190,6 +190,10 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void {
const tracy = trace(@src());
defer tracy.end();
+ var sub_prog_node = prog_node.start("Flush Module", 0);
+ sub_prog_node.activate();
+ defer sub_prog_node.end();
+
const module = self.base.options.module.?;
const target = comp.getTarget();
src/link/Wasm.zig
@@ -1477,32 +1477,36 @@ fn resetState(self: *Wasm) void {
self.code_section_index = null;
}
-pub fn flush(self: *Wasm, comp: *Compilation) !void {
+pub fn flush(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void {
if (self.base.options.emit == null) {
if (build_options.have_llvm) {
if (self.llvm_object) |llvm_object| {
- return try llvm_object.flushModule(comp);
+ return try llvm_object.flushModule(comp, prog_node);
}
}
return;
}
if (build_options.have_llvm and self.base.options.use_lld) {
- return self.linkWithLLD(comp);
+ return self.linkWithLLD(comp, prog_node);
} else {
- return self.flushModule(comp);
+ return self.flushModule(comp, prog_node);
}
}
-pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
+pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
if (build_options.have_llvm) {
if (self.llvm_object) |llvm_object| {
- return try llvm_object.flushModule(comp);
+ return try llvm_object.flushModule(comp, prog_node);
}
}
+ var sub_prog_node = prog_node.start("WASM Flush", 0);
+ sub_prog_node.activate();
+ defer sub_prog_node.end();
+
// ensure the error names table is populated when an error name is referenced
try self.populateErrorNameTable();
@@ -2028,7 +2032,7 @@ fn emitImport(self: *Wasm, writer: anytype, import: types.Import) !void {
}
}
-fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
+fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
@@ -2060,7 +2064,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
}
}
- try self.flushModule(comp);
+ try self.flushModule(comp, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? });
@@ -2069,6 +2073,11 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
}
} else null;
+ var sub_prog_node = prog_node.start("LLD Link", 0);
+ sub_prog_node.activate();
+ sub_prog_node.context.refresh();
+ defer sub_prog_node.end();
+
const is_obj = self.base.options.output_mode == .Obj;
const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj)
src/Compilation.zig
@@ -2084,7 +2084,13 @@ pub fn update(comp: *Compilation) !void {
}
}
- try comp.performAllTheWork();
+ // If the terminal is dumb, we dont want to show the user all the output.
+ var progress: std.Progress = .{ .dont_print_on_dumb = true };
+ const main_progress_node = progress.start("", 0);
+ defer main_progress_node.end();
+ if (comp.color == .off) progress.terminal = null;
+
+ try comp.performAllTheWork(main_progress_node);
if (!use_stage1) {
if (comp.bin_file.options.module) |module| {
@@ -2158,9 +2164,9 @@ pub fn update(comp: *Compilation) !void {
.path = dir_path,
};
- try comp.flush();
+ try comp.flush(main_progress_node);
} else {
- try comp.flush();
+ try comp.flush(main_progress_node);
}
// Failure here only means an unnecessary cache miss.
@@ -2171,7 +2177,7 @@ pub fn update(comp: *Compilation) !void {
assert(comp.bin_file.lock == null);
comp.bin_file.lock = man.toOwnedLock();
} else {
- try comp.flush();
+ try comp.flush(main_progress_node);
}
// Unload all source files to save memory.
@@ -2188,8 +2194,8 @@ pub fn update(comp: *Compilation) !void {
}
}
-fn flush(comp: *Compilation) !void {
- try comp.bin_file.flush(comp); // This is needed before reading the error flags.
+fn flush(comp: *Compilation, prog_node: *std.Progress.Node) !void {
+ try comp.bin_file.flush(comp, prog_node); // This is needed before reading the error flags.
comp.link_error_flags = comp.bin_file.errorFlags();
const use_stage1 = build_options.omit_stage2 or
@@ -2590,14 +2596,10 @@ pub fn getCompileLogOutput(self: *Compilation) []const u8 {
return module.compile_log_text.items;
}
-pub fn performAllTheWork(comp: *Compilation) error{ TimerUnsupported, OutOfMemory }!void {
- // If the terminal is dumb, we dont want to show the user all the
- // output.
- var progress: std.Progress = .{ .dont_print_on_dumb = true };
- var main_progress_node = progress.start("", 0);
- defer main_progress_node.end();
- if (comp.color == .off) progress.terminal = null;
-
+pub fn performAllTheWork(
+ comp: *Compilation,
+ main_progress_node: *std.Progress.Node,
+) error{ TimerUnsupported, OutOfMemory }!void {
// Here we queue up all the AstGen tasks first, followed by C object compilation.
// We wait until the AstGen tasks are all completed before proceeding to the
// (at least for now) single-threaded main work queue. However, C object compilation
src/link.zig
@@ -573,7 +573,7 @@ pub const File = struct {
/// Commit pending changes and write headers. Takes into account final output mode
/// and `use_lld`, not only `effectiveOutputMode`.
- pub fn flush(base: *File, comp: *Compilation) !void {
+ pub fn flush(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) !void {
if (comp.clang_preprocessor_mode == .yes) {
const emit = base.options.emit orelse return; // -fno-emit-bin
// TODO: avoid extra link step when it's just 1 object file (the `zig cc -c` case)
@@ -591,32 +591,32 @@ pub const File = struct {
const use_lld = build_options.have_llvm and base.options.use_lld;
if (use_lld and base.options.output_mode == .Lib and base.options.link_mode == .Static) {
- return base.linkAsArchive(comp);
+ return base.linkAsArchive(comp, prog_node);
}
switch (base.tag) {
- .coff => return @fieldParentPtr(Coff, "base", base).flush(comp),
- .elf => return @fieldParentPtr(Elf, "base", base).flush(comp),
- .macho => return @fieldParentPtr(MachO, "base", base).flush(comp),
- .c => return @fieldParentPtr(C, "base", base).flush(comp),
- .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp),
- .spirv => return @fieldParentPtr(SpirV, "base", base).flush(comp),
- .plan9 => return @fieldParentPtr(Plan9, "base", base).flush(comp),
- .nvptx => return @fieldParentPtr(NvPtx, "base", base).flush(comp),
+ .coff => return @fieldParentPtr(Coff, "base", base).flush(comp, prog_node),
+ .elf => return @fieldParentPtr(Elf, "base", base).flush(comp, prog_node),
+ .macho => return @fieldParentPtr(MachO, "base", base).flush(comp, prog_node),
+ .c => return @fieldParentPtr(C, "base", base).flush(comp, prog_node),
+ .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp, prog_node),
+ .spirv => return @fieldParentPtr(SpirV, "base", base).flush(comp, prog_node),
+ .plan9 => return @fieldParentPtr(Plan9, "base", base).flush(comp, prog_node),
+ .nvptx => return @fieldParentPtr(NvPtx, "base", base).flush(comp, prog_node),
}
}
/// Commit pending changes and write headers. Works based on `effectiveOutputMode`
/// rather than final output mode.
- pub fn flushModule(base: *File, comp: *Compilation) !void {
+ pub fn flushModule(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) !void {
switch (base.tag) {
- .coff => return @fieldParentPtr(Coff, "base", base).flushModule(comp),
- .elf => return @fieldParentPtr(Elf, "base", base).flushModule(comp),
- .macho => return @fieldParentPtr(MachO, "base", base).flushModule(comp),
- .c => return @fieldParentPtr(C, "base", base).flushModule(comp),
- .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp),
- .spirv => return @fieldParentPtr(SpirV, "base", base).flushModule(comp),
- .plan9 => return @fieldParentPtr(Plan9, "base", base).flushModule(comp),
- .nvptx => return @fieldParentPtr(NvPtx, "base", base).flushModule(comp),
+ .coff => return @fieldParentPtr(Coff, "base", base).flushModule(comp, prog_node),
+ .elf => return @fieldParentPtr(Elf, "base", base).flushModule(comp, prog_node),
+ .macho => return @fieldParentPtr(MachO, "base", base).flushModule(comp, prog_node),
+ .c => return @fieldParentPtr(C, "base", base).flushModule(comp, prog_node),
+ .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp, prog_node),
+ .spirv => return @fieldParentPtr(SpirV, "base", base).flushModule(comp, prog_node),
+ .plan9 => return @fieldParentPtr(Plan9, "base", base).flushModule(comp, prog_node),
+ .nvptx => return @fieldParentPtr(NvPtx, "base", base).flushModule(comp, prog_node),
}
}
@@ -754,7 +754,7 @@ pub const File = struct {
}
}
- pub fn linkAsArchive(base: *File, comp: *Compilation) !void {
+ pub fn linkAsArchive(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
@@ -787,9 +787,9 @@ pub const File = struct {
}
}
if (base.options.object_format == .macho) {
- try base.cast(MachO).?.flushObject(comp);
+ try base.cast(MachO).?.flushObject(comp, prog_node);
} else {
- try base.flushModule(comp);
+ try base.flushModule(comp, prog_node);
}
break :blk try fs.path.join(arena, &.{
fs.path.dirname(full_out_path_z).?, base.intermediary_basename.?,