authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-17 04:06:51-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-17 04:09:35-07:00
loga7c05c06bef1570546cae4c45a76027819c7fa09
tree80ae95c7d5edf95f4ed8ed013eb0bf9e27e337fb
parent2aeaa1cfc4c563a24525fb27fd2783bfd5da808a

stage2: expose progress bar API to linker backends

This gives us insight as to what is happening when we are waiting for things such as LLVM emit object and LLD linking.

11 files changed, 134 insertions(+), 83 deletions(-)

src/Compilation.zig+16-14
......@@ -2084,7 +2084,13 @@ pub fn update(comp: *Compilation) !void {
20842084 }
20852085 }
20862086
2087 try comp.performAllTheWork();
2087 // If the terminal is dumb, we dont want to show the user all the output.
2088 var progress: std.Progress = .{ .dont_print_on_dumb = true };
2089 const main_progress_node = progress.start("", 0);
2090 defer main_progress_node.end();
2091 if (comp.color == .off) progress.terminal = null;
2092
2093 try comp.performAllTheWork(main_progress_node);
20882094
20892095 if (!use_stage1) {
20902096 if (comp.bin_file.options.module) |module| {
......@@ -2158,9 +2164,9 @@ pub fn update(comp: *Compilation) !void {
21582164 .path = dir_path,
21592165 };
21602166
2161 try comp.flush();
2167 try comp.flush(main_progress_node);
21622168 } else {
2163 try comp.flush();
2169 try comp.flush(main_progress_node);
21642170 }
21652171
21662172 // Failure here only means an unnecessary cache miss.
......@@ -2171,7 +2177,7 @@ pub fn update(comp: *Compilation) !void {
21712177 assert(comp.bin_file.lock == null);
21722178 comp.bin_file.lock = man.toOwnedLock();
21732179 } else {
2174 try comp.flush();
2180 try comp.flush(main_progress_node);
21752181 }
21762182
21772183 // Unload all source files to save memory.
......@@ -2188,8 +2194,8 @@ pub fn update(comp: *Compilation) !void {
21882194 }
21892195}
21902196
2191fn flush(comp: *Compilation) !void {
2192 try comp.bin_file.flush(comp); // This is needed before reading the error flags.
2197fn flush(comp: *Compilation, prog_node: *std.Progress.Node) !void {
2198 try comp.bin_file.flush(comp, prog_node); // This is needed before reading the error flags.
21932199 comp.link_error_flags = comp.bin_file.errorFlags();
21942200
21952201 const use_stage1 = build_options.omit_stage2 or
......@@ -2590,14 +2596,10 @@ pub fn getCompileLogOutput(self: *Compilation) []const u8 {
25902596 return module.compile_log_text.items;
25912597}
25922598
2593pub fn performAllTheWork(comp: *Compilation) error{ TimerUnsupported, OutOfMemory }!void {
2594 // If the terminal is dumb, we dont want to show the user all the
2595 // output.
2596 var progress: std.Progress = .{ .dont_print_on_dumb = true };
2597 var main_progress_node = progress.start("", 0);
2598 defer main_progress_node.end();
2599 if (comp.color == .off) progress.terminal = null;
2600
2599pub fn performAllTheWork(
2600 comp: *Compilation,
2601 main_progress_node: *std.Progress.Node,
2602) error{ TimerUnsupported, OutOfMemory }!void {
26012603 // Here we queue up all the AstGen tasks first, followed by C object compilation.
26022604 // We wait until the AstGen tasks are all completed before proceeding to the
26032605 // (at least for now) single-threaded main work queue. However, C object compilation
src/codegen/llvm.zig+6-1
......@@ -469,7 +469,12 @@ pub const Object = struct {
469469 _ = builder.buildRet(is_lt);
470470 }
471471
472 pub fn flushModule(self: *Object, comp: *Compilation) !void {
472 pub fn flushModule(self: *Object, comp: *Compilation, prog_node: *std.Progress.Node) !void {
473 var sub_prog_node = prog_node.start("LLVM Emit Object", 0);
474 sub_prog_node.activate();
475 sub_prog_node.context.refresh();
476 defer sub_prog_node.end();
477
473478 try self.genErrorNameTable(comp);
474479 try self.genCmpLtErrorsLenFunction(comp);
475480
src/link.zig+22-22
......@@ -573,7 +573,7 @@ pub const File = struct {
573573
574574 /// Commit pending changes and write headers. Takes into account final output mode
575575 /// and `use_lld`, not only `effectiveOutputMode`.
576 pub fn flush(base: *File, comp: *Compilation) !void {
576 pub fn flush(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) !void {
577577 if (comp.clang_preprocessor_mode == .yes) {
578578 const emit = base.options.emit orelse return; // -fno-emit-bin
579579 // 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 {
591591
592592 const use_lld = build_options.have_llvm and base.options.use_lld;
593593 if (use_lld and base.options.output_mode == .Lib and base.options.link_mode == .Static) {
594 return base.linkAsArchive(comp);
594 return base.linkAsArchive(comp, prog_node);
595595 }
596596 switch (base.tag) {
597 .coff => return @fieldParentPtr(Coff, "base", base).flush(comp),
598 .elf => return @fieldParentPtr(Elf, "base", base).flush(comp),
599 .macho => return @fieldParentPtr(MachO, "base", base).flush(comp),
600 .c => return @fieldParentPtr(C, "base", base).flush(comp),
601 .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp),
602 .spirv => return @fieldParentPtr(SpirV, "base", base).flush(comp),
603 .plan9 => return @fieldParentPtr(Plan9, "base", base).flush(comp),
604 .nvptx => return @fieldParentPtr(NvPtx, "base", base).flush(comp),
597 .coff => return @fieldParentPtr(Coff, "base", base).flush(comp, prog_node),
598 .elf => return @fieldParentPtr(Elf, "base", base).flush(comp, prog_node),
599 .macho => return @fieldParentPtr(MachO, "base", base).flush(comp, prog_node),
600 .c => return @fieldParentPtr(C, "base", base).flush(comp, prog_node),
601 .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp, prog_node),
602 .spirv => return @fieldParentPtr(SpirV, "base", base).flush(comp, prog_node),
603 .plan9 => return @fieldParentPtr(Plan9, "base", base).flush(comp, prog_node),
604 .nvptx => return @fieldParentPtr(NvPtx, "base", base).flush(comp, prog_node),
605605 }
606606 }
607607
608608 /// Commit pending changes and write headers. Works based on `effectiveOutputMode`
609609 /// rather than final output mode.
610 pub fn flushModule(base: *File, comp: *Compilation) !void {
610 pub fn flushModule(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) !void {
611611 switch (base.tag) {
612 .coff => return @fieldParentPtr(Coff, "base", base).flushModule(comp),
613 .elf => return @fieldParentPtr(Elf, "base", base).flushModule(comp),
614 .macho => return @fieldParentPtr(MachO, "base", base).flushModule(comp),
615 .c => return @fieldParentPtr(C, "base", base).flushModule(comp),
616 .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp),
617 .spirv => return @fieldParentPtr(SpirV, "base", base).flushModule(comp),
618 .plan9 => return @fieldParentPtr(Plan9, "base", base).flushModule(comp),
619 .nvptx => return @fieldParentPtr(NvPtx, "base", base).flushModule(comp),
612 .coff => return @fieldParentPtr(Coff, "base", base).flushModule(comp, prog_node),
613 .elf => return @fieldParentPtr(Elf, "base", base).flushModule(comp, prog_node),
614 .macho => return @fieldParentPtr(MachO, "base", base).flushModule(comp, prog_node),
615 .c => return @fieldParentPtr(C, "base", base).flushModule(comp, prog_node),
616 .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp, prog_node),
617 .spirv => return @fieldParentPtr(SpirV, "base", base).flushModule(comp, prog_node),
618 .plan9 => return @fieldParentPtr(Plan9, "base", base).flushModule(comp, prog_node),
619 .nvptx => return @fieldParentPtr(NvPtx, "base", base).flushModule(comp, prog_node),
620620 }
621621 }
622622
......@@ -754,7 +754,7 @@ pub const File = struct {
754754 }
755755 }
756756
757 pub fn linkAsArchive(base: *File, comp: *Compilation) !void {
757 pub fn linkAsArchive(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) !void {
758758 const tracy = trace(@src());
759759 defer tracy.end();
760760
......@@ -787,9 +787,9 @@ pub const File = struct {
787787 }
788788 }
789789 if (base.options.object_format == .macho) {
790 try base.cast(MachO).?.flushObject(comp);
790 try base.cast(MachO).?.flushObject(comp, prog_node);
791791 } else {
792 try base.flushModule(comp);
792 try base.flushModule(comp, prog_node);
793793 }
794794 break :blk try fs.path.join(arena, &.{
795795 fs.path.dirname(full_out_path_z).?, base.intermediary_basename.?,
src/link/C.zig+7-3
......@@ -235,14 +235,18 @@ pub fn updateDeclLineNumber(self: *C, module: *Module, decl: *Module.Decl) !void
235235 _ = decl;
236236}
237237
238pub fn flush(self: *C, comp: *Compilation) !void {
239 return self.flushModule(comp);
238pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void {
239 return self.flushModule(comp, prog_node);
240240}
241241
242pub fn flushModule(self: *C, comp: *Compilation) !void {
242pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void {
243243 const tracy = trace(@src());
244244 defer tracy.end();
245245
246 var sub_prog_node = prog_node.start("Flush Module", 0);
247 sub_prog_node.activate();
248 defer sub_prog_node.end();
249
246250 const gpa = comp.gpa;
247251 const module = self.base.options.module.?;
248252
src/link/Coff.zig+17-8
......@@ -829,36 +829,40 @@ pub fn updateDeclExports(
829829 }
830830}
831831
832pub fn flush(self: *Coff, comp: *Compilation) !void {
832pub fn flush(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void {
833833 if (self.base.options.emit == null) {
834834 if (build_options.have_llvm) {
835835 if (self.llvm_object) |llvm_object| {
836 return try llvm_object.flushModule(comp);
836 return try llvm_object.flushModule(comp, prog_node);
837837 }
838838 }
839839 return;
840840 }
841841 if (build_options.have_llvm and self.base.options.use_lld) {
842 return self.linkWithLLD(comp);
842 return self.linkWithLLD(comp, prog_node);
843843 } else {
844844 switch (self.base.options.effectiveOutputMode()) {
845845 .Exe, .Obj => {},
846846 .Lib => return error.TODOImplementWritingLibFiles,
847847 }
848 return self.flushModule(comp);
848 return self.flushModule(comp, prog_node);
849849 }
850850}
851851
852pub fn flushModule(self: *Coff, comp: *Compilation) !void {
852pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void {
853853 const tracy = trace(@src());
854854 defer tracy.end();
855855
856856 if (build_options.have_llvm) {
857857 if (self.llvm_object) |llvm_object| {
858 return try llvm_object.flushModule(comp);
858 return try llvm_object.flushModule(comp, prog_node);
859859 }
860860 }
861861
862 var sub_prog_node = prog_node.start("COFF Flush", 0);
863 sub_prog_node.activate();
864 defer sub_prog_node.end();
865
862866 if (self.text_section_size_dirty) {
863867 // Write the new raw size in the .text header
864868 var buf: [4]u8 = undefined;
......@@ -892,7 +896,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void {
892896 }
893897}
894898
895fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
899fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void {
896900 const tracy = trace(@src());
897901 defer tracy.end();
898902
......@@ -924,7 +928,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
924928 }
925929 }
926930
927 try self.flushModule(comp);
931 try self.flushModule(comp, prog_node);
928932
929933 if (fs.path.dirname(full_out_path)) |dirname| {
930934 break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? });
......@@ -933,6 +937,11 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
933937 }
934938 } else null;
935939
940 var sub_prog_node = prog_node.start("LLD Link", 0);
941 sub_prog_node.activate();
942 sub_prog_node.context.refresh();
943 defer sub_prog_node.end();
944
936945 const is_lib = self.base.options.output_mode == .Lib;
937946 const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
938947 const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe;
src/link/Elf.zig+17-8
......@@ -929,35 +929,39 @@ pub fn populateMissingMetadata(self: *Elf) !void {
929929 }
930930}
931931
932pub fn flush(self: *Elf, comp: *Compilation) !void {
932pub fn flush(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
933933 if (self.base.options.emit == null) {
934934 if (build_options.have_llvm) {
935935 if (self.llvm_object) |llvm_object| {
936 return try llvm_object.flushModule(comp);
936 return try llvm_object.flushModule(comp, prog_node);
937937 }
938938 }
939939 return;
940940 }
941941 const use_lld = build_options.have_llvm and self.base.options.use_lld;
942942 if (use_lld) {
943 return self.linkWithLLD(comp);
943 return self.linkWithLLD(comp, prog_node);
944944 }
945945 switch (self.base.options.output_mode) {
946 .Exe, .Obj => return self.flushModule(comp),
946 .Exe, .Obj => return self.flushModule(comp, prog_node),
947947 .Lib => return error.TODOImplementWritingLibFiles,
948948 }
949949}
950950
951pub fn flushModule(self: *Elf, comp: *Compilation) !void {
951pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
952952 const tracy = trace(@src());
953953 defer tracy.end();
954954
955955 if (build_options.have_llvm) {
956956 if (self.llvm_object) |llvm_object| {
957 return try llvm_object.flushModule(comp);
957 return try llvm_object.flushModule(comp, prog_node);
958958 }
959959 }
960960
961 var sub_prog_node = prog_node.start("ELF Flush", 0);
962 sub_prog_node.activate();
963 defer sub_prog_node.end();
964
961965 // TODO This linker code currently assumes there is only 1 compilation unit and it
962966 // corresponds to the Zig source code.
963967 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
......@@ -1204,7 +1208,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
12041208 assert(!self.debug_strtab_dirty);
12051209}
12061210
1207fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1211fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
12081212 const tracy = trace(@src());
12091213 defer tracy.end();
12101214
......@@ -1236,7 +1240,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
12361240 }
12371241 }
12381242
1239 try self.flushModule(comp);
1243 try self.flushModule(comp, prog_node);
12401244
12411245 if (fs.path.dirname(full_out_path)) |dirname| {
12421246 break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? });
......@@ -1245,6 +1249,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
12451249 }
12461250 } else null;
12471251
1252 var sub_prog_node = prog_node.start("LLD Link", 0);
1253 sub_prog_node.activate();
1254 sub_prog_node.context.refresh();
1255 defer sub_prog_node.end();
1256
12481257 const is_obj = self.base.options.output_mode == .Obj;
12491258 const is_lib = self.base.options.output_mode == .Lib;
12501259 const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
src/link/MachO.zig+14-9
......@@ -419,33 +419,34 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
419419 return self;
420420}
421421
422pub fn flush(self: *MachO, comp: *Compilation) !void {
422pub fn flush(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void {
423423 if (self.base.options.emit == null) {
424424 if (build_options.have_llvm) {
425425 if (self.llvm_object) |llvm_object| {
426 try llvm_object.flushModule(comp);
426 try llvm_object.flushModule(comp, prog_node);
427427 }
428428 }
429429 return;
430430 }
431
431432 if (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Static) {
432433 if (build_options.have_llvm) {
433 return self.base.linkAsArchive(comp);
434 return self.base.linkAsArchive(comp, prog_node);
434435 } else {
435436 log.err("TODO: non-LLVM archiver for MachO object files", .{});
436437 return error.TODOImplementWritingStaticLibFiles;
437438 }
438439 }
439 try self.flushModule(comp);
440 try self.flushModule(comp, prog_node);
440441}
441442
442pub fn flushModule(self: *MachO, comp: *Compilation) !void {
443pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void {
443444 const tracy = trace(@src());
444445 defer tracy.end();
445446
446447 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
447448 if (!use_stage1 and self.base.options.output_mode == .Obj)
448 return self.flushObject(comp);
449 return self.flushObject(comp, prog_node);
449450
450451 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
451452 defer arena_allocator.deinit();
......@@ -482,7 +483,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
482483
483484 const obj_basename = self.base.intermediary_basename orelse break :blk null;
484485
485 try self.flushObject(comp);
486 try self.flushObject(comp, prog_node);
486487
487488 if (fs.path.dirname(full_out_path)) |dirname| {
488489 break :blk try fs.path.join(arena, &.{ dirname, obj_basename });
......@@ -491,6 +492,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
491492 }
492493 } else null;
493494
495 var sub_prog_node = prog_node.start("MachO Flush", 0);
496 sub_prog_node.activate();
497 defer sub_prog_node.end();
498
494499 const is_lib = self.base.options.output_mode == .Lib;
495500 const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
496501 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 {
11111116 self.cold_start = false;
11121117}
11131118
1114pub fn flushObject(self: *MachO, comp: *Compilation) !void {
1119pub fn flushObject(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void {
11151120 const tracy = trace(@src());
11161121 defer tracy.end();
11171122
11181123 if (build_options.have_llvm)
11191124 if (self.llvm_object) |llvm_object|
1120 return llvm_object.flushModule(comp);
1125 return llvm_object.flushModule(comp, prog_node);
11211126
11221127 return error.TODOImplementWritingObjFiles;
11231128}
src/link/NvPtx.zig+4-4
......@@ -97,11 +97,11 @@ pub fn freeDecl(self: *NvPtx, decl: *Module.Decl) void {
9797 return self.llvm_object.freeDecl(decl);
9898}
9999
100pub fn flush(self: *NvPtx, comp: *Compilation) !void {
101 return self.flushModule(comp);
100pub fn flush(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) !void {
101 return self.flushModule(comp, prog_node);
102102}
103103
104pub fn flushModule(self: *NvPtx, comp: *Compilation) !void {
104pub fn flushModule(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) !void {
105105 if (!build_options.have_llvm) return;
106106 if (build_options.skip_non_native) {
107107 @panic("Attempted to compile for architecture that was disabled by build configuration");
......@@ -117,5 +117,5 @@ pub fn flushModule(self: *NvPtx, comp: *Compilation) !void {
117117 };
118118 hack_comp.bin_file.options.emit = null;
119119 }
120 return try self.llvm_object.flushModule(hack_comp);
120 return try self.llvm_object.flushModule(hack_comp, prog_node);
121121}
src/link/Plan9.zig+7-3
......@@ -351,7 +351,7 @@ fn updateFinish(self: *Plan9, decl: *Module.Decl) !void {
351351 }
352352}
353353
354pub fn flush(self: *Plan9, comp: *Compilation) !void {
354pub fn flush(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) !void {
355355 assert(!self.base.options.use_lld);
356356
357357 switch (self.base.options.effectiveOutputMode()) {
......@@ -360,7 +360,7 @@ pub fn flush(self: *Plan9, comp: *Compilation) !void {
360360 .Obj => return error.TODOImplementPlan9Objs,
361361 .Lib => return error.TODOImplementWritingLibFiles,
362362 }
363 return self.flushModule(comp);
363 return self.flushModule(comp, prog_node);
364364}
365365
366366pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void {
......@@ -387,7 +387,7 @@ fn declCount(self: *Plan9) usize {
387387 return self.data_decl_table.count() + fn_decl_count;
388388}
389389
390pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
390pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) !void {
391391 if (build_options.skip_non_native and builtin.object_format != .plan9) {
392392 @panic("Attempted to compile for object format that was disabled by build configuration");
393393 }
......@@ -396,6 +396,10 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
396396 const tracy = trace(@src());
397397 defer tracy.end();
398398
399 var sub_prog_node = prog_node.start("Flush Module", 0);
400 sub_prog_node.activate();
401 defer sub_prog_node.end();
402
399403 log.debug("flushModule", .{});
400404
401405 defer assert(self.hdr.entry != 0x0);
src/link/SpirV.zig+7-3
......@@ -174,15 +174,15 @@ pub fn freeDecl(self: *SpirV, decl: *Module.Decl) void {
174174 self.decl_table.swapRemoveAt(index);
175175}
176176
177pub fn flush(self: *SpirV, comp: *Compilation) !void {
177pub fn flush(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) !void {
178178 if (build_options.have_llvm and self.base.options.use_lld) {
179179 return error.LLD_LinkingIsTODO_ForSpirV; // TODO: LLD Doesn't support SpirV at all.
180180 } else {
181 return self.flushModule(comp);
181 return self.flushModule(comp, prog_node);
182182 }
183183}
184184
185pub fn flushModule(self: *SpirV, comp: *Compilation) !void {
185pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) !void {
186186 if (build_options.skip_non_native) {
187187 @panic("Attempted to compile for architecture that was disabled by build configuration");
188188 }
......@@ -190,6 +190,10 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void {
190190 const tracy = trace(@src());
191191 defer tracy.end();
192192
193 var sub_prog_node = prog_node.start("Flush Module", 0);
194 sub_prog_node.activate();
195 defer sub_prog_node.end();
196
193197 const module = self.base.options.module.?;
194198 const target = comp.getTarget();
195199
src/link/Wasm.zig+17-8
......@@ -1477,32 +1477,36 @@ fn resetState(self: *Wasm) void {
14771477 self.code_section_index = null;
14781478}
14791479
1480pub fn flush(self: *Wasm, comp: *Compilation) !void {
1480pub fn flush(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void {
14811481 if (self.base.options.emit == null) {
14821482 if (build_options.have_llvm) {
14831483 if (self.llvm_object) |llvm_object| {
1484 return try llvm_object.flushModule(comp);
1484 return try llvm_object.flushModule(comp, prog_node);
14851485 }
14861486 }
14871487 return;
14881488 }
14891489 if (build_options.have_llvm and self.base.options.use_lld) {
1490 return self.linkWithLLD(comp);
1490 return self.linkWithLLD(comp, prog_node);
14911491 } else {
1492 return self.flushModule(comp);
1492 return self.flushModule(comp, prog_node);
14931493 }
14941494}
14951495
1496pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
1496pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void {
14971497 const tracy = trace(@src());
14981498 defer tracy.end();
14991499
15001500 if (build_options.have_llvm) {
15011501 if (self.llvm_object) |llvm_object| {
1502 return try llvm_object.flushModule(comp);
1502 return try llvm_object.flushModule(comp, prog_node);
15031503 }
15041504 }
15051505
1506 var sub_prog_node = prog_node.start("WASM Flush", 0);
1507 sub_prog_node.activate();
1508 defer sub_prog_node.end();
1509
15061510 // ensure the error names table is populated when an error name is referenced
15071511 try self.populateErrorNameTable();
15081512
......@@ -2028,7 +2032,7 @@ fn emitImport(self: *Wasm, writer: anytype, import: types.Import) !void {
20282032 }
20292033}
20302034
2031fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
2035fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void {
20322036 const tracy = trace(@src());
20332037 defer tracy.end();
20342038
......@@ -2060,7 +2064,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
20602064 }
20612065 }
20622066
2063 try self.flushModule(comp);
2067 try self.flushModule(comp, prog_node);
20642068
20652069 if (fs.path.dirname(full_out_path)) |dirname| {
20662070 break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? });
......@@ -2069,6 +2073,11 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
20692073 }
20702074 } else null;
20712075
2076 var sub_prog_node = prog_node.start("LLD Link", 0);
2077 sub_prog_node.activate();
2078 sub_prog_node.context.refresh();
2079 defer sub_prog_node.end();
2080
20722081 const is_obj = self.base.options.output_mode == .Obj;
20732082
20742083 const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj)