| 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 | 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 | 2095 | if (!use_stage1) { |
| 2090 | 2096 | if (comp.bin_file.options.module) |module| { |
| ... | ... | @@ -2158,9 +2164,9 @@ pub fn update(comp: *Compilation) !void { |
| 2158 | 2164 | .path = dir_path, |
| 2159 | 2165 | }; |
| 2160 | 2166 | |
| 2161 | try comp.flush(); | |
| 2167 | try comp.flush(main_progress_node); | |
| 2162 | 2168 | } else { |
| 2163 | try comp.flush(); | |
| 2169 | try comp.flush(main_progress_node); | |
| 2164 | 2170 | } |
| 2165 | 2171 | |
| 2166 | 2172 | // Failure here only means an unnecessary cache miss. |
| ... | ... | @@ -2171,7 +2177,7 @@ pub fn update(comp: *Compilation) !void { |
| 2171 | 2177 | assert(comp.bin_file.lock == null); |
| 2172 | 2178 | comp.bin_file.lock = man.toOwnedLock(); |
| 2173 | 2179 | } else { |
| 2174 | try comp.flush(); | |
| 2180 | try comp.flush(main_progress_node); | |
| 2175 | 2181 | } |
| 2176 | 2182 | |
| 2177 | 2183 | // Unload all source files to save memory. |
| ... | ... | @@ -2188,8 +2194,8 @@ pub fn update(comp: *Compilation) !void { |
| 2188 | 2194 | } |
| 2189 | 2195 | } |
| 2190 | 2196 | |
| 2191 | fn flush(comp: *Compilation) !void { | |
| 2192 | try comp.bin_file.flush(comp); // This is needed before reading the error flags. | |
| 2197 | fn 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. | |
| 2193 | 2199 | comp.link_error_flags = comp.bin_file.errorFlags(); |
| 2194 | 2200 | |
| 2195 | 2201 | const use_stage1 = build_options.omit_stage2 or |
| ... | ... | @@ -2590,14 +2596,10 @@ pub fn getCompileLogOutput(self: *Compilation) []const u8 { |
| 2590 | 2596 | return module.compile_log_text.items; |
| 2591 | 2597 | } |
| 2592 | 2598 | |
| 2593 | pub 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 | ||
| 2599 | pub fn performAllTheWork( | |
| 2600 | comp: *Compilation, | |
| 2601 | main_progress_node: *std.Progress.Node, | |
| 2602 | ) error{ TimerUnsupported, OutOfMemory }!void { | |
| 2601 | 2603 | // Here we queue up all the AstGen tasks first, followed by C object compilation. |
| 2602 | 2604 | // We wait until the AstGen tasks are all completed before proceeding to the |
| 2603 | 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 | 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 | 478 | try self.genErrorNameTable(comp); |
| 474 | 479 | try self.genCmpLtErrorsLenFunction(comp); |
| 475 | 480 |
src/link.zig+22-22| ... | ... | @@ -573,7 +573,7 @@ pub const File = struct { |
| 573 | 573 | |
| 574 | 574 | /// Commit pending changes and write headers. Takes into account final output mode |
| 575 | 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 | 577 | if (comp.clang_preprocessor_mode == .yes) { |
| 578 | 578 | const emit = base.options.emit orelse return; // -fno-emit-bin |
| 579 | 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 | 591 | |
| 592 | 592 | const use_lld = build_options.have_llvm and base.options.use_lld; |
| 593 | 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 | 596 | 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), | |
| 605 | 605 | } |
| 606 | 606 | } |
| 607 | 607 | |
| 608 | 608 | /// Commit pending changes and write headers. Works based on `effectiveOutputMode` |
| 609 | 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 | 611 | 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), | |
| 620 | 620 | } |
| 621 | 621 | } |
| 622 | 622 | |
| ... | ... | @@ -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 | 758 | const tracy = trace(@src()); |
| 759 | 759 | defer tracy.end(); |
| 760 | 760 | |
| ... | ... | @@ -787,9 +787,9 @@ pub const File = struct { |
| 787 | 787 | } |
| 788 | 788 | } |
| 789 | 789 | if (base.options.object_format == .macho) { |
| 790 | try base.cast(MachO).?.flushObject(comp); | |
| 790 | try base.cast(MachO).?.flushObject(comp, prog_node); | |
| 791 | 791 | } else { |
| 792 | try base.flushModule(comp); | |
| 792 | try base.flushModule(comp, prog_node); | |
| 793 | 793 | } |
| 794 | 794 | break :blk try fs.path.join(arena, &.{ |
| 795 | 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 | 235 | _ = decl; |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | pub fn flush(self: *C, comp: *Compilation) !void { | |
| 239 | return self.flushModule(comp); | |
| 238 | pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void { | |
| 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 | 243 | const tracy = trace(@src()); |
| 244 | 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 | 250 | const gpa = comp.gpa; |
| 247 | 251 | const module = self.base.options.module.?; |
| 248 | 252 |
src/link/Coff.zig+17-8| ... | ... | @@ -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 | 833 | if (self.base.options.emit == null) { |
| 834 | 834 | if (build_options.have_llvm) { |
| 835 | 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 | 839 | return; |
| 840 | 840 | } |
| 841 | 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 | 843 | } else { |
| 844 | 844 | switch (self.base.options.effectiveOutputMode()) { |
| 845 | 845 | .Exe, .Obj => {}, |
| 846 | 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 | 853 | const tracy = trace(@src()); |
| 854 | 854 | defer tracy.end(); |
| 855 | 855 | |
| 856 | 856 | if (build_options.have_llvm) { |
| 857 | 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 | 866 | if (self.text_section_size_dirty) { |
| 863 | 867 | // Write the new raw size in the .text header |
| 864 | 868 | var buf: [4]u8 = undefined; |
| ... | ... | @@ -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 | 900 | const tracy = trace(@src()); |
| 897 | 901 | defer tracy.end(); |
| 898 | 902 | |
| ... | ... | @@ -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 | 933 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 930 | 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 | 937 | } |
| 934 | 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 | 945 | const is_lib = self.base.options.output_mode == .Lib; |
| 937 | 946 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; |
| 938 | 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 | 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 | 933 | if (self.base.options.emit == null) { |
| 934 | 934 | if (build_options.have_llvm) { |
| 935 | 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 | 939 | return; |
| 940 | 940 | } |
| 941 | 941 | const use_lld = build_options.have_llvm and self.base.options.use_lld; |
| 942 | 942 | if (use_lld) { |
| 943 | return self.linkWithLLD(comp); | |
| 943 | return self.linkWithLLD(comp, prog_node); | |
| 944 | 944 | } |
| 945 | 945 | switch (self.base.options.output_mode) { |
| 946 | .Exe, .Obj => return self.flushModule(comp), | |
| 946 | .Exe, .Obj => return self.flushModule(comp, prog_node), | |
| 947 | 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 | 952 | const tracy = trace(@src()); |
| 953 | 953 | defer tracy.end(); |
| 954 | 954 | |
| 955 | 955 | if (build_options.have_llvm) { |
| 956 | 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 | 965 | // TODO This linker code currently assumes there is only 1 compilation unit and it |
| 962 | 966 | // corresponds to the Zig source code. |
| 963 | 967 | const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| ... | ... | @@ -1204,7 +1208,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 1204 | 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 | 1212 | const tracy = trace(@src()); |
| 1209 | 1213 | defer tracy.end(); |
| 1210 | 1214 | |
| ... | ... | @@ -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 | 1245 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 1242 | 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 | 1249 | } |
| 1246 | 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 | 1257 | const is_obj = self.base.options.output_mode == .Obj; |
| 1249 | 1258 | const is_lib = self.base.options.output_mode == .Lib; |
| 1250 | 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 | 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 | 423 | if (self.base.options.emit == null) { |
| 424 | 424 | if (build_options.have_llvm) { |
| 425 | 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 | 429 | return; |
| 430 | 430 | } |
| 431 | ||
| 431 | 432 | if (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Static) { |
| 432 | 433 | if (build_options.have_llvm) { |
| 433 | return self.base.linkAsArchive(comp); | |
| 434 | return self.base.linkAsArchive(comp, prog_node); | |
| 434 | 435 | } else { |
| 435 | 436 | log.err("TODO: non-LLVM archiver for MachO object files", .{}); |
| 436 | 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 | 444 | const tracy = trace(@src()); |
| 444 | 445 | defer tracy.end(); |
| 445 | 446 | |
| 446 | 447 | const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1; |
| 447 | 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 | 451 | var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator); |
| 451 | 452 | defer arena_allocator.deinit(); |
| ... | ... | @@ -482,7 +483,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 482 | 483 | |
| 483 | 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 | 488 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 488 | 489 | break :blk try fs.path.join(arena, &.{ dirname, obj_basename }); |
| ... | ... | @@ -491,6 +492,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 491 | 492 | } |
| 492 | 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 | 499 | const is_lib = self.base.options.output_mode == .Lib; |
| 495 | 500 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; |
| 496 | 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 | 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 | 1120 | const tracy = trace(@src()); |
| 1116 | 1121 | defer tracy.end(); |
| 1117 | 1122 | |
| 1118 | 1123 | if (build_options.have_llvm) |
| 1119 | 1124 | if (self.llvm_object) |llvm_object| |
| 1120 | return llvm_object.flushModule(comp); | |
| 1125 | return llvm_object.flushModule(comp, prog_node); | |
| 1121 | 1126 | |
| 1122 | 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 | 97 | return self.llvm_object.freeDecl(decl); |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | pub fn flush(self: *NvPtx, comp: *Compilation) !void { | |
| 101 | return self.flushModule(comp); | |
| 100 | pub fn flush(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) !void { | |
| 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 | 105 | if (!build_options.have_llvm) return; |
| 106 | 106 | if (build_options.skip_non_native) { |
| 107 | 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 | 117 | }; |
| 118 | 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 | 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 | 355 | assert(!self.base.options.use_lld); |
| 356 | 356 | |
| 357 | 357 | switch (self.base.options.effectiveOutputMode()) { |
| ... | ... | @@ -360,7 +360,7 @@ pub fn flush(self: *Plan9, comp: *Compilation) !void { |
| 360 | 360 | .Obj => return error.TODOImplementPlan9Objs, |
| 361 | 361 | .Lib => return error.TODOImplementWritingLibFiles, |
| 362 | 362 | } |
| 363 | return self.flushModule(comp); | |
| 363 | return self.flushModule(comp, prog_node); | |
| 364 | 364 | } |
| 365 | 365 | |
| 366 | 366 | pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void { |
| ... | ... | @@ -387,7 +387,7 @@ fn declCount(self: *Plan9) usize { |
| 387 | 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 | 391 | if (build_options.skip_non_native and builtin.object_format != .plan9) { |
| 392 | 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 | 396 | const tracy = trace(@src()); |
| 397 | 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 | 403 | log.debug("flushModule", .{}); |
| 400 | 404 | |
| 401 | 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 | 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 | 178 | if (build_options.have_llvm and self.base.options.use_lld) { |
| 179 | 179 | return error.LLD_LinkingIsTODO_ForSpirV; // TODO: LLD Doesn't support SpirV at all. |
| 180 | 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 | 186 | if (build_options.skip_non_native) { |
| 187 | 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 | 190 | const tracy = trace(@src()); |
| 191 | 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 | 197 | const module = self.base.options.module.?; |
| 194 | 198 | const target = comp.getTarget(); |
| 195 | 199 |
src/link/Wasm.zig+17-8| ... | ... | @@ -1477,32 +1477,36 @@ fn resetState(self: *Wasm) void { |
| 1477 | 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 | 1481 | if (self.base.options.emit == null) { |
| 1482 | 1482 | if (build_options.have_llvm) { |
| 1483 | 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 | 1487 | return; |
| 1488 | 1488 | } |
| 1489 | 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 | 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 | 1497 | const tracy = trace(@src()); |
| 1498 | 1498 | defer tracy.end(); |
| 1499 | 1499 | |
| 1500 | 1500 | if (build_options.have_llvm) { |
| 1501 | 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 | 1510 | // ensure the error names table is populated when an error name is referenced |
| 1507 | 1511 | try self.populateErrorNameTable(); |
| 1508 | 1512 | |
| ... | ... | @@ -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 | 2036 | const tracy = trace(@src()); |
| 2033 | 2037 | defer tracy.end(); |
| 2034 | 2038 | |
| ... | ... | @@ -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 | 2069 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 2066 | 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 | 2073 | } |
| 2070 | 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 | 2081 | const is_obj = self.base.options.output_mode == .Obj; |
| 2073 | 2082 | |
| 2074 | 2083 | const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj) |