authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-31 17:55:29-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-10-31 17:55:29-04:00
log8346e011c9ecbd7d462f0948d2e9dfc7e4067482
tree65b594fbf4e9a1df9e9d3c3006897ff7fd7b92ea
parent91d93b6395bf4a5718cffe18d4a9351b2ff06492
parent2d1efba8c51327a37ac5fe13dda252b362dc467f
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10068 from leecannon/tracy_improvements

stage2: tracy integration improvements

4 files changed, 405 insertions(+), 42 deletions(-)

build.zig+4
...@@ -110,6 +110,8 @@ pub fn build(b: *Builder) !void {...@@ -110,6 +110,8 @@ pub fn build(b: *Builder) !void {
110 return;110 return;
111111
112 const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");112 const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");
113 const tracy_callstack = b.option(bool, "tracy-callstack", "Include callstack information with Tracy data. Does nothing if -Dtracy is not provided") orelse false;
114 const tracy_allocation = b.option(bool, "tracy-allocation", "Include allocation information with Tracy data. Does nothing if -Dtracy is not provided") orelse false;
113 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;115 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
114 const strip = b.option(bool, "strip", "Omit debug information") orelse false;116 const strip = b.option(bool, "strip", "Omit debug information") orelse false;
115117
...@@ -264,6 +266,8 @@ pub fn build(b: *Builder) !void {...@@ -264,6 +266,8 @@ pub fn build(b: *Builder) !void {
264 exe_options.addOption(bool, "enable_logging", enable_logging);266 exe_options.addOption(bool, "enable_logging", enable_logging);
265 exe_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots);267 exe_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots);
266 exe_options.addOption(bool, "enable_tracy", tracy != null);268 exe_options.addOption(bool, "enable_tracy", tracy != null);
269 exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);
270 exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
267 exe_options.addOption(bool, "is_stage1", is_stage1);271 exe_options.addOption(bool, "is_stage1", is_stage1);
268 exe_options.addOption(bool, "omit_stage2", omit_stage2);272 exe_options.addOption(bool, "omit_stage2", omit_stage2);
269 if (tracy) |tracy_path| {273 if (tracy) |tracy_path| {
src/Compilation.zig+104-17
...@@ -13,7 +13,8 @@ const Type = @import("type.zig").Type;...@@ -13,7 +13,8 @@ const Type = @import("type.zig").Type;
13const target_util = @import("target.zig");13const target_util = @import("target.zig");
14const Package = @import("Package.zig");14const Package = @import("Package.zig");
15const link = @import("link.zig");15const link = @import("link.zig");
16const trace = @import("tracy.zig").trace;16const tracy = @import("tracy.zig");
17const trace = tracy.trace;
17const Liveness = @import("Liveness.zig");18const Liveness = @import("Liveness.zig");
18const build_options = @import("build_options");19const build_options = @import("build_options");
19const LibCInstallation = @import("libc_installation.zig").LibCInstallation;20const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
...@@ -1726,8 +1727,8 @@ pub fn getTarget(self: Compilation) Target {...@@ -1726,8 +1727,8 @@ pub fn getTarget(self: Compilation) Target {
17261727
1727/// Detect changes to source files, perform semantic analysis, and update the output files.1728/// Detect changes to source files, perform semantic analysis, and update the output files.
1728pub fn update(self: *Compilation) !void {1729pub fn update(self: *Compilation) !void {
1729 const tracy = trace(@src());1730 const t = trace(@src());
1730 defer tracy.end();1731 defer t.end();
17311732
1732 self.clearMiscFailures();1733 self.clearMiscFailures();
17331734
...@@ -2111,6 +2112,9 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor...@@ -2111,6 +2112,9 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
2111 defer self.work_queue_wait_group.wait();2112 defer self.work_queue_wait_group.wait();
21122113
2113 {2114 {
2115 const astgen_frame = tracy.namedFrame("astgen");
2116 defer astgen_frame.end();
2117
2114 self.astgen_wait_group.reset();2118 self.astgen_wait_group.reset();
2115 defer self.astgen_wait_group.wait();2119 defer self.astgen_wait_group.wait();
21162120
...@@ -2138,6 +2142,9 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor...@@ -2138,6 +2142,9 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
21382142
2139 const use_stage1 = build_options.is_stage1 and self.bin_file.options.use_stage1;2143 const use_stage1 = build_options.is_stage1 and self.bin_file.options.use_stage1;
2140 if (!use_stage1) {2144 if (!use_stage1) {
2145 const outdated_and_deleted_decls_frame = tracy.namedFrame("outdated_and_deleted_decls");
2146 defer outdated_and_deleted_decls_frame.end();
2147
2141 // Iterate over all the files and look for outdated and deleted declarations.2148 // Iterate over all the files and look for outdated and deleted declarations.
2142 if (self.bin_file.options.module) |mod| {2149 if (self.bin_file.options.module) |mod| {
2143 try mod.processOutdatedAndDeletedDecls();2150 try mod.processOutdatedAndDeletedDecls();
...@@ -2181,6 +2188,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2181,6 +2188,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2181 => return,2188 => return,
21822189
2183 .complete, .codegen_failure_retryable => {2190 .complete, .codegen_failure_retryable => {
2191 const named_frame = tracy.namedFrame("codegen_decl");
2192 defer named_frame.end();
2193
2184 if (build_options.omit_stage2)2194 if (build_options.omit_stage2)
2185 @panic("sadly stage2 is omitted from this build to save memory on the CI server");2195 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
21862196
...@@ -2230,6 +2240,10 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2230,6 +2240,10 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2230 defer tmp_arena.deinit();2240 defer tmp_arena.deinit();
2231 const sema_arena = &tmp_arena.allocator;2241 const sema_arena = &tmp_arena.allocator;
22322242
2243 const sema_frame = tracy.namedFrame("sema");
2244 var sema_frame_ended = false;
2245 errdefer if (!sema_frame_ended) sema_frame.end();
2246
2233 var air = module.analyzeFnBody(decl, func, sema_arena) catch |err| switch (err) {2247 var air = module.analyzeFnBody(decl, func, sema_arena) catch |err| switch (err) {
2234 error.AnalysisFail => {2248 error.AnalysisFail => {
2235 assert(func.state != .in_progress);2249 assert(func.state != .in_progress);
...@@ -2239,16 +2253,29 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2239,16 +2253,29 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2239 };2253 };
2240 defer air.deinit(gpa);2254 defer air.deinit(gpa);
22412255
2256 sema_frame.end();
2257 sema_frame_ended = true;
2258
2259 const liveness_frame = tracy.namedFrame("liveness");
2260 var liveness_frame_ended = false;
2261 errdefer if (!liveness_frame_ended) liveness_frame.end();
2262
2242 log.debug("analyze liveness of {s}", .{decl.name});2263 log.debug("analyze liveness of {s}", .{decl.name});
2243 var liveness = try Liveness.analyze(gpa, air, decl.getFileScope().zir);2264 var liveness = try Liveness.analyze(gpa, air, decl.getFileScope().zir);
2244 defer liveness.deinit(gpa);2265 defer liveness.deinit(gpa);
22452266
2267 liveness_frame.end();
2268 liveness_frame_ended = true;
2269
2246 if (builtin.mode == .Debug and comp.verbose_air) {2270 if (builtin.mode == .Debug and comp.verbose_air) {
2247 std.debug.print("# Begin Function AIR: {s}:\n", .{decl.name});2271 std.debug.print("# Begin Function AIR: {s}:\n", .{decl.name});
2248 @import("print_air.zig").dump(gpa, air, decl.getFileScope().zir, liveness);2272 @import("print_air.zig").dump(gpa, air, decl.getFileScope().zir, liveness);
2249 std.debug.print("# End Function AIR: {s}\n\n", .{decl.name});2273 std.debug.print("# End Function AIR: {s}\n\n", .{decl.name});
2250 }2274 }
22512275
2276 const named_frame = tracy.namedFrame("codegen");
2277 defer named_frame.end();
2278
2252 comp.bin_file.updateFunc(module, func, air, liveness) catch |err| switch (err) {2279 comp.bin_file.updateFunc(module, func, air, liveness) catch |err| switch (err) {
2253 error.OutOfMemory => return error.OutOfMemory,2280 error.OutOfMemory => return error.OutOfMemory,
2254 error.AnalysisFail => {2281 error.AnalysisFail => {
...@@ -2284,6 +2311,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2284,6 +2311,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2284 // emit-h only requires semantic analysis of the Decl to be complete,2311 // emit-h only requires semantic analysis of the Decl to be complete,
2285 // it does not depend on machine code generation to succeed.2312 // it does not depend on machine code generation to succeed.
2286 .codegen_failure, .codegen_failure_retryable, .complete => {2313 .codegen_failure, .codegen_failure_retryable, .complete => {
2314 const named_frame = tracy.namedFrame("emit_h_decl");
2315 defer named_frame.end();
2316
2287 if (build_options.omit_stage2)2317 if (build_options.omit_stage2)
2288 @panic("sadly stage2 is omitted from this build to save memory on the CI server");2318 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
2289 const gpa = comp.gpa;2319 const gpa = comp.gpa;
...@@ -2321,6 +2351,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2321,6 +2351,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2321 },2351 },
2322 },2352 },
2323 .analyze_decl => |decl| {2353 .analyze_decl => |decl| {
2354 const named_frame = tracy.namedFrame("analyze_decl");
2355 defer named_frame.end();
2356
2324 if (build_options.omit_stage2)2357 if (build_options.omit_stage2)
2325 @panic("sadly stage2 is omitted from this build to save memory on the CI server");2358 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
2326 const module = comp.bin_file.options.module.?;2359 const module = comp.bin_file.options.module.?;
...@@ -2330,6 +2363,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2330,6 +2363,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2330 };2363 };
2331 },2364 },
2332 .update_embed_file => |embed_file| {2365 .update_embed_file => |embed_file| {
2366 const named_frame = tracy.namedFrame("update_embed_file");
2367 defer named_frame.end();
2368
2333 if (build_options.omit_stage2)2369 if (build_options.omit_stage2)
2334 @panic("sadly stage2 is omitted from this build to save memory on the CI server");2370 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
2335 const module = comp.bin_file.options.module.?;2371 const module = comp.bin_file.options.module.?;
...@@ -2339,6 +2375,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2339,6 +2375,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2339 };2375 };
2340 },2376 },
2341 .update_line_number => |decl| {2377 .update_line_number => |decl| {
2378 const named_frame = tracy.namedFrame("update_line_number");
2379 defer named_frame.end();
2380
2342 if (build_options.omit_stage2)2381 if (build_options.omit_stage2)
2343 @panic("sadly stage2 is omitted from this build to save memory on the CI server");2382 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
2344 const gpa = comp.gpa;2383 const gpa = comp.gpa;
...@@ -2355,6 +2394,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2355,6 +2394,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2355 };2394 };
2356 },2395 },
2357 .analyze_pkg => |pkg| {2396 .analyze_pkg => |pkg| {
2397 const named_frame = tracy.namedFrame("analyze_pkg");
2398 defer named_frame.end();
2399
2358 if (build_options.omit_stage2)2400 if (build_options.omit_stage2)
2359 @panic("sadly stage2 is omitted from this build to save memory on the CI server");2401 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
2360 const module = comp.bin_file.options.module.?;2402 const module = comp.bin_file.options.module.?;
...@@ -2371,6 +2413,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2371,6 +2413,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2371 };2413 };
2372 },2414 },
2373 .glibc_crt_file => |crt_file| {2415 .glibc_crt_file => |crt_file| {
2416 const named_frame = tracy.namedFrame("glibc_crt_file");
2417 defer named_frame.end();
2418
2374 glibc.buildCRTFile(comp, crt_file) catch |err| {2419 glibc.buildCRTFile(comp, crt_file) catch |err| {
2375 // TODO Surface more error details.2420 // TODO Surface more error details.
2376 try comp.setMiscFailure(.glibc_crt_file, "unable to build glibc CRT file: {s}", .{2421 try comp.setMiscFailure(.glibc_crt_file, "unable to build glibc CRT file: {s}", .{
...@@ -2379,6 +2424,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2379,6 +2424,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2379 };2424 };
2380 },2425 },
2381 .glibc_shared_objects => {2426 .glibc_shared_objects => {
2427 const named_frame = tracy.namedFrame("glibc_shared_objects");
2428 defer named_frame.end();
2429
2382 glibc.buildSharedObjects(comp) catch |err| {2430 glibc.buildSharedObjects(comp) catch |err| {
2383 // TODO Surface more error details.2431 // TODO Surface more error details.
2384 try comp.setMiscFailure(2432 try comp.setMiscFailure(
...@@ -2389,6 +2437,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2389,6 +2437,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2389 };2437 };
2390 },2438 },
2391 .musl_crt_file => |crt_file| {2439 .musl_crt_file => |crt_file| {
2440 const named_frame = tracy.namedFrame("musl_crt_file");
2441 defer named_frame.end();
2442
2392 musl.buildCRTFile(comp, crt_file) catch |err| {2443 musl.buildCRTFile(comp, crt_file) catch |err| {
2393 // TODO Surface more error details.2444 // TODO Surface more error details.
2394 try comp.setMiscFailure(2445 try comp.setMiscFailure(
...@@ -2399,6 +2450,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2399,6 +2450,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2399 };2450 };
2400 },2451 },
2401 .mingw_crt_file => |crt_file| {2452 .mingw_crt_file => |crt_file| {
2453 const named_frame = tracy.namedFrame("mingw_crt_file");
2454 defer named_frame.end();
2455
2402 mingw.buildCRTFile(comp, crt_file) catch |err| {2456 mingw.buildCRTFile(comp, crt_file) catch |err| {
2403 // TODO Surface more error details.2457 // TODO Surface more error details.
2404 try comp.setMiscFailure(2458 try comp.setMiscFailure(
...@@ -2409,6 +2463,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2409,6 +2463,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2409 };2463 };
2410 },2464 },
2411 .windows_import_lib => |index| {2465 .windows_import_lib => |index| {
2466 const named_frame = tracy.namedFrame("windows_import_lib");
2467 defer named_frame.end();
2468
2412 const link_lib = comp.bin_file.options.system_libs.keys()[index];2469 const link_lib = comp.bin_file.options.system_libs.keys()[index];
2413 mingw.buildImportLib(comp, link_lib) catch |err| {2470 mingw.buildImportLib(comp, link_lib) catch |err| {
2414 // TODO Surface more error details.2471 // TODO Surface more error details.
...@@ -2420,6 +2477,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2420,6 +2477,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2420 };2477 };
2421 },2478 },
2422 .libunwind => {2479 .libunwind => {
2480 const named_frame = tracy.namedFrame("libunwind");
2481 defer named_frame.end();
2482
2423 libunwind.buildStaticLib(comp) catch |err| {2483 libunwind.buildStaticLib(comp) catch |err| {
2424 // TODO Surface more error details.2484 // TODO Surface more error details.
2425 try comp.setMiscFailure(2485 try comp.setMiscFailure(
...@@ -2430,6 +2490,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2430,6 +2490,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2430 };2490 };
2431 },2491 },
2432 .libcxx => {2492 .libcxx => {
2493 const named_frame = tracy.namedFrame("libcxx");
2494 defer named_frame.end();
2495
2433 libcxx.buildLibCXX(comp) catch |err| {2496 libcxx.buildLibCXX(comp) catch |err| {
2434 // TODO Surface more error details.2497 // TODO Surface more error details.
2435 try comp.setMiscFailure(2498 try comp.setMiscFailure(
...@@ -2440,6 +2503,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2440,6 +2503,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2440 };2503 };
2441 },2504 },
2442 .libcxxabi => {2505 .libcxxabi => {
2506 const named_frame = tracy.namedFrame("libcxxabi");
2507 defer named_frame.end();
2508
2443 libcxx.buildLibCXXABI(comp) catch |err| {2509 libcxx.buildLibCXXABI(comp) catch |err| {
2444 // TODO Surface more error details.2510 // TODO Surface more error details.
2445 try comp.setMiscFailure(2511 try comp.setMiscFailure(
...@@ -2450,6 +2516,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2450,6 +2516,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2450 };2516 };
2451 },2517 },
2452 .libtsan => {2518 .libtsan => {
2519 const named_frame = tracy.namedFrame("libtsan");
2520 defer named_frame.end();
2521
2453 libtsan.buildTsan(comp) catch |err| {2522 libtsan.buildTsan(comp) catch |err| {
2454 // TODO Surface more error details.2523 // TODO Surface more error details.
2455 try comp.setMiscFailure(2524 try comp.setMiscFailure(
...@@ -2460,6 +2529,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2460,6 +2529,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2460 };2529 };
2461 },2530 },
2462 .wasi_libc_crt_file => |crt_file| {2531 .wasi_libc_crt_file => |crt_file| {
2532 const named_frame = tracy.namedFrame("wasi_libc_crt_file");
2533 defer named_frame.end();
2534
2463 wasi_libc.buildCRTFile(comp, crt_file) catch |err| {2535 wasi_libc.buildCRTFile(comp, crt_file) catch |err| {
2464 // TODO Surface more error details.2536 // TODO Surface more error details.
2465 try comp.setMiscFailure(2537 try comp.setMiscFailure(
...@@ -2470,6 +2542,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2470,6 +2542,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2470 };2542 };
2471 },2543 },
2472 .compiler_rt_lib => {2544 .compiler_rt_lib => {
2545 const named_frame = tracy.namedFrame("compiler_rt_lib");
2546 defer named_frame.end();
2547
2473 comp.buildOutputFromZig(2548 comp.buildOutputFromZig(
2474 "compiler_rt.zig",2549 "compiler_rt.zig",
2475 .Lib,2550 .Lib,
...@@ -2486,6 +2561,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2486,6 +2561,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2486 };2561 };
2487 },2562 },
2488 .compiler_rt_obj => {2563 .compiler_rt_obj => {
2564 const named_frame = tracy.namedFrame("compiler_rt_obj");
2565 defer named_frame.end();
2566
2489 comp.buildOutputFromZig(2567 comp.buildOutputFromZig(
2490 "compiler_rt.zig",2568 "compiler_rt.zig",
2491 .Obj,2569 .Obj,
...@@ -2502,6 +2580,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2502,6 +2580,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2502 };2580 };
2503 },2581 },
2504 .libssp => {2582 .libssp => {
2583 const named_frame = tracy.namedFrame("libssp");
2584 defer named_frame.end();
2585
2505 comp.buildOutputFromZig(2586 comp.buildOutputFromZig(
2506 "ssp.zig",2587 "ssp.zig",
2507 .Lib,2588 .Lib,
...@@ -2518,6 +2599,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2518,6 +2599,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2518 };2599 };
2519 },2600 },
2520 .zig_libc => {2601 .zig_libc => {
2602 const named_frame = tracy.namedFrame("zig_libc");
2603 defer named_frame.end();
2604
2521 comp.buildOutputFromZig(2605 comp.buildOutputFromZig(
2522 "c.zig",2606 "c.zig",
2523 .Lib,2607 .Lib,
...@@ -2534,6 +2618,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2534,6 +2618,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2534 };2618 };
2535 },2619 },
2536 .stage1_module => {2620 .stage1_module => {
2621 const named_frame = tracy.namedFrame("stage1_module");
2622 defer named_frame.end();
2623
2537 if (!build_options.is_stage1)2624 if (!build_options.is_stage1)
2538 unreachable;2625 unreachable;
25392626
...@@ -2674,8 +2761,8 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {...@@ -2674,8 +2761,8 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
2674 if (!build_options.have_llvm)2761 if (!build_options.have_llvm)
2675 return error.ZigCompilerNotBuiltWithLLVMExtensions;2762 return error.ZigCompilerNotBuiltWithLLVMExtensions;
26762763
2677 const tracy = trace(@src());2764 const t = trace(@src());
2678 defer tracy.end();2765 defer t.end();
26792766
2680 const cimport_zig_basename = "cimport.zig";2767 const cimport_zig_basename = "cimport.zig";
26812768
...@@ -2929,8 +3016,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P...@@ -2929,8 +3016,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
2929 const self_exe_path = comp.self_exe_path orelse3016 const self_exe_path = comp.self_exe_path orelse
2930 return comp.failCObj(c_object, "clang compilation disabled", .{});3017 return comp.failCObj(c_object, "clang compilation disabled", .{});
29313018
2932 const tracy = trace(@src());3019 const t = trace(@src());
2933 defer tracy.end();3020 defer t.end();
29343021
2935 log.debug("updating C object: {s}", .{c_object.src.src_path});3022 log.debug("updating C object: {s}", .{c_object.src.src_path});
29363023
...@@ -3828,8 +3915,8 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {...@@ -3828,8 +3915,8 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
3828}3915}
38293916
3830fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) Allocator.Error!void {3917fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) Allocator.Error!void {
3831 const tracy = trace(@src());3918 const t = trace(@src());
3832 defer tracy.end();3919 defer t.end();
38333920
3834 const source = try comp.generateBuiltinZigSource(comp.gpa);3921 const source = try comp.generateBuiltinZigSource(comp.gpa);
3835 defer comp.gpa.free(source);3922 defer comp.gpa.free(source);
...@@ -3866,8 +3953,8 @@ pub fn dump_argv(argv: []const []const u8) void {...@@ -3866,8 +3953,8 @@ pub fn dump_argv(argv: []const []const u8) void {
3866}3953}
38673954
3868pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Allocator.Error![]u8 {3955pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Allocator.Error![]u8 {
3869 const tracy = trace(@src());3956 const t = trace(@src());
3870 defer tracy.end();3957 defer t.end();
38713958
3872 var buffer = std.ArrayList(u8).init(allocator);3959 var buffer = std.ArrayList(u8).init(allocator);
3873 defer buffer.deinit();3960 defer buffer.deinit();
...@@ -4112,8 +4199,8 @@ fn buildOutputFromZig(...@@ -4112,8 +4199,8 @@ fn buildOutputFromZig(
4112 out: *?CRTFile,4199 out: *?CRTFile,
4113 misc_task_tag: MiscTask,4200 misc_task_tag: MiscTask,
4114) !void {4201) !void {
4115 const tracy = trace(@src());4202 const t = trace(@src());
4116 defer tracy.end();4203 defer t.end();
41174204
4118 std.debug.assert(output_mode != .Exe);4205 std.debug.assert(output_mode != .Exe);
4119 const special_sub = "std" ++ std.fs.path.sep_str ++ "special";4206 const special_sub = "std" ++ std.fs.path.sep_str ++ "special";
...@@ -4211,8 +4298,8 @@ fn buildOutputFromZig(...@@ -4211,8 +4298,8 @@ fn buildOutputFromZig(
4211}4298}
42124299
4213fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node) !void {4300fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node) !void {
4214 const tracy = trace(@src());4301 const t = trace(@src());
4215 defer tracy.end();4302 defer t.end();
42164303
4217 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);4304 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
4218 defer arena_allocator.deinit();4305 defer arena_allocator.deinit();
...@@ -4564,8 +4651,8 @@ pub fn build_crt_file(...@@ -4564,8 +4651,8 @@ pub fn build_crt_file(
4564 output_mode: std.builtin.OutputMode,4651 output_mode: std.builtin.OutputMode,
4565 c_source_files: []const Compilation.CSourceFile,4652 c_source_files: []const Compilation.CSourceFile,
4566) !void {4653) !void {
4567 const tracy = trace(@src());4654 const t = trace(@src());
4568 defer tracy.end();4655 defer t.end();
45694656
4570 const target = comp.getTarget();4657 const target = comp.getTarget();
4571 const basename = try std.zig.binNameAlloc(comp.gpa, .{4658 const basename = try std.zig.binNameAlloc(comp.gpa, .{
src/main.zig+10
...@@ -10,6 +10,7 @@ const ArrayList = std.ArrayList;...@@ -10,6 +10,7 @@ const ArrayList = std.ArrayList;
10const Ast = std.zig.Ast;10const Ast = std.zig.Ast;
11const warn = std.log.warn;11const warn = std.log.warn;
1212
13const tracy = @import("tracy.zig");
13const Compilation = @import("Compilation.zig");14const Compilation = @import("Compilation.zig");
14const link = @import("link.zig");15const link = @import("link.zig");
15const Package = @import("Package.zig");16const Package = @import("Package.zig");
...@@ -155,6 +156,12 @@ pub fn main() anyerror!void {...@@ -155,6 +156,12 @@ pub fn main() anyerror!void {
155 const arena = &arena_instance.allocator;156 const arena = &arena_instance.allocator;
156157
157 const args = try process.argsAlloc(arena);158 const args = try process.argsAlloc(arena);
159
160 if (tracy.enable_allocation) {
161 var gpa_tracy = tracy.tracyAllocator(gpa);
162 return mainArgs(&gpa_tracy.allocator, arena, args);
163 }
164
158 return mainArgs(gpa, arena, args);165 return mainArgs(gpa, arena, args);
159}166}
160167
...@@ -2297,6 +2304,7 @@ fn buildOutputType(...@@ -2297,6 +2304,7 @@ fn buildOutputType(
2297 last_cmd = cmd;2304 last_cmd = cmd;
2298 switch (cmd) {2305 switch (cmd) {
2299 .update => {2306 .update => {
2307 tracy.frameMark();
2300 if (output_mode == .Exe) {2308 if (output_mode == .Exe) {
2301 try comp.makeBinFileWritable();2309 try comp.makeBinFileWritable();
2302 }2310 }
...@@ -2309,6 +2317,7 @@ fn buildOutputType(...@@ -2309,6 +2317,7 @@ fn buildOutputType(
2309 try stderr.writeAll(repl_help);2317 try stderr.writeAll(repl_help);
2310 },2318 },
2311 .run => {2319 .run => {
2320 tracy.frameMark();
2312 try runOrTest(2321 try runOrTest(
2313 comp,2322 comp,
2314 gpa,2323 gpa,
...@@ -2325,6 +2334,7 @@ fn buildOutputType(...@@ -2325,6 +2334,7 @@ fn buildOutputType(
2325 );2334 );
2326 },2335 },
2327 .update_and_run => {2336 .update_and_run => {
2337 tracy.frameMark();
2328 if (output_mode == .Exe) {2338 if (output_mode == .Exe) {
2329 try comp.makeBinFileWritable();2339 try comp.makeBinFileWritable();
2330 }2340 }
src/tracy.zig+287-25
...@@ -2,47 +2,309 @@ const std = @import("std");...@@ -2,47 +2,309 @@ const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub const enable = if (builtin.is_test) false else @import("build_options").enable_tracy;4pub const enable = if (builtin.is_test) false else @import("build_options").enable_tracy;
5pub const enable_allocation = enable and @import("build_options").enable_tracy_allocation;
6pub const enable_callstack = enable and @import("build_options").enable_tracy_callstack;
57
6extern fn ___tracy_emit_zone_begin_callstack(8// TODO: make this configurable
7 srcloc: *const ___tracy_source_location_data,9const callstack_depth = 10;
8 depth: c_int,
9 active: c_int,
10) ___tracy_c_zone_context;
11
12extern fn ___tracy_emit_zone_end(ctx: ___tracy_c_zone_context) void;
13
14pub const ___tracy_source_location_data = extern struct {
15 name: ?[*:0]const u8,
16 function: [*:0]const u8,
17 file: [*:0]const u8,
18 line: u32,
19 color: u32,
20};
2110
22pub const ___tracy_c_zone_context = extern struct {11const ___tracy_c_zone_context = extern struct {
23 id: u32,12 id: u32,
24 active: c_int,13 active: c_int,
2514
26 pub fn end(self: ___tracy_c_zone_context) void {15 pub inline fn end(self: @This()) void {
27 ___tracy_emit_zone_end(self);16 ___tracy_emit_zone_end(self);
28 }17 }
18
19 pub inline fn addText(self: @This(), text: []const u8) void {
20 ___tracy_emit_zone_text(self, text.ptr, text.len);
21 }
22
23 pub inline fn setName(self: @This(), name: []const u8) void {
24 ___tracy_emit_zone_name(self, name.ptr, name.len);
25 }
26
27 pub inline fn setColor(self: @This(), color: u32) void {
28 ___tracy_emit_zone_color(self, color);
29 }
30
31 pub inline fn setValue(self: @This(), value: u64) void {
32 ___tracy_emit_zone_value(self, value);
33 }
29};34};
3035
31pub const Ctx = if (enable) ___tracy_c_zone_context else struct {36pub const Ctx = if (enable) ___tracy_c_zone_context else struct {
32 pub fn end(self: Ctx) void {37 pub inline fn end(self: @This()) void {
38 _ = self;
39 }
40
41 pub inline fn addText(self: @This(), text: []const u8) void {
33 _ = self;42 _ = self;
43 _ = text;
44 }
45
46 pub inline fn setName(self: @This(), name: []const u8) void {
47 _ = self;
48 _ = name;
49 }
50
51 pub inline fn setColor(self: @This(), color: u32) void {
52 _ = self;
53 _ = color;
54 }
55
56 pub inline fn setValue(self: @This(), value: u64) void {
57 _ = self;
58 _ = value;
34 }59 }
35};60};
3661
37pub inline fn trace(comptime src: std.builtin.SourceLocation) Ctx {62pub inline fn trace(comptime src: std.builtin.SourceLocation) Ctx {
38 if (!enable) return .{};63 if (!enable) return .{};
3964
40 const loc: ___tracy_source_location_data = .{65 if (enable_callstack) {
41 .name = null,66 return ___tracy_emit_zone_begin_callstack(&.{
42 .function = src.fn_name.ptr,67 .name = null,
43 .file = src.file.ptr,68 .function = src.fn_name.ptr,
44 .line = src.line,69 .file = src.file.ptr,
45 .color = 0,70 .line = src.line,
71 .color = 0,
72 }, callstack_depth, 1);
73 } else {
74 return ___tracy_emit_zone_begin(&.{
75 .name = null,
76 .function = src.fn_name.ptr,
77 .file = src.file.ptr,
78 .line = src.line,
79 .color = 0,
80 }, 1);
81 }
82}
83
84pub inline fn traceNamed(comptime src: std.builtin.SourceLocation, comptime name: [:0]const u8) Ctx {
85 if (!enable) return .{};
86
87 if (enable_callstack) {
88 return ___tracy_emit_zone_begin_callstack(&.{
89 .name = name.ptr,
90 .function = src.fn_name.ptr,
91 .file = src.file.ptr,
92 .line = src.line,
93 .color = 0,
94 }, callstack_depth, 1);
95 } else {
96 return ___tracy_emit_zone_begin(&.{
97 .name = name.ptr,
98 .function = src.fn_name.ptr,
99 .file = src.file.ptr,
100 .line = src.line,
101 .color = 0,
102 }, 1);
103 }
104}
105
106pub fn tracyAllocator(allocator: *std.mem.Allocator) TracyAllocator(null) {
107 return TracyAllocator(null).init(allocator);
108}
109
110pub fn TracyAllocator(comptime name: ?[:0]const u8) type {
111 return struct {
112 allocator: std.mem.Allocator,
113 parent_allocator: *std.mem.Allocator,
114
115 const Self = @This();
116
117 pub fn init(allocator: *std.mem.Allocator) Self {
118 return .{
119 .parent_allocator = allocator,
120 .allocator = .{
121 .allocFn = allocFn,
122 .resizeFn = resizeFn,
123 },
124 };
125 }
126
127 fn allocFn(allocator: *std.mem.Allocator, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) std.mem.Allocator.Error![]u8 {
128 const self = @fieldParentPtr(Self, "allocator", allocator);
129 const result = self.parent_allocator.allocFn(self.parent_allocator, len, ptr_align, len_align, ret_addr);
130 if (result) |data| {
131 if (data.len != 0) {
132 if (name) |n| {
133 allocNamed(data.ptr, data.len, n);
134 } else {
135 alloc(data.ptr, data.len);
136 }
137 }
138 } else |_| {
139 messageColor("allocation failed", 0xFF0000);
140 }
141 return result;
142 }
143
144 fn resizeFn(allocator: *std.mem.Allocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) std.mem.Allocator.Error!usize {
145 const self = @fieldParentPtr(Self, "allocator", allocator);
146
147 if (self.parent_allocator.resizeFn(self.parent_allocator, buf, buf_align, new_len, len_align, ret_addr)) |resized_len| {
148 // this condition is to handle free being called on an empty slice that was never even allocated
149 // example case: `std.process.getSelfExeSharedLibPaths` can return `&[_][:0]u8{}`
150 if (buf.len != 0) {
151 if (name) |n| {
152 freeNamed(buf.ptr, n);
153 } else {
154 free(buf.ptr);
155 }
156 }
157
158 if (resized_len != 0) {
159 // this was a shrink or a resize
160 if (name) |n| {
161 allocNamed(buf.ptr, resized_len, n);
162 } else {
163 alloc(buf.ptr, resized_len);
164 }
165 }
166
167 return resized_len;
168 } else |err| {
169 // this is not really an error condition, during normal operation the compiler hits this case thousands of times
170 // due to this emitting messages for it is both slow and causes clutter
171 // messageColor("allocation resize failed", 0xFF0000);
172 return err;
173 }
174 }
175 };
176}
177
178// This function only accepts comptime known strings, see `messageCopy` for runtime strings
179pub inline fn message(comptime msg: [:0]const u8) void {
180 if (!enable) return;
181 ___tracy_emit_messageL(msg.ptr, if (enable_callstack) callstack_depth else 0);
182}
183
184// This function only accepts comptime known strings, see `messageColorCopy` for runtime strings
185pub inline fn messageColor(comptime msg: [:0]const u8, color: u32) void {
186 if (!enable) return;
187 ___tracy_emit_messageLC(msg.ptr, color, if (enable_callstack) callstack_depth else 0);
188}
189
190pub inline fn messageCopy(msg: []const u8) void {
191 if (!enable) return;
192 ___tracy_emit_message(msg.ptr, msg.len, if (enable_callstack) callstack_depth else 0);
193}
194
195pub inline fn messageColorCopy(msg: [:0]const u8, color: u32) void {
196 if (!enable) return;
197 ___tracy_emit_messageC(msg.ptr, msg.len, color, if (enable_callstack) callstack_depth else 0);
198}
199
200pub inline fn frameMark() void {
201 if (!enable) return;
202 ___tracy_emit_frame_mark(null);
203}
204
205pub inline fn frameMarkNamed(comptime name: [:0]const u8) void {
206 if (!enable) return;
207 ___tracy_emit_frame_mark(name.ptr);
208}
209
210pub inline fn namedFrame(comptime name: [:0]const u8) Frame(name) {
211 frameMarkStart(name);
212 return .{};
213}
214
215pub fn Frame(comptime name: [:0]const u8) type {
216 return struct {
217 pub fn end(_: @This()) void {
218 frameMarkEnd(name);
219 }
46 };220 };
47 return ___tracy_emit_zone_begin_callstack(&loc, 1, 1);
48}221}
222
223inline fn frameMarkStart(comptime name: [:0]const u8) void {
224 if (!enable) return;
225 ___tracy_emit_frame_mark_start(name.ptr);
226}
227
228inline fn frameMarkEnd(comptime name: [:0]const u8) void {
229 if (!enable) return;
230 ___tracy_emit_frame_mark_end(name.ptr);
231}
232
233extern fn ___tracy_emit_frame_mark_start(name: [*:0]const u8) void;
234extern fn ___tracy_emit_frame_mark_end(name: [*:0]const u8) void;
235
236inline fn alloc(ptr: [*]u8, len: usize) void {
237 if (!enable) return;
238
239 if (enable_callstack) {
240 ___tracy_emit_memory_alloc_callstack(ptr, len, callstack_depth, 0);
241 } else {
242 ___tracy_emit_memory_alloc(ptr, len, 0);
243 }
244}
245
246inline fn allocNamed(ptr: [*]u8, len: usize, comptime name: [:0]const u8) void {
247 if (!enable) return;
248
249 if (enable_callstack) {
250 ___tracy_emit_memory_alloc_callstack_named(ptr, len, callstack_depth, 0, name.ptr);
251 } else {
252 ___tracy_emit_memory_alloc_named(ptr, len, 0, name.ptr);
253 }
254}
255
256inline fn free(ptr: [*]u8) void {
257 if (!enable) return;
258
259 if (enable_callstack) {
260 ___tracy_emit_memory_free_callstack(ptr, callstack_depth, 0);
261 } else {
262 ___tracy_emit_memory_free(ptr, 0);
263 }
264}
265
266inline fn freeNamed(ptr: [*]u8, comptime name: [:0]const u8) void {
267 if (!enable) return;
268
269 if (enable_callstack) {
270 ___tracy_emit_memory_free_callstack_named(ptr, callstack_depth, 0, name.ptr);
271 } else {
272 ___tracy_emit_memory_free_named(ptr, 0, name.ptr);
273 }
274}
275
276extern fn ___tracy_emit_zone_begin(
277 srcloc: *const ___tracy_source_location_data,
278 active: c_int,
279) ___tracy_c_zone_context;
280extern fn ___tracy_emit_zone_begin_callstack(
281 srcloc: *const ___tracy_source_location_data,
282 depth: c_int,
283 active: c_int,
284) ___tracy_c_zone_context;
285extern fn ___tracy_emit_zone_text(ctx: ___tracy_c_zone_context, txt: [*]const u8, size: usize) void;
286extern fn ___tracy_emit_zone_name(ctx: ___tracy_c_zone_context, txt: [*]const u8, size: usize) void;
287extern fn ___tracy_emit_zone_color(ctx: ___tracy_c_zone_context, color: u32) void;
288extern fn ___tracy_emit_zone_value(ctx: ___tracy_c_zone_context, value: u64) void;
289extern fn ___tracy_emit_zone_end(ctx: ___tracy_c_zone_context) void;
290extern fn ___tracy_emit_memory_alloc(ptr: *const c_void, size: usize, secure: c_int) void;
291extern fn ___tracy_emit_memory_alloc_callstack(ptr: *const c_void, size: usize, depth: c_int, secure: c_int) void;
292extern fn ___tracy_emit_memory_free(ptr: *const c_void, secure: c_int) void;
293extern fn ___tracy_emit_memory_free_callstack(ptr: *const c_void, depth: c_int, secure: c_int) void;
294extern fn ___tracy_emit_memory_alloc_named(ptr: *const c_void, size: usize, secure: c_int, name: [*:0]const u8) void;
295extern fn ___tracy_emit_memory_alloc_callstack_named(ptr: *const c_void, size: usize, depth: c_int, secure: c_int, name: [*:0]const u8) void;
296extern fn ___tracy_emit_memory_free_named(ptr: *const c_void, secure: c_int, name: [*:0]const u8) void;
297extern fn ___tracy_emit_memory_free_callstack_named(ptr: *const c_void, depth: c_int, secure: c_int, name: [*:0]const u8) void;
298extern fn ___tracy_emit_message(txt: [*]const u8, size: usize, callstack: c_int) void;
299extern fn ___tracy_emit_messageL(txt: [*:0]const u8, callstack: c_int) void;
300extern fn ___tracy_emit_messageC(txt: [*]const u8, size: usize, color: u32, callstack: c_int) void;
301extern fn ___tracy_emit_messageLC(txt: [*:0]const u8, color: u32, callstack: c_int) void;
302extern fn ___tracy_emit_frame_mark(name: ?[*:0]const u8) void;
303
304const ___tracy_source_location_data = extern struct {
305 name: ?[*:0]const u8,
306 function: [*:0]const u8,
307 file: [*:0]const u8,
308 line: u32,
309 color: u32,
310};