authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-31 19:07:05-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-01 00:17:02-07:00
log87179d91a76470eb5e09d4e070063a2021c7f176
tree681783fb3f0ce3123f0e4b7cc07592e3256d19d8
parentb45c6c757cb4a16f5021c8bf057d14183036f14c

stage2: hook up Sema to the progress bar


2 files changed, 49 insertions(+), 53 deletions(-)

src/Compilation.zig+44-53
...@@ -232,9 +232,6 @@ const Job = union(enum) {...@@ -232,9 +232,6 @@ const Job = union(enum) {
232 /// one of WASI libc static objects232 /// one of WASI libc static objects
233 wasi_libc_crt_file: wasi_libc.CRTFile,233 wasi_libc_crt_file: wasi_libc.CRTFile,
234234
235 /// Use stage1 C++ code to compile zig code into an object file.
236 stage1_module: void,
237
238 /// The value is the index into `link.File.Options.system_libs`.235 /// The value is the index into `link.File.Options.system_libs`.
239 windows_import_lib: usize,236 windows_import_lib: usize,
240};237};
...@@ -1831,10 +1828,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1831,10 +1828,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1831 }1828 }
1832 }1829 }
18331830
1834 if (comp.bin_file.options.use_stage1 and comp.bin_file.options.module != null) {
1835 try comp.work_queue.writeItem(.{ .stage1_module = {} });
1836 }
1837
1838 return comp;1831 return comp;
1839}1832}
18401833
...@@ -2597,13 +2590,13 @@ pub fn getCompileLogOutput(self: *Compilation) []const u8 {...@@ -2597,13 +2590,13 @@ pub fn getCompileLogOutput(self: *Compilation) []const u8 {
2597 return module.compile_log_text.items;2590 return module.compile_log_text.items;
2598}2591}
25992592
2600pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemory }!void {2593pub fn performAllTheWork(comp: *Compilation) error{ TimerUnsupported, OutOfMemory }!void {
2601 // If the terminal is dumb, we dont want to show the user all the2594 // If the terminal is dumb, we dont want to show the user all the
2602 // output.2595 // output.
2603 var progress: std.Progress = .{ .dont_print_on_dumb = true };2596 var progress: std.Progress = .{ .dont_print_on_dumb = true };
2604 var main_progress_node = progress.start("", 0);2597 var main_progress_node = progress.start("", 0);
2605 defer main_progress_node.end();2598 defer main_progress_node.end();
2606 if (self.color == .off) progress.terminal = null;2599 if (comp.color == .off) progress.terminal = null;
26072600
2608 // Here we queue up all the AstGen tasks first, followed by C object compilation.2601 // Here we queue up all the AstGen tasks first, followed by C object compilation.
2609 // We wait until the AstGen tasks are all completed before proceeding to the2602 // We wait until the AstGen tasks are all completed before proceeding to the
...@@ -2613,93 +2606,105 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor...@@ -2613,93 +2606,105 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
2613 var zir_prog_node = main_progress_node.start("AST Lowering", 0);2606 var zir_prog_node = main_progress_node.start("AST Lowering", 0);
2614 defer zir_prog_node.end();2607 defer zir_prog_node.end();
26152608
2616 var c_obj_prog_node = main_progress_node.start("Compile C Objects", self.c_source_files.len);2609 var c_obj_prog_node = main_progress_node.start("Compile C Objects", comp.c_source_files.len);
2617 defer c_obj_prog_node.end();2610 defer c_obj_prog_node.end();
26182611
2619 var embed_file_prog_node = main_progress_node.start("Detect @embedFile updates", self.embed_file_work_queue.count);2612 var embed_file_prog_node = main_progress_node.start("Detect @embedFile updates", comp.embed_file_work_queue.count);
2620 defer embed_file_prog_node.end();2613 defer embed_file_prog_node.end();
26212614
2622 self.work_queue_wait_group.reset();2615 comp.work_queue_wait_group.reset();
2623 defer self.work_queue_wait_group.wait();2616 defer comp.work_queue_wait_group.wait();
26242617
2625 {2618 {
2626 const astgen_frame = tracy.namedFrame("astgen");2619 const astgen_frame = tracy.namedFrame("astgen");
2627 defer astgen_frame.end();2620 defer astgen_frame.end();
26282621
2629 self.astgen_wait_group.reset();2622 comp.astgen_wait_group.reset();
2630 defer self.astgen_wait_group.wait();2623 defer comp.astgen_wait_group.wait();
26312624
2632 // builtin.zig is handled specially for two reasons:2625 // builtin.zig is handled specially for two reasons:
2633 // 1. to avoid race condition of zig processes truncating each other's builtin.zig files2626 // 1. to avoid race condition of zig processes truncating each other's builtin.zig files
2634 // 2. optimization; in the hot path it only incurs a stat() syscall, which happens2627 // 2. optimization; in the hot path it only incurs a stat() syscall, which happens
2635 // in the `astgen_wait_group`.2628 // in the `astgen_wait_group`.
2636 if (self.bin_file.options.module) |mod| {2629 if (comp.bin_file.options.module) |mod| {
2637 if (mod.job_queued_update_builtin_zig) {2630 if (mod.job_queued_update_builtin_zig) {
2638 mod.job_queued_update_builtin_zig = false;2631 mod.job_queued_update_builtin_zig = false;
26392632
2640 self.astgen_wait_group.start();2633 comp.astgen_wait_group.start();
2641 try self.thread_pool.spawn(workerUpdateBuiltinZigFile, .{2634 try comp.thread_pool.spawn(workerUpdateBuiltinZigFile, .{
2642 self, mod, &self.astgen_wait_group,2635 comp, mod, &comp.astgen_wait_group,
2643 });2636 });
2644 }2637 }
2645 }2638 }
26462639
2647 while (self.astgen_work_queue.readItem()) |file| {2640 while (comp.astgen_work_queue.readItem()) |file| {
2648 self.astgen_wait_group.start();2641 comp.astgen_wait_group.start();
2649 try self.thread_pool.spawn(workerAstGenFile, .{2642 try comp.thread_pool.spawn(workerAstGenFile, .{
2650 self, file, &zir_prog_node, &self.astgen_wait_group, .root,2643 comp, file, &zir_prog_node, &comp.astgen_wait_group, .root,
2651 });2644 });
2652 }2645 }
26532646
2654 while (self.embed_file_work_queue.readItem()) |embed_file| {2647 while (comp.embed_file_work_queue.readItem()) |embed_file| {
2655 self.astgen_wait_group.start();2648 comp.astgen_wait_group.start();
2656 try self.thread_pool.spawn(workerCheckEmbedFile, .{2649 try comp.thread_pool.spawn(workerCheckEmbedFile, .{
2657 self, embed_file, &embed_file_prog_node, &self.astgen_wait_group,2650 comp, embed_file, &embed_file_prog_node, &comp.astgen_wait_group,
2658 });2651 });
2659 }2652 }
26602653
2661 while (self.c_object_work_queue.readItem()) |c_object| {2654 while (comp.c_object_work_queue.readItem()) |c_object| {
2662 self.work_queue_wait_group.start();2655 comp.work_queue_wait_group.start();
2663 try self.thread_pool.spawn(workerUpdateCObject, .{2656 try comp.thread_pool.spawn(workerUpdateCObject, .{
2664 self, c_object, &c_obj_prog_node, &self.work_queue_wait_group,2657 comp, c_object, &c_obj_prog_node, &comp.work_queue_wait_group,
2665 });2658 });
2666 }2659 }
2667 }2660 }
26682661
2669 const use_stage1 = build_options.is_stage1 and self.bin_file.options.use_stage1;2662 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
2670 if (!use_stage1) {2663 if (!use_stage1) {
2671 const outdated_and_deleted_decls_frame = tracy.namedFrame("outdated_and_deleted_decls");2664 const outdated_and_deleted_decls_frame = tracy.namedFrame("outdated_and_deleted_decls");
2672 defer outdated_and_deleted_decls_frame.end();2665 defer outdated_and_deleted_decls_frame.end();
26732666
2674 // Iterate over all the files and look for outdated and deleted declarations.2667 // Iterate over all the files and look for outdated and deleted declarations.
2675 if (self.bin_file.options.module) |mod| {2668 if (comp.bin_file.options.module) |mod| {
2676 try mod.processOutdatedAndDeletedDecls();2669 try mod.processOutdatedAndDeletedDecls();
2677 }2670 }
2678 } else if (self.bin_file.options.module) |mod| {2671 } else if (comp.bin_file.options.module) |mod| {
2679 // If there are any AstGen compile errors, report them now to avoid2672 // If there are any AstGen compile errors, report them now to avoid
2680 // hitting stage1 bugs.2673 // hitting stage1 bugs.
2681 if (mod.failed_files.count() != 0) {2674 if (mod.failed_files.count() != 0) {
2682 return;2675 return;
2683 }2676 }
2677 comp.updateStage1Module(main_progress_node) catch |err| {
2678 fatal("unable to build stage1 zig object: {s}", .{@errorName(err)});
2679 };
2680 }
2681
2682 if (comp.bin_file.options.module) |mod| {
2683 mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
2684 mod.sema_prog_node.activate();
2684 }2685 }
2686 defer if (comp.bin_file.options.module) |mod| {
2687 mod.sema_prog_node.end();
2688 mod.sema_prog_node = undefined;
2689 };
26852690
2686 // In this main loop we give priority to non-anonymous Decls in the work queue, so2691 // In this main loop we give priority to non-anonymous Decls in the work queue, so
2687 // that they can establish references to anonymous Decls, setting alive=true in the2692 // that they can establish references to anonymous Decls, setting alive=true in the
2688 // backend, preventing anonymous Decls from being prematurely destroyed.2693 // backend, preventing anonymous Decls from being prematurely destroyed.
2689 while (true) {2694 while (true) {
2690 if (self.work_queue.readItem()) |work_item| {2695 if (comp.work_queue.readItem()) |work_item| {
2691 try processOneJob(self, work_item, main_progress_node);2696 try processOneJob(comp, work_item);
2692 continue;2697 continue;
2693 }2698 }
2694 if (self.anon_work_queue.readItem()) |work_item| {2699 if (comp.anon_work_queue.readItem()) |work_item| {
2695 try processOneJob(self, work_item, main_progress_node);2700 try processOneJob(comp, work_item);
2696 continue;2701 continue;
2697 }2702 }
2698 break;2703 break;
2699 }2704 }
2700}2705}
27012706
2702fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress.Node) !void {2707fn processOneJob(comp: *Compilation, job: Job) !void {
2703 switch (job) {2708 switch (job) {
2704 .codegen_decl => |decl| switch (decl.analysis) {2709 .codegen_decl => |decl| switch (decl.analysis) {
2705 .unreferenced => unreachable,2710 .unreferenced => unreachable,
...@@ -2807,9 +2812,6 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2807,9 +2812,6 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2807 if (build_options.omit_stage2)2812 if (build_options.omit_stage2)
2808 @panic("sadly stage2 is omitted from this build to save memory on the CI server");2813 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
28092814
2810 const named_frame = tracy.namedFrame("analyze_decl");
2811 defer named_frame.end();
2812
2813 const module = comp.bin_file.options.module.?;2815 const module = comp.bin_file.options.module.?;
2814 module.ensureDeclAnalyzed(decl) catch |err| switch (err) {2816 module.ensureDeclAnalyzed(decl) catch |err| switch (err) {
2815 error.OutOfMemory => return error.OutOfMemory,2817 error.OutOfMemory => return error.OutOfMemory,
...@@ -3074,17 +3076,6 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -3074,17 +3076,6 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
3074 ),3076 ),
3075 };3077 };
3076 },3078 },
3077 .stage1_module => {
3078 const named_frame = tracy.namedFrame("stage1_module");
3079 defer named_frame.end();
3080
3081 if (!build_options.is_stage1)
3082 unreachable;
3083
3084 comp.updateStage1Module(main_progress_node) catch |err| {
3085 fatal("unable to build stage1 zig object: {s}", .{@errorName(err)});
3086 };
3087 },
3088 }3079 }
3089}3080}
30903081
src/Module.zig+5
...@@ -42,6 +42,7 @@ root_pkg: *Package,...@@ -42,6 +42,7 @@ root_pkg: *Package,
42/// Normally, `main_pkg` and `root_pkg` are the same. The exception is `zig test`, in which42/// Normally, `main_pkg` and `root_pkg` are the same. The exception is `zig test`, in which
43/// `root_pkg` is the test runner, and `main_pkg` is the user's source file which has the tests.43/// `root_pkg` is the test runner, and `main_pkg` is the user's source file which has the tests.
44main_pkg: *Package,44main_pkg: *Package,
45sema_prog_node: std.Progress.Node = undefined,
4546
46/// Used by AstGen worker to load and store ZIR cache.47/// Used by AstGen worker to load and store ZIR cache.
47global_zir_cache: Compilation.Directory,48global_zir_cache: Compilation.Directory,
...@@ -3517,6 +3518,10 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {...@@ -3517,6 +3518,10 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {
3517 .unreferenced => false,3518 .unreferenced => false,
3518 };3519 };
35193520
3521 var decl_prog_node = mod.sema_prog_node.start(mem.sliceTo(decl.name, 0), 0);
3522 decl_prog_node.activate();
3523 defer decl_prog_node.end();
3524
3520 const type_changed = mod.semaDecl(decl) catch |err| switch (err) {3525 const type_changed = mod.semaDecl(decl) catch |err| switch (err) {
3521 error.AnalysisFail => {3526 error.AnalysisFail => {
3522 if (decl.analysis == .in_progress) {3527 if (decl.analysis == .in_progress) {