authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-18 19:03:41-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-18 21:55:37-04:00
logc9a0ec25e0baae7f128a8f7efe4d308af7fad753
tree71892b6263beda3d803b02c724733aba98cb39ef
parent355319fb674073234ea2f356a310577fb982f72b

self-hosted: add Tracy integration

This tool helps give an intuitive picture of performance. This will help us understand where to improve the code.

5 files changed, 81 insertions(+), 2 deletions(-)

build.zig+13
......@@ -72,9 +72,22 @@ pub fn build(b: *Builder) !void {
7272 if (!only_install_lib_files) {
7373 exe.install();
7474 }
75 const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");
7576 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse false;
7677 if (link_libc) exe.linkLibC();
7778
79 exe.addBuildOption(bool, "enable_tracy", tracy != null);
80 if (tracy) |tracy_path| {
81 const client_cpp = fs.path.join(
82 b.allocator,
83 &[_][]const u8{ tracy_path, "TracyClient.cpp" },
84 ) catch unreachable;
85 exe.addIncludeDir(tracy_path);
86 exe.addCSourceFile(client_cpp, &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" });
87 exe.linkSystemLibraryName("c++");
88 exe.linkLibC();
89 }
90
7891 b.installDirectory(InstallDirectoryOptions{
7992 .source_dir = "lib",
8093 .install_dir = .Lib,
lib/std/build.zig+3-2
......@@ -1905,10 +1905,11 @@ pub const LibExeObjStep = struct {
19051905 builder.allocator,
19061906 &[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) },
19071907 );
1908 try fs.cwd().writeFile(build_options_file, self.build_options_contents.span());
1908 const path_from_root = builder.pathFromRoot(build_options_file);
1909 try fs.cwd().writeFile(path_from_root, self.build_options_contents.span());
19091910 try zig_args.append("--pkg-begin");
19101911 try zig_args.append("build_options");
1911 try zig_args.append(builder.pathFromRoot(build_options_file));
1912 try zig_args.append(path_from_root);
19121913 try zig_args.append("--pkg-end");
19131914 }
19141915
src-self-hosted/Module.zig+16
......@@ -16,6 +16,7 @@ const zir = @import("zir.zig");
1616const Module = @This();
1717const Inst = ir.Inst;
1818const ast = std.zig.ast;
19const trace = @import("tracy.zig").trace;
1920
2021/// General-purpose allocator.
2122allocator: *Allocator,
......@@ -796,6 +797,9 @@ pub fn target(self: Module) std.Target {
796797
797798/// Detect changes to source files, perform semantic analysis, and update the output files.
798799pub fn update(self: *Module) !void {
800 const tracy = trace(@src());
801 defer tracy.end();
802
799803 self.generation += 1;
800804
801805 // TODO Use the cache hash file system to detect which source files changed.
......@@ -1050,6 +1054,9 @@ fn ensureDeclAnalyzed(self: *Module, decl: *Decl) InnerError!void {
10501054}
10511055
10521056fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !void {
1057 const tracy = trace(@src());
1058 defer tracy.end();
1059
10531060 const file_scope = decl.scope.cast(Scope.File).?;
10541061 const tree = try self.getAstTree(file_scope);
10551062 const ast_node = tree.root_node.decls()[decl.src_index];
......@@ -1330,6 +1337,9 @@ fn astGenIntegerLiteral(self: *Module, scope: *Scope, int_lit: *ast.Node.Integer
13301337}
13311338
13321339fn astGenBlock(self: *Module, scope: *Scope, block_node: *ast.Node.Block) !void {
1340 const tracy = trace(@src());
1341 defer tracy.end();
1342
13331343 if (block_node.label) |label| {
13341344 return self.failTok(scope, label, "TODO implement labeled blocks", .{});
13351345 }
......@@ -1526,6 +1536,9 @@ fn getSrcModule(self: *Module, root_scope: *Scope.ZIRModule) !*zir.Module {
15261536}
15271537
15281538fn getAstTree(self: *Module, root_scope: *Scope.File) !*ast.Tree {
1539 const tracy = trace(@src());
1540 defer tracy.end();
1541
15291542 switch (root_scope.status) {
15301543 .never_loaded, .unloaded_success => {
15311544 try self.failed_files.ensureCapacity(self.failed_files.size + 1);
......@@ -1739,6 +1752,9 @@ fn deleteDeclExports(self: *Module, decl: *Decl) void {
17391752}
17401753
17411754fn analyzeFnBody(self: *Module, decl: *Decl, func: *Fn) !void {
1755 const tracy = trace(@src());
1756 defer tracy.end();
1757
17421758 // Use the Decl's arena for function memory.
17431759 var arena = decl.typed_value.most_recent.arena.?.promote(self.allocator);
17441760 defer decl.typed_value.most_recent.arena.?.* = arena.state;
src-self-hosted/codegen.zig+4
......@@ -10,6 +10,7 @@ const Module = @import("Module.zig");
1010const ErrorMsg = Module.ErrorMsg;
1111const Target = std.Target;
1212const Allocator = mem.Allocator;
13const trace = @import("tracy.zig").trace;
1314
1415pub const Result = union(enum) {
1516 /// The `code` parameter passed to `generateSymbol` has the value appended.
......@@ -29,6 +30,9 @@ pub fn generateSymbol(
2930 /// A Decl that this symbol depends on had a semantic analysis failure.
3031 AnalysisFail,
3132}!Result {
33 const tracy = trace(@src());
34 defer tracy.end();
35
3236 switch (typed_value.ty.zigTypeTag()) {
3337 .Fn => {
3438 const module_fn = typed_value.val.cast(Value.Payload.Function).?.func;
src-self-hosted/tracy.zig created+45
......@@ -0,0 +1,45 @@
1pub const std = @import("std");
2
3pub const enable = @import("build_options").enable_tracy;
4
5extern fn ___tracy_emit_zone_begin_callstack(
6 srcloc: *const ___tracy_source_location_data,
7 depth: c_int,
8 active: c_int,
9) ___tracy_c_zone_context;
10
11extern fn ___tracy_emit_zone_end(ctx: ___tracy_c_zone_context) void;
12
13pub const ___tracy_source_location_data = extern struct {
14 name: ?[*:0]const u8,
15 function: [*:0]const u8,
16 file: [*:0]const u8,
17 line: u32,
18 color: u32,
19};
20
21pub const ___tracy_c_zone_context = extern struct {
22 id: u32,
23 active: c_int,
24
25 pub fn end(self: ___tracy_c_zone_context) void {
26 ___tracy_emit_zone_end(self);
27 }
28};
29
30pub const Ctx = if (enable) ___tracy_c_zone_context else struct {
31 pub fn end(self: Ctx) void {}
32};
33
34pub inline fn trace(comptime src: std.builtin.SourceLocation) Ctx {
35 if (!enable) return .{};
36
37 const loc: ___tracy_source_location_data = .{
38 .name = null,
39 .function = src.fn_name.ptr,
40 .file = src.file.ptr,
41 .line = src.line,
42 .color = 0,
43 };
44 return ___tracy_emit_zone_begin_callstack(&loc, 1, 1);
45}