| author | |
| committer | |
| log | a7c05c06bef1570546cae4c45a76027819c7fa09 |
| tree | 80ae95c7d5edf95f4ed8ed013eb0bf9e27e337fb |
| parent | 2aeaa1cfc4c563a24525fb27fd2783bfd5da808a |
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 { | ... | @@ -2084,7 +2084,13 @@ pub fn update(comp: *Compilation) !void { |
| 2084 | } | 2084 | } |
| 2085 | } | 2085 | } |
| 2086 | 2086 | ||
| 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); | ||
| 2088 | 2094 | ||
| 2089 | if (!use_stage1) { | 2095 | if (!use_stage1) { |
| 2090 | if (comp.bin_file.options.module) |module| { | 2096 | if (comp.bin_file.options.module) |module| { |
| ... | @@ -2158,9 +2164,9 @@ pub fn update(comp: *Compilation) !void { | ... | @@ -2158,9 +2164,9 @@ pub fn update(comp: *Compilation) !void { |
| 2158 | .path = dir_path, | 2164 | .path = dir_path, |
| 2159 | }; | 2165 | }; |
| 2160 | 2166 | ||
| 2161 | try comp.flush(); | 2167 | try comp.flush(main_progress_node); |
| 2162 | } else { | 2168 | } else { |
| 2163 | try comp.flush(); | 2169 | try comp.flush(main_progress_node); |
| 2164 | } | 2170 | } |
| 2165 | 2171 | ||
| 2166 | // Failure here only means an unnecessary cache miss. | 2172 | // Failure here only means an unnecessary cache miss. |
| ... | @@ -2171,7 +2177,7 @@ pub fn update(comp: *Compilation) !void { | ... | @@ -2171,7 +2177,7 @@ pub fn update(comp: *Compilation) !void { |
| 2171 | assert(comp.bin_file.lock == null); | 2177 | assert(comp.bin_file.lock == null); |
| 2172 | comp.bin_file.lock = man.toOwnedLock(); | 2178 | comp.bin_file.lock = man.toOwnedLock(); |
| 2173 | } else { | 2179 | } else { |
| 2174 | try comp.flush(); | 2180 | try comp.flush(main_progress_node); |
| 2175 | } | 2181 | } |
| 2176 | 2182 | ||
| 2177 | // Unload all source files to save memory. | 2183 | // Unload all source files to save memory. |
| ... | @@ -2188,8 +2194,8 @@ pub fn update(comp: *Compilation) !void { | ... | @@ -2188,8 +2194,8 @@ pub fn update(comp: *Compilation) !void { |
| 2188 | } | 2194 | } |
| 2189 | } | 2195 | } |
| 2190 | 2196 | ||
| 2191 | fn flush(comp: *Compilation) !void { | 2197 | fn flush(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 2192 | try comp.bin_file.flush(comp); // This is needed before reading the error flags. | 2198 | try comp.bin_file.flush(comp, prog_node); // This is needed before reading the error flags. |
| 2193 | comp.link_error_flags = comp.bin_file.errorFlags(); | 2199 | comp.link_error_flags = comp.bin_file.errorFlags(); |
| 2194 | 2200 | ||
| 2195 | const use_stage1 = build_options.omit_stage2 or | 2201 | const use_stage1 = build_options.omit_stage2 or |
| ... | @@ -2590,14 +2596,10 @@ pub fn getCompileLogOutput(self: *Compilation) []const u8 { | ... | @@ -2590,14 +2596,10 @@ pub fn getCompileLogOutput(self: *Compilation) []const u8 { |
| 2590 | return module.compile_log_text.items; | 2596 | return module.compile_log_text.items; |
| 2591 | } | 2597 | } |
| 2592 | 2598 | ||
| 2593 | pub fn performAllTheWork(comp: *Compilation) error{ TimerUnsupported, OutOfMemory }!void { | 2599 | pub fn performAllTheWork( |
| 2594 | // If the terminal is dumb, we dont want to show the user all the | 2600 | comp: *Compilation, |
| 2595 | // output. | 2601 | main_progress_node: *std.Progress.Node, |
| 2596 | var progress: std.Progress = .{ .dont_print_on_dumb = true }; | 2602 | ) error{ TimerUnsupported, OutOfMemory }!void { |
| 2597 | var main_progress_node = progress.start("", 0); | ||
| 2598 | defer main_progress_node.end(); | ||
| 2599 | if (comp.color == .off) progress.terminal = null; | ||
| 2600 | |||
| 2601 | // Here we queue up all the AstGen tasks first, followed by C object compilation. | 2603 | // Here we queue up all the AstGen tasks first, followed by C object compilation. |
| 2602 | // We wait until the AstGen tasks are all completed before proceeding to the | 2604 | // We wait until the AstGen tasks are all completed before proceeding to the |
| 2603 | // (at least for now) single-threaded main work queue. However, C object compilation | 2605 | // (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 { | ... | @@ -469,7 +469,12 @@ pub const Object = struct { |
| 469 | _ = builder.buildRet(is_lt); | 469 | _ = builder.buildRet(is_lt); |
| 470 | } | 470 | } |
| 471 | 471 | ||
| 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 | |||
| 473 | try self.genErrorNameTable(comp); | 478 | try self.genErrorNameTable(comp); |
| 474 | try self.genCmpLtErrorsLenFunction(comp); | 479 | try self.genCmpLtErrorsLenFunction(comp); |
| 475 | 480 |
src/link.zig+22-22| ... | @@ -573,7 +573,7 @@ pub const File = struct { | ... | @@ -573,7 +573,7 @@ pub const File = struct { |
| 573 | 573 | ||
| 574 | /// Commit pending changes and write headers. Takes into account final output mode | 574 | /// Commit pending changes and write headers. Takes into account final output mode |
| 575 | /// and `use_lld`, not only `effectiveOutputMode`. | 575 | /// 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 { |
| 577 | if (comp.clang_preprocessor_mode == .yes) { | 577 | if (comp.clang_preprocessor_mode == .yes) { |
| 578 | const emit = base.options.emit orelse return; // -fno-emit-bin | 578 | const emit = base.options.emit orelse return; // -fno-emit-bin |
| 579 | // TODO: avoid extra link step when it's just 1 object file (the `zig cc -c` case) | 579 | // 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 { | ... | @@ -591,32 +591,32 @@ pub const File = struct { |
| 591 | 591 | ||
| 592 | const use_lld = build_options.have_llvm and base.options.use_lld; | 592 | const use_lld = build_options.have_llvm and base.options.use_lld; |
| 593 | if (use_lld and base.options.output_mode == .Lib and base.options.link_mode == .Static) { | 593 | 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); |
| 595 | } | 595 | } |
| 596 | switch (base.tag) { | 596 | switch (base.tag) { |
| 597 | .coff => return @fieldParentPtr(Coff, "base", base).flush(comp), | 597 | .coff => return @fieldParentPtr(Coff, "base", base).flush(comp, prog_node), |
| 598 | .elf => return @fieldParentPtr(Elf, "base", base).flush(comp), | 598 | .elf => return @fieldParentPtr(Elf, "base", base).flush(comp, prog_node), |
| 599 | .macho => return @fieldParentPtr(MachO, "base", base).flush(comp), | 599 | .macho => return @fieldParentPtr(MachO, "base", base).flush(comp, prog_node), |
| 600 | .c => return @fieldParentPtr(C, "base", base).flush(comp), | 600 | .c => return @fieldParentPtr(C, "base", base).flush(comp, prog_node), |
| 601 | .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp), | 601 | .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp, prog_node), |
| 602 | .spirv => return @fieldParentPtr(SpirV, "base", base).flush(comp), | 602 | .spirv => return @fieldParentPtr(SpirV, "base", base).flush(comp, prog_node), |
| 603 | .plan9 => return @fieldParentPtr(Plan9, "base", base).flush(comp), | 603 | .plan9 => return @fieldParentPtr(Plan9, "base", base).flush(comp, prog_node), |
| 604 | .nvptx => return @fieldParentPtr(NvPtx, "base", base).flush(comp), | 604 | .nvptx => return @fieldParentPtr(NvPtx, "base", base).flush(comp, prog_node), |
| 605 | } | 605 | } |
| 606 | } | 606 | } |
| 607 | 607 | ||
| 608 | /// Commit pending changes and write headers. Works based on `effectiveOutputMode` | 608 | /// Commit pending changes and write headers. Works based on `effectiveOutputMode` |
| 609 | /// rather than final output mode. | 609 | /// 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 { |
| 611 | switch (base.tag) { | 611 | switch (base.tag) { |
| 612 | .coff => return @fieldParentPtr(Coff, "base", base).flushModule(comp), | 612 | .coff => return @fieldParentPtr(Coff, "base", base).flushModule(comp, prog_node), |
| 613 | .elf => return @fieldParentPtr(Elf, "base", base).flushModule(comp), | 613 | .elf => return @fieldParentPtr(Elf, "base", base).flushModule(comp, prog_node), |
| 614 | .macho => return @fieldParentPtr(MachO, "base", base).flushModule(comp), | 614 | .macho => return @fieldParentPtr(MachO, "base", base).flushModule(comp, prog_node), |
| 615 | .c => return @fieldParentPtr(C, "base", base).flushModule(comp), | 615 | .c => return @fieldParentPtr(C, "base", base).flushModule(comp, prog_node), |
| 616 | .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp), | 616 | .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp, prog_node), |
| 617 | .spirv => return @fieldParentPtr(SpirV, "base", base).flushModule(comp), | 617 | .spirv => return @fieldParentPtr(SpirV, "base", base).flushModule(comp, prog_node), |
| 618 | .plan9 => return @fieldParentPtr(Plan9, "base", base).flushModule(comp), | 618 | .plan9 => return @fieldParentPtr(Plan9, "base", base).flushModule(comp, prog_node), |
| 619 | .nvptx => return @fieldParentPtr(NvPtx, "base", base).flushModule(comp), | 619 | .nvptx => return @fieldParentPtr(NvPtx, "base", base).flushModule(comp, prog_node), |
| 620 | } | 620 | } |
| 621 | } | 621 | } |
| 622 | 622 | ||
| ... | @@ -754,7 +754,7 @@ pub const File = struct { | ... | @@ -754,7 +754,7 @@ pub const File = struct { |
| 754 | } | 754 | } |
| 755 | } | 755 | } |
| 756 | 756 | ||
| 757 | pub fn linkAsArchive(base: *File, comp: *Compilation) !void { | 757 | pub fn linkAsArchive(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 758 | const tracy = trace(@src()); | 758 | const tracy = trace(@src()); |
| 759 | defer tracy.end(); | 759 | defer tracy.end(); |
| 760 | 760 | ||
| ... | @@ -787,9 +787,9 @@ pub const File = struct { | ... | @@ -787,9 +787,9 @@ pub const File = struct { |
| 787 | } | 787 | } |
| 788 | } | 788 | } |
| 789 | if (base.options.object_format == .macho) { | 789 | if (base.options.object_format == .macho) { |
| 790 | try base.cast(MachO).?.flushObject(comp); | 790 | try base.cast(MachO).?.flushObject(comp, prog_node); |
| 791 | } else { | 791 | } else { |
| 792 | try base.flushModule(comp); | 792 | try base.flushModule(comp, prog_node); |
| 793 | } | 793 | } |
| 794 | break :blk try fs.path.join(arena, &.{ | 794 | break :blk try fs.path.join(arena, &.{ |
| 795 | fs.path.dirname(full_out_path_z).?, base.intermediary_basename.?, | 795 | 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 | ... | @@ -235,14 +235,18 @@ pub fn updateDeclLineNumber(self: *C, module: *Module, decl: *Module.Decl) !void |
| 235 | _ = decl; | 235 | _ = decl; |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | pub fn flush(self: *C, comp: *Compilation) !void { | 238 | pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 239 | return self.flushModule(comp); | 239 | return self.flushModule(comp, prog_node); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | pub fn flushModule(self: *C, comp: *Compilation) !void { | 242 | pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 243 | const tracy = trace(@src()); | 243 | const tracy = trace(@src()); |
| 244 | defer tracy.end(); | 244 | defer tracy.end(); |
| 245 | 245 | ||
| 246 | var sub_prog_node = prog_node.start("Flush Module", 0); | ||
| 247 | sub_prog_node.activate(); | ||
| 248 | defer sub_prog_node.end(); | ||
| 249 | |||
| 246 | const gpa = comp.gpa; | 250 | const gpa = comp.gpa; |
| 247 | const module = self.base.options.module.?; | 251 | const module = self.base.options.module.?; |
| 248 | 252 |
src/link/Coff.zig+17-8| ... | @@ -829,36 +829,40 @@ pub fn updateDeclExports( | ... | @@ -829,36 +829,40 @@ pub fn updateDeclExports( |
| 829 | } | 829 | } |
| 830 | } | 830 | } |
| 831 | 831 | ||
| 832 | pub fn flush(self: *Coff, comp: *Compilation) !void { | 832 | pub fn flush(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 833 | if (self.base.options.emit == null) { | 833 | if (self.base.options.emit == null) { |
| 834 | if (build_options.have_llvm) { | 834 | if (build_options.have_llvm) { |
| 835 | if (self.llvm_object) |llvm_object| { | 835 | if (self.llvm_object) |llvm_object| { |
| 836 | return try llvm_object.flushModule(comp); | 836 | return try llvm_object.flushModule(comp, prog_node); |
| 837 | } | 837 | } |
| 838 | } | 838 | } |
| 839 | return; | 839 | return; |
| 840 | } | 840 | } |
| 841 | if (build_options.have_llvm and self.base.options.use_lld) { | 841 | if (build_options.have_llvm and self.base.options.use_lld) { |
| 842 | return self.linkWithLLD(comp); | 842 | return self.linkWithLLD(comp, prog_node); |
| 843 | } else { | 843 | } else { |
| 844 | switch (self.base.options.effectiveOutputMode()) { | 844 | switch (self.base.options.effectiveOutputMode()) { |
| 845 | .Exe, .Obj => {}, | 845 | .Exe, .Obj => {}, |
| 846 | .Lib => return error.TODOImplementWritingLibFiles, | 846 | .Lib => return error.TODOImplementWritingLibFiles, |
| 847 | } | 847 | } |
| 848 | return self.flushModule(comp); | 848 | return self.flushModule(comp, prog_node); |
| 849 | } | 849 | } |
| 850 | } | 850 | } |
| 851 | 851 | ||
| 852 | pub fn flushModule(self: *Coff, comp: *Compilation) !void { | 852 | pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 853 | const tracy = trace(@src()); | 853 | const tracy = trace(@src()); |
| 854 | defer tracy.end(); | 854 | defer tracy.end(); |
| 855 | 855 | ||
| 856 | if (build_options.have_llvm) { | 856 | if (build_options.have_llvm) { |
| 857 | if (self.llvm_object) |llvm_object| { | 857 | if (self.llvm_object) |llvm_object| { |
| 858 | return try llvm_object.flushModule(comp); | 858 | return try llvm_object.flushModule(comp, prog_node); |
| 859 | } | 859 | } |
| 860 | } | 860 | } |
| 861 | 861 | ||
| 862 | var sub_prog_node = prog_node.start("COFF Flush", 0); | ||
| 863 | sub_prog_node.activate(); | ||
| 864 | defer sub_prog_node.end(); | ||
| 865 | |||
| 862 | if (self.text_section_size_dirty) { | 866 | if (self.text_section_size_dirty) { |
| 863 | // Write the new raw size in the .text header | 867 | // Write the new raw size in the .text header |
| 864 | var buf: [4]u8 = undefined; | 868 | var buf: [4]u8 = undefined; |
| ... | @@ -892,7 +896,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void { | ... | @@ -892,7 +896,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void { |
| 892 | } | 896 | } |
| 893 | } | 897 | } |
| 894 | 898 | ||
| 895 | fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | 899 | fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 896 | const tracy = trace(@src()); | 900 | const tracy = trace(@src()); |
| 897 | defer tracy.end(); | 901 | defer tracy.end(); |
| 898 | 902 | ||
| ... | @@ -924,7 +928,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | ... | @@ -924,7 +928,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 924 | } | 928 | } |
| 925 | } | 929 | } |
| 926 | 930 | ||
| 927 | try self.flushModule(comp); | 931 | try self.flushModule(comp, prog_node); |
| 928 | 932 | ||
| 929 | if (fs.path.dirname(full_out_path)) |dirname| { | 933 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 930 | break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? }); | 934 | break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? }); |
| ... | @@ -933,6 +937,11 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | ... | @@ -933,6 +937,11 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 933 | } | 937 | } |
| 934 | } else null; | 938 | } else null; |
| 935 | 939 | ||
| 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 | |||
| 936 | const is_lib = self.base.options.output_mode == .Lib; | 945 | const is_lib = self.base.options.output_mode == .Lib; |
| 937 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; | 946 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; |
| 938 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe; | 947 | 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 { | ... | @@ -929,35 +929,39 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 929 | } | 929 | } |
| 930 | } | 930 | } |
| 931 | 931 | ||
| 932 | pub fn flush(self: *Elf, comp: *Compilation) !void { | 932 | pub fn flush(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 933 | if (self.base.options.emit == null) { | 933 | if (self.base.options.emit == null) { |
| 934 | if (build_options.have_llvm) { | 934 | if (build_options.have_llvm) { |
| 935 | if (self.llvm_object) |llvm_object| { | 935 | if (self.llvm_object) |llvm_object| { |
| 936 | return try llvm_object.flushModule(comp); | 936 | return try llvm_object.flushModule(comp, prog_node); |
| 937 | } | 937 | } |
| 938 | } | 938 | } |
| 939 | return; | 939 | return; |
| 940 | } | 940 | } |
| 941 | const use_lld = build_options.have_llvm and self.base.options.use_lld; | 941 | const use_lld = build_options.have_llvm and self.base.options.use_lld; |
| 942 | if (use_lld) { | 942 | if (use_lld) { |
| 943 | return self.linkWithLLD(comp); | 943 | return self.linkWithLLD(comp, prog_node); |
| 944 | } | 944 | } |
| 945 | switch (self.base.options.output_mode) { | 945 | switch (self.base.options.output_mode) { |
| 946 | .Exe, .Obj => return self.flushModule(comp), | 946 | .Exe, .Obj => return self.flushModule(comp, prog_node), |
| 947 | .Lib => return error.TODOImplementWritingLibFiles, | 947 | .Lib => return error.TODOImplementWritingLibFiles, |
| 948 | } | 948 | } |
| 949 | } | 949 | } |
| 950 | 950 | ||
| 951 | pub fn flushModule(self: *Elf, comp: *Compilation) !void { | 951 | pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 952 | const tracy = trace(@src()); | 952 | const tracy = trace(@src()); |
| 953 | defer tracy.end(); | 953 | defer tracy.end(); |
| 954 | 954 | ||
| 955 | if (build_options.have_llvm) { | 955 | if (build_options.have_llvm) { |
| 956 | if (self.llvm_object) |llvm_object| { | 956 | if (self.llvm_object) |llvm_object| { |
| 957 | return try llvm_object.flushModule(comp); | 957 | return try llvm_object.flushModule(comp, prog_node); |
| 958 | } | 958 | } |
| 959 | } | 959 | } |
| 960 | 960 | ||
| 961 | var sub_prog_node = prog_node.start("ELF Flush", 0); | ||
| 962 | sub_prog_node.activate(); | ||
| 963 | defer sub_prog_node.end(); | ||
| 964 | |||
| 961 | // TODO This linker code currently assumes there is only 1 compilation unit and it | 965 | // TODO This linker code currently assumes there is only 1 compilation unit and it |
| 962 | // corresponds to the Zig source code. | 966 | // corresponds to the Zig source code. |
| 963 | const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; | 967 | const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| ... | @@ -1204,7 +1208,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { | ... | @@ -1204,7 +1208,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 1204 | assert(!self.debug_strtab_dirty); | 1208 | assert(!self.debug_strtab_dirty); |
| 1205 | } | 1209 | } |
| 1206 | 1210 | ||
| 1207 | fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | 1211 | fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 1208 | const tracy = trace(@src()); | 1212 | const tracy = trace(@src()); |
| 1209 | defer tracy.end(); | 1213 | defer tracy.end(); |
| 1210 | 1214 | ||
| ... | @@ -1236,7 +1240,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1236,7 +1240,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1236 | } | 1240 | } |
| 1237 | } | 1241 | } |
| 1238 | 1242 | ||
| 1239 | try self.flushModule(comp); | 1243 | try self.flushModule(comp, prog_node); |
| 1240 | 1244 | ||
| 1241 | if (fs.path.dirname(full_out_path)) |dirname| { | 1245 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 1242 | break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? }); | 1246 | break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? }); |
| ... | @@ -1245,6 +1249,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1245,6 +1249,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1245 | } | 1249 | } |
| 1246 | } else null; | 1250 | } else null; |
| 1247 | 1251 | ||
| 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 | |||
| 1248 | const is_obj = self.base.options.output_mode == .Obj; | 1257 | const is_obj = self.base.options.output_mode == .Obj; |
| 1249 | const is_lib = self.base.options.output_mode == .Lib; | 1258 | const is_lib = self.base.options.output_mode == .Lib; |
| 1250 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; | 1259 | 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 { | ... | @@ -419,33 +419,34 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO { |
| 419 | return self; | 419 | return self; |
| 420 | } | 420 | } |
| 421 | 421 | ||
| 422 | pub fn flush(self: *MachO, comp: *Compilation) !void { | 422 | pub fn flush(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 423 | if (self.base.options.emit == null) { | 423 | if (self.base.options.emit == null) { |
| 424 | if (build_options.have_llvm) { | 424 | if (build_options.have_llvm) { |
| 425 | if (self.llvm_object) |llvm_object| { | 425 | if (self.llvm_object) |llvm_object| { |
| 426 | try llvm_object.flushModule(comp); | 426 | try llvm_object.flushModule(comp, prog_node); |
| 427 | } | 427 | } |
| 428 | } | 428 | } |
| 429 | return; | 429 | return; |
| 430 | } | 430 | } |
| 431 | |||
| 431 | if (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Static) { | 432 | if (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Static) { |
| 432 | if (build_options.have_llvm) { | 433 | if (build_options.have_llvm) { |
| 433 | return self.base.linkAsArchive(comp); | 434 | return self.base.linkAsArchive(comp, prog_node); |
| 434 | } else { | 435 | } else { |
| 435 | log.err("TODO: non-LLVM archiver for MachO object files", .{}); | 436 | log.err("TODO: non-LLVM archiver for MachO object files", .{}); |
| 436 | return error.TODOImplementWritingStaticLibFiles; | 437 | return error.TODOImplementWritingStaticLibFiles; |
| 437 | } | 438 | } |
| 438 | } | 439 | } |
| 439 | try self.flushModule(comp); | 440 | try self.flushModule(comp, prog_node); |
| 440 | } | 441 | } |
| 441 | 442 | ||
| 442 | pub fn flushModule(self: *MachO, comp: *Compilation) !void { | 443 | pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 443 | const tracy = trace(@src()); | 444 | const tracy = trace(@src()); |
| 444 | defer tracy.end(); | 445 | defer tracy.end(); |
| 445 | 446 | ||
| 446 | const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1; | 447 | const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1; |
| 447 | if (!use_stage1 and self.base.options.output_mode == .Obj) | 448 | if (!use_stage1 and self.base.options.output_mode == .Obj) |
| 448 | return self.flushObject(comp); | 449 | return self.flushObject(comp, prog_node); |
| 449 | 450 | ||
| 450 | var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator); | 451 | var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator); |
| 451 | defer arena_allocator.deinit(); | 452 | defer arena_allocator.deinit(); |
| ... | @@ -482,7 +483,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -482,7 +483,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 482 | 483 | ||
| 483 | const obj_basename = self.base.intermediary_basename orelse break :blk null; | 484 | const obj_basename = self.base.intermediary_basename orelse break :blk null; |
| 484 | 485 | ||
| 485 | try self.flushObject(comp); | 486 | try self.flushObject(comp, prog_node); |
| 486 | 487 | ||
| 487 | if (fs.path.dirname(full_out_path)) |dirname| { | 488 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 488 | break :blk try fs.path.join(arena, &.{ dirname, obj_basename }); | 489 | break :blk try fs.path.join(arena, &.{ dirname, obj_basename }); |
| ... | @@ -491,6 +492,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -491,6 +492,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 491 | } | 492 | } |
| 492 | } else null; | 493 | } else null; |
| 493 | 494 | ||
| 495 | var sub_prog_node = prog_node.start("MachO Flush", 0); | ||
| 496 | sub_prog_node.activate(); | ||
| 497 | defer sub_prog_node.end(); | ||
| 498 | |||
| 494 | const is_lib = self.base.options.output_mode == .Lib; | 499 | const is_lib = self.base.options.output_mode == .Lib; |
| 495 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; | 500 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; |
| 496 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe; | 501 | 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 { | ... | @@ -1111,13 +1116,13 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 1111 | self.cold_start = false; | 1116 | self.cold_start = false; |
| 1112 | } | 1117 | } |
| 1113 | 1118 | ||
| 1114 | pub fn flushObject(self: *MachO, comp: *Compilation) !void { | 1119 | pub fn flushObject(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 1115 | const tracy = trace(@src()); | 1120 | const tracy = trace(@src()); |
| 1116 | defer tracy.end(); | 1121 | defer tracy.end(); |
| 1117 | 1122 | ||
| 1118 | if (build_options.have_llvm) | 1123 | if (build_options.have_llvm) |
| 1119 | if (self.llvm_object) |llvm_object| | 1124 | if (self.llvm_object) |llvm_object| |
| 1120 | return llvm_object.flushModule(comp); | 1125 | return llvm_object.flushModule(comp, prog_node); |
| 1121 | 1126 | ||
| 1122 | return error.TODOImplementWritingObjFiles; | 1127 | return error.TODOImplementWritingObjFiles; |
| 1123 | } | 1128 | } |
src/link/NvPtx.zig+4-4| ... | @@ -97,11 +97,11 @@ pub fn freeDecl(self: *NvPtx, decl: *Module.Decl) void { | ... | @@ -97,11 +97,11 @@ pub fn freeDecl(self: *NvPtx, decl: *Module.Decl) void { |
| 97 | return self.llvm_object.freeDecl(decl); | 97 | return self.llvm_object.freeDecl(decl); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | pub fn flush(self: *NvPtx, comp: *Compilation) !void { | 100 | pub fn flush(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 101 | return self.flushModule(comp); | 101 | return self.flushModule(comp, prog_node); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | pub fn flushModule(self: *NvPtx, comp: *Compilation) !void { | 104 | pub fn flushModule(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 105 | if (!build_options.have_llvm) return; | 105 | if (!build_options.have_llvm) return; |
| 106 | if (build_options.skip_non_native) { | 106 | if (build_options.skip_non_native) { |
| 107 | @panic("Attempted to compile for architecture that was disabled by build configuration"); | 107 | @panic("Attempted to compile for architecture that was disabled by build configuration"); |
| ... | @@ -117,5 +117,5 @@ pub fn flushModule(self: *NvPtx, comp: *Compilation) !void { | ... | @@ -117,5 +117,5 @@ pub fn flushModule(self: *NvPtx, comp: *Compilation) !void { |
| 117 | }; | 117 | }; |
| 118 | hack_comp.bin_file.options.emit = null; | 118 | hack_comp.bin_file.options.emit = null; |
| 119 | } | 119 | } |
| 120 | return try self.llvm_object.flushModule(hack_comp); | 120 | return try self.llvm_object.flushModule(hack_comp, prog_node); |
| 121 | } | 121 | } |
src/link/Plan9.zig+7-3| ... | @@ -351,7 +351,7 @@ fn updateFinish(self: *Plan9, decl: *Module.Decl) !void { | ... | @@ -351,7 +351,7 @@ fn updateFinish(self: *Plan9, decl: *Module.Decl) !void { |
| 351 | } | 351 | } |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | pub fn flush(self: *Plan9, comp: *Compilation) !void { | 354 | pub fn flush(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 355 | assert(!self.base.options.use_lld); | 355 | assert(!self.base.options.use_lld); |
| 356 | 356 | ||
| 357 | switch (self.base.options.effectiveOutputMode()) { | 357 | switch (self.base.options.effectiveOutputMode()) { |
| ... | @@ -360,7 +360,7 @@ pub fn flush(self: *Plan9, comp: *Compilation) !void { | ... | @@ -360,7 +360,7 @@ pub fn flush(self: *Plan9, comp: *Compilation) !void { |
| 360 | .Obj => return error.TODOImplementPlan9Objs, | 360 | .Obj => return error.TODOImplementPlan9Objs, |
| 361 | .Lib => return error.TODOImplementWritingLibFiles, | 361 | .Lib => return error.TODOImplementWritingLibFiles, |
| 362 | } | 362 | } |
| 363 | return self.flushModule(comp); | 363 | return self.flushModule(comp, prog_node); |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void { | 366 | pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void { |
| ... | @@ -387,7 +387,7 @@ fn declCount(self: *Plan9) usize { | ... | @@ -387,7 +387,7 @@ fn declCount(self: *Plan9) usize { |
| 387 | return self.data_decl_table.count() + fn_decl_count; | 387 | return self.data_decl_table.count() + fn_decl_count; |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | pub fn flushModule(self: *Plan9, comp: *Compilation) !void { | 390 | pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 391 | if (build_options.skip_non_native and builtin.object_format != .plan9) { | 391 | if (build_options.skip_non_native and builtin.object_format != .plan9) { |
| 392 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 392 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 393 | } | 393 | } |
| ... | @@ -396,6 +396,10 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void { | ... | @@ -396,6 +396,10 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void { |
| 396 | const tracy = trace(@src()); | 396 | const tracy = trace(@src()); |
| 397 | defer tracy.end(); | 397 | defer tracy.end(); |
| 398 | 398 | ||
| 399 | var sub_prog_node = prog_node.start("Flush Module", 0); | ||
| 400 | sub_prog_node.activate(); | ||
| 401 | defer sub_prog_node.end(); | ||
| 402 | |||
| 399 | log.debug("flushModule", .{}); | 403 | log.debug("flushModule", .{}); |
| 400 | 404 | ||
| 401 | defer assert(self.hdr.entry != 0x0); | 405 | 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 { | ... | @@ -174,15 +174,15 @@ pub fn freeDecl(self: *SpirV, decl: *Module.Decl) void { |
| 174 | self.decl_table.swapRemoveAt(index); | 174 | self.decl_table.swapRemoveAt(index); |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | pub fn flush(self: *SpirV, comp: *Compilation) !void { | 177 | pub fn flush(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 178 | if (build_options.have_llvm and self.base.options.use_lld) { | 178 | if (build_options.have_llvm and self.base.options.use_lld) { |
| 179 | return error.LLD_LinkingIsTODO_ForSpirV; // TODO: LLD Doesn't support SpirV at all. | 179 | return error.LLD_LinkingIsTODO_ForSpirV; // TODO: LLD Doesn't support SpirV at all. |
| 180 | } else { | 180 | } else { |
| 181 | return self.flushModule(comp); | 181 | return self.flushModule(comp, prog_node); |
| 182 | } | 182 | } |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | pub fn flushModule(self: *SpirV, comp: *Compilation) !void { | 185 | pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 186 | if (build_options.skip_non_native) { | 186 | if (build_options.skip_non_native) { |
| 187 | @panic("Attempted to compile for architecture that was disabled by build configuration"); | 187 | @panic("Attempted to compile for architecture that was disabled by build configuration"); |
| 188 | } | 188 | } |
| ... | @@ -190,6 +190,10 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void { | ... | @@ -190,6 +190,10 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void { |
| 190 | const tracy = trace(@src()); | 190 | const tracy = trace(@src()); |
| 191 | defer tracy.end(); | 191 | defer tracy.end(); |
| 192 | 192 | ||
| 193 | var sub_prog_node = prog_node.start("Flush Module", 0); | ||
| 194 | sub_prog_node.activate(); | ||
| 195 | defer sub_prog_node.end(); | ||
| 196 | |||
| 193 | const module = self.base.options.module.?; | 197 | const module = self.base.options.module.?; |
| 194 | const target = comp.getTarget(); | 198 | const target = comp.getTarget(); |
| 195 | 199 |
src/link/Wasm.zig+17-8| ... | @@ -1477,32 +1477,36 @@ fn resetState(self: *Wasm) void { | ... | @@ -1477,32 +1477,36 @@ fn resetState(self: *Wasm) void { |
| 1477 | self.code_section_index = null; | 1477 | self.code_section_index = null; |
| 1478 | } | 1478 | } |
| 1479 | 1479 | ||
| 1480 | pub fn flush(self: *Wasm, comp: *Compilation) !void { | 1480 | pub fn flush(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 1481 | if (self.base.options.emit == null) { | 1481 | if (self.base.options.emit == null) { |
| 1482 | if (build_options.have_llvm) { | 1482 | if (build_options.have_llvm) { |
| 1483 | if (self.llvm_object) |llvm_object| { | 1483 | if (self.llvm_object) |llvm_object| { |
| 1484 | return try llvm_object.flushModule(comp); | 1484 | return try llvm_object.flushModule(comp, prog_node); |
| 1485 | } | 1485 | } |
| 1486 | } | 1486 | } |
| 1487 | return; | 1487 | return; |
| 1488 | } | 1488 | } |
| 1489 | if (build_options.have_llvm and self.base.options.use_lld) { | 1489 | if (build_options.have_llvm and self.base.options.use_lld) { |
| 1490 | return self.linkWithLLD(comp); | 1490 | return self.linkWithLLD(comp, prog_node); |
| 1491 | } else { | 1491 | } else { |
| 1492 | return self.flushModule(comp); | 1492 | return self.flushModule(comp, prog_node); |
| 1493 | } | 1493 | } |
| 1494 | } | 1494 | } |
| 1495 | 1495 | ||
| 1496 | pub fn flushModule(self: *Wasm, comp: *Compilation) !void { | 1496 | pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 1497 | const tracy = trace(@src()); | 1497 | const tracy = trace(@src()); |
| 1498 | defer tracy.end(); | 1498 | defer tracy.end(); |
| 1499 | 1499 | ||
| 1500 | if (build_options.have_llvm) { | 1500 | if (build_options.have_llvm) { |
| 1501 | if (self.llvm_object) |llvm_object| { | 1501 | if (self.llvm_object) |llvm_object| { |
| 1502 | return try llvm_object.flushModule(comp); | 1502 | return try llvm_object.flushModule(comp, prog_node); |
| 1503 | } | 1503 | } |
| 1504 | } | 1504 | } |
| 1505 | 1505 | ||
| 1506 | var sub_prog_node = prog_node.start("WASM Flush", 0); | ||
| 1507 | sub_prog_node.activate(); | ||
| 1508 | defer sub_prog_node.end(); | ||
| 1509 | |||
| 1506 | // ensure the error names table is populated when an error name is referenced | 1510 | // ensure the error names table is populated when an error name is referenced |
| 1507 | try self.populateErrorNameTable(); | 1511 | try self.populateErrorNameTable(); |
| 1508 | 1512 | ||
| ... | @@ -2028,7 +2032,7 @@ fn emitImport(self: *Wasm, writer: anytype, import: types.Import) !void { | ... | @@ -2028,7 +2032,7 @@ fn emitImport(self: *Wasm, writer: anytype, import: types.Import) !void { |
| 2028 | } | 2032 | } |
| 2029 | } | 2033 | } |
| 2030 | 2034 | ||
| 2031 | fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { | 2035 | fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 2032 | const tracy = trace(@src()); | 2036 | const tracy = trace(@src()); |
| 2033 | defer tracy.end(); | 2037 | defer tracy.end(); |
| 2034 | 2038 | ||
| ... | @@ -2060,7 +2064,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { | ... | @@ -2060,7 +2064,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 2060 | } | 2064 | } |
| 2061 | } | 2065 | } |
| 2062 | 2066 | ||
| 2063 | try self.flushModule(comp); | 2067 | try self.flushModule(comp, prog_node); |
| 2064 | 2068 | ||
| 2065 | if (fs.path.dirname(full_out_path)) |dirname| { | 2069 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 2066 | break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? }); | 2070 | break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? }); |
| ... | @@ -2069,6 +2073,11 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { | ... | @@ -2069,6 +2073,11 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 2069 | } | 2073 | } |
| 2070 | } else null; | 2074 | } else null; |
| 2071 | 2075 | ||
| 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 | |||
| 2072 | const is_obj = self.base.options.output_mode == .Obj; | 2081 | const is_obj = self.base.options.output_mode == .Obj; |
| 2073 | 2082 | ||
| 2074 | const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj) | 2083 | const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj) |