self-hosted: add Tracy integration
This tool helps give an intuitive picture of performance. This will help us understand where to improve the code.master
parent
355319fb67
commit
c9a0ec25e0
13
build.zig
13
build.zig
|
@ -72,9 +72,22 @@ pub fn build(b: *Builder) !void {
|
|||
if (!only_install_lib_files) {
|
||||
exe.install();
|
||||
}
|
||||
const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");
|
||||
const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse false;
|
||||
if (link_libc) exe.linkLibC();
|
||||
|
||||
exe.addBuildOption(bool, "enable_tracy", tracy != null);
|
||||
if (tracy) |tracy_path| {
|
||||
const client_cpp = fs.path.join(
|
||||
b.allocator,
|
||||
&[_][]const u8{ tracy_path, "TracyClient.cpp" },
|
||||
) catch unreachable;
|
||||
exe.addIncludeDir(tracy_path);
|
||||
exe.addCSourceFile(client_cpp, &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" });
|
||||
exe.linkSystemLibraryName("c++");
|
||||
exe.linkLibC();
|
||||
}
|
||||
|
||||
b.installDirectory(InstallDirectoryOptions{
|
||||
.source_dir = "lib",
|
||||
.install_dir = .Lib,
|
||||
|
|
|
@ -1905,10 +1905,11 @@ pub const LibExeObjStep = struct {
|
|||
builder.allocator,
|
||||
&[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) },
|
||||
);
|
||||
try fs.cwd().writeFile(build_options_file, self.build_options_contents.span());
|
||||
const path_from_root = builder.pathFromRoot(build_options_file);
|
||||
try fs.cwd().writeFile(path_from_root, self.build_options_contents.span());
|
||||
try zig_args.append("--pkg-begin");
|
||||
try zig_args.append("build_options");
|
||||
try zig_args.append(builder.pathFromRoot(build_options_file));
|
||||
try zig_args.append(path_from_root);
|
||||
try zig_args.append("--pkg-end");
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ const zir = @import("zir.zig");
|
|||
const Module = @This();
|
||||
const Inst = ir.Inst;
|
||||
const ast = std.zig.ast;
|
||||
const trace = @import("tracy.zig").trace;
|
||||
|
||||
/// General-purpose allocator.
|
||||
allocator: *Allocator,
|
||||
|
@ -796,6 +797,9 @@ pub fn target(self: Module) std.Target {
|
|||
|
||||
/// Detect changes to source files, perform semantic analysis, and update the output files.
|
||||
pub fn update(self: *Module) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
self.generation += 1;
|
||||
|
||||
// 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 {
|
|||
}
|
||||
|
||||
fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const file_scope = decl.scope.cast(Scope.File).?;
|
||||
const tree = try self.getAstTree(file_scope);
|
||||
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
|
|||
}
|
||||
|
||||
fn astGenBlock(self: *Module, scope: *Scope, block_node: *ast.Node.Block) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
if (block_node.label) |label| {
|
||||
return self.failTok(scope, label, "TODO implement labeled blocks", .{});
|
||||
}
|
||||
|
@ -1526,6 +1536,9 @@ fn getSrcModule(self: *Module, root_scope: *Scope.ZIRModule) !*zir.Module {
|
|||
}
|
||||
|
||||
fn getAstTree(self: *Module, root_scope: *Scope.File) !*ast.Tree {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
switch (root_scope.status) {
|
||||
.never_loaded, .unloaded_success => {
|
||||
try self.failed_files.ensureCapacity(self.failed_files.size + 1);
|
||||
|
@ -1739,6 +1752,9 @@ fn deleteDeclExports(self: *Module, decl: *Decl) void {
|
|||
}
|
||||
|
||||
fn analyzeFnBody(self: *Module, decl: *Decl, func: *Fn) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
// Use the Decl's arena for function memory.
|
||||
var arena = decl.typed_value.most_recent.arena.?.promote(self.allocator);
|
||||
defer decl.typed_value.most_recent.arena.?.* = arena.state;
|
||||
|
|
|
@ -10,6 +10,7 @@ const Module = @import("Module.zig");
|
|||
const ErrorMsg = Module.ErrorMsg;
|
||||
const Target = std.Target;
|
||||
const Allocator = mem.Allocator;
|
||||
const trace = @import("tracy.zig").trace;
|
||||
|
||||
pub const Result = union(enum) {
|
||||
/// The `code` parameter passed to `generateSymbol` has the value appended.
|
||||
|
@ -29,6 +30,9 @@ pub fn generateSymbol(
|
|||
/// A Decl that this symbol depends on had a semantic analysis failure.
|
||||
AnalysisFail,
|
||||
}!Result {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
switch (typed_value.ty.zigTypeTag()) {
|
||||
.Fn => {
|
||||
const module_fn = typed_value.val.cast(Value.Payload.Function).?.func;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
pub const std = @import("std");
|
||||
|
||||
pub const enable = @import("build_options").enable_tracy;
|
||||
|
||||
extern fn ___tracy_emit_zone_begin_callstack(
|
||||
srcloc: *const ___tracy_source_location_data,
|
||||
depth: c_int,
|
||||
active: c_int,
|
||||
) ___tracy_c_zone_context;
|
||||
|
||||
extern fn ___tracy_emit_zone_end(ctx: ___tracy_c_zone_context) void;
|
||||
|
||||
pub const ___tracy_source_location_data = extern struct {
|
||||
name: ?[*:0]const u8,
|
||||
function: [*:0]const u8,
|
||||
file: [*:0]const u8,
|
||||
line: u32,
|
||||
color: u32,
|
||||
};
|
||||
|
||||
pub const ___tracy_c_zone_context = extern struct {
|
||||
id: u32,
|
||||
active: c_int,
|
||||
|
||||
pub fn end(self: ___tracy_c_zone_context) void {
|
||||
___tracy_emit_zone_end(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Ctx = if (enable) ___tracy_c_zone_context else struct {
|
||||
pub fn end(self: Ctx) void {}
|
||||
};
|
||||
|
||||
pub inline fn trace(comptime src: std.builtin.SourceLocation) Ctx {
|
||||
if (!enable) return .{};
|
||||
|
||||
const loc: ___tracy_source_location_data = .{
|
||||
.name = null,
|
||||
.function = src.fn_name.ptr,
|
||||
.file = src.file.ptr,
|
||||
.line = src.line,
|
||||
.color = 0,
|
||||
};
|
||||
return ___tracy_emit_zone_begin_callstack(&loc, 1, 1);
|
||||
}
|
Loading…
Reference in New Issue