commit f3ad12b5f1e2d76d157928d9bd4b5926b1bd015f (tree)
parent c5a61e8998742ee0627afd80f35008b5d2703e61
Author: mlugg <mlugg@noreply.codeberg.org>
Date: Fri, 29 May 2026 14:55:11 +0200
Merge pull request 'Elf2: yet more enhancements' (#35516) from elf2 into master
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35516
Diffstat:
12 files changed, 424 insertions(+), 580 deletions(-)
diff --git a/build.zig b/build.zig
@@ -181,10 +181,10 @@ pub fn build(b: *std.Build) !void {
return;
const entitlements = b.option([]const u8, "entitlements", "Path to entitlements file for hot-code swapping without sudo on macOS");
- const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");
- const tracy_callstack = b.option(bool, "tracy-callstack", "Include callstack information with Tracy data. Does nothing if -Dtracy is not provided") orelse (tracy != null);
- const tracy_allocation = b.option(bool, "tracy-allocation", "Include allocation information with Tracy data. Does nothing if -Dtracy is not provided") orelse (tracy != null);
- const tracy_callstack_depth: u32 = b.option(u32, "tracy-callstack-depth", "Declare callstack depth for Tracy data. Does nothing if -Dtracy_callstack is not provided") orelse 10;
+ const tracy = b.option(std.Build.LazyPath, "tracy", "Enable Tracy integration. Supply path to Tracy source");
+ const tracy_callstack = b.option(bool, "tracy-callstack", "Include callstack information with Tracy data. Does nothing if -Dtracy is not provided. Has a significant performance impact in some cases. Default: false") orelse false;
+ const tracy_allocation = b.option(bool, "tracy-allocation", "Include allocation information with Tracy data. Does nothing if -Dtracy is not provided. Default: true") orelse (tracy != null);
+ const tracy_callstack_depth: u32 = b.option(u32, "tracy-callstack-depth", "Declare callstack depth for Tracy data. Does nothing if -Dtracy-callstack is not provided") orelse 6;
const debug_gpa = b.option(bool, "debug-allocator", "Force the compiler to use SafeAllocator") orelse false;
const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse (enable_llvm or only_c);
const sanitize_thread = b.option(bool, "sanitize-thread", "Enable thread-sanitization") orelse false;
@@ -373,32 +373,31 @@ pub fn build(b: *std.Build) !void {
exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
exe_options.addOption(u32, "tracy_callstack_depth", tracy_callstack_depth);
exe_options.addOption(bool, "value_tracing", value_tracing);
- if (tracy) |tracy_path| {
- const client_cpp = b.pathJoin(
- &[_][]const u8{ tracy_path, "public", "TracyClient.cpp" },
- );
-
- const tracy_c_flags: []const []const u8 = &.{
- "-DTRACY_ENABLE=1",
- "-fno-sanitize=undefined",
- "-DTRACY_FIBERS",
- };
-
- exe.root_module.addIncludePath(.{ .cwd_relative = tracy_path });
- exe.root_module.addCSourceFile(.{
- .file = .{ .cwd_relative = client_cpp },
- .flags = tracy_c_flags[0..switch (io_mode) {
- .threaded => 2,
- .evented => 3,
- }],
+ if (tracy) |tracy_dir| {
+ const tracy_mod = b.createModule(.{
+ .target = target,
+ // Always build Tracy in ReleaseFast so that it doesn't make Debug compiler builds unusable.
+ .optimize = .ReleaseFast,
+ .root_source_file = null,
+ .link_libc = true,
+ .link_libcpp = true,
});
- exe.root_module.link_libc = true;
- exe.root_module.link_libcpp = true;
+
+ tracy_mod.addCMacro("TRACY_ENABLE", "1");
+
+ if (!tracy_callstack) {
+ tracy_mod.addCMacro("TRACY_NO_CALLSTACK", "1");
+ }
+
+ tracy_mod.addIncludePath(tracy_dir);
+ tracy_mod.addCSourceFile(.{ .file = tracy_dir.path(b, "public/TracyClient.cpp") });
if (target.result.os.tag == .windows) {
- exe.root_module.linkSystemLibrary("dbghelp", .{});
- exe.root_module.linkSystemLibrary("ws2_32", .{});
+ tracy_mod.linkSystemLibrary("dbghelp", .{});
+ tracy_mod.linkSystemLibrary("ws2_32", .{});
}
+
+ exe.root_module.addImport("tracy", tracy_mod);
}
const test_filters = b.option([]const []const u8, "test-filter", "Skip tests that do not match any filter") orelse &[0][]const u8{};
diff --git a/src/Air/Liveness.zig b/src/Air/Liveness.zig
@@ -13,7 +13,7 @@ const Log2Int = std.math.Log2Int;
const Writer = std.Io.Writer;
const Liveness = @This();
-const trace = @import("../tracy.zig").trace;
+const traceNamed = @import("../tracy.zig").traceNamed;
const Air = @import("../Air.zig");
const InternPool = @import("../InternPool.zig");
const Zcu = @import("../Zcu.zig");
@@ -140,7 +140,7 @@ fn LivenessPassData(comptime pass: LivenessPass) type {
}
pub fn analyze(zcu: *Zcu, air: Air, intern_pool: *InternPool) Allocator.Error!Liveness {
- const tracy = trace(@src());
+ const tracy = traceNamed(@src(), "analyze_liveness");
defer tracy.end();
const gpa = zcu.gpa;
diff --git a/src/Compilation.zig b/src/Compilation.zig
@@ -2870,8 +2870,8 @@ pub const UpdateError = error{
/// Detect changes to source files, perform semantic analysis, and update the output files.
pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateError!void {
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
+ const tracy_frame = tracy.namedFrame(comp.root_name);
+ defer tracy_frame.end();
const gpa = comp.gpa;
const io = comp.io;
@@ -3008,10 +3008,19 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
// For compiling C objects, we rely on the cache hash system to avoid duplicating work.
// Add a Job for each C object.
- try comp.c_object_work_queue.ensureUnusedCapacity(gpa, comp.c_object_table.count());
- for (comp.c_object_table.keys()) |c_object| {
- comp.c_object_work_queue.pushBackAssumeCapacity(c_object);
- try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{c_object.src.src_path}));
+ if (comp.bin_file != null and comp.bin_file.?.post_prelink) {
+ assert(comp.config.incremental);
+ // TODO: this indicates that we are using incremental compilation and this is not the first
+ // incremental update. The incremental linkers do not (currently?) support updating C inputs
+ // incrementally. The frontend needs to learn to trigger a full rebuild if a C link input
+ // changes. For now, to avoid crashing the linker in this case, don't kick off C object
+ // updates if we've done prelink already. https://codeberg.org/ziglang/zig/issues/32081
+ } else {
+ try comp.c_object_work_queue.ensureUnusedCapacity(gpa, comp.c_object_table.count());
+ for (comp.c_object_table.keys()) |c_object| {
+ comp.c_object_work_queue.pushBackAssumeCapacity(c_object);
+ try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{c_object.src.src_path}));
+ }
}
for (comp.link_inputs) |input| if (input.path()) |path| {
@@ -7595,6 +7604,9 @@ pub fn queuePrelinkTaskMode(comp: *Compilation, path: Cache.Path, must_link: boo
/// Only valid to call during `update`.
pub fn queuePrelinkTasks(comp: *Compilation, tasks: []const link.PrelinkTask) Io.Cancelable!void {
+ if (tasks.len > 0) {
+ if (comp.bin_file) |lf| assert(!lf.post_prelink);
+ }
comp.link_prog_node.increaseEstimatedTotalItems(tasks.len);
try comp.link_queue.enqueuePrelink(comp, tasks);
}
diff --git a/src/Sema.zig b/src/Sema.zig
@@ -19,7 +19,6 @@ const Type = @import("Type.zig");
const Air = @import("Air.zig");
const Zir = std.zig.Zir;
const Zcu = @import("Zcu.zig");
-const trace = @import("tracy.zig").trace;
const Namespace = Zcu.Namespace;
const CompileError = Zcu.CompileError;
const SemaError = Zcu.SemaError;
@@ -1127,8 +1126,6 @@ fn analyzeBodyInner(
block: *Block,
body: []const Zir.Inst.Index,
) CompileError!void {
- // No tracy calls here, to avoid interfering with the tail call mechanism.
-
try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body);
const pt = sema.pt;
@@ -3002,9 +2999,6 @@ fn zirErrorSetDecl(
sema: *Sema,
inst: Zir.Inst.Index,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -3032,9 +3026,6 @@ fn zirErrorSetDecl(
}
fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
@@ -3061,18 +3052,12 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
}
fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
const operand = sema.resolveInst(inst_data.operand);
return sema.analyzeRef(block, block.tokenOffset(inst_data.src_tok), operand, .none);
}
fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const operand = sema.resolveInst(inst_data.operand);
const src = block.nodeOffset(inst_data.src_node);
@@ -3114,9 +3099,6 @@ fn ensureResultUsed(
}
fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
@@ -3139,9 +3121,6 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
}
fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
@@ -3166,9 +3145,6 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index
}
fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const object = sema.resolveInst(inst_data.operand);
@@ -3302,9 +3278,6 @@ fn zirAllocExtended(
}
fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
const var_src = block.nodeOffset(inst_data.src_node);
@@ -3732,9 +3705,6 @@ fn zirAllocInferredComptime(
}
fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
@@ -3764,9 +3734,6 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
}
fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
@@ -3797,9 +3764,6 @@ fn zirAllocInferred(
block: *Block,
is_const: bool,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const gpa = sema.gpa;
if (block.isComptime()) {
@@ -3830,9 +3794,6 @@ fn zirAllocInferred(
}
fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const gpa = sema.gpa;
@@ -4391,9 +4352,6 @@ fn zirValidatePtrStructInit(
block: *Block,
inst: Zir.Inst.Index,
) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -4776,9 +4734,6 @@ pub fn addDeclaredHereNote(sema: *Sema, parent: *Zcu.ErrorMsg, decl_ty: Type) !v
}
fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(pl_node.src_node);
const bin = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;
@@ -4870,9 +4825,6 @@ fn zirSetEvalBranchQuota(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
}
fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const zir_tags = sema.code.instructions.items(.tag);
const zir_datas = sema.code.instructions.items(.data);
const inst_data = zir_datas[@intFromEnum(inst)].pl_node;
@@ -4935,8 +4887,6 @@ fn uavRef(sema: *Sema, val: Value) CompileError!Air.Inst.Ref {
fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
_ = block;
- const tracy = trace(@src());
- defer tracy.end();
const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].int;
return sema.pt.intRef(.comptime_int, int);
@@ -4944,8 +4894,6 @@ fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
_ = block;
- const tracy = trace(@src());
- defer tracy.end();
const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str;
const byte_count = int.len * @sizeOf(std.math.big.Limb);
@@ -4981,9 +4929,6 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
}
fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
@@ -5111,9 +5056,6 @@ fn zirTrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
}
fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -5202,9 +5144,6 @@ fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) Comp
}
fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = parent_block.nodeOffset(pl_node.src_node);
const extra = sema.code.extraData(Zir.Inst.Block, pl_node.payload_index);
@@ -5326,9 +5265,6 @@ fn resolveAnalyzedBlock(
merges: *Block.Merges,
need_debug_scope: bool,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const gpa = sema.gpa;
const pt = sema.pt;
const zcu = pt.zcu;
@@ -5540,9 +5476,6 @@ fn resolveAnalyzedBlock(
}
fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
@@ -5713,9 +5646,6 @@ fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
}
fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"break";
const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
const operand = sema.resolveInst(inst_data.operand);
@@ -5746,9 +5676,6 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
}
fn zirSwitchContinue(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"break";
const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
const operand_src = start_block.nodeOffset(extra.operand_src_node.unwrap().?);
@@ -6139,9 +6066,6 @@ fn zirCall(
inst: Zir.Inst.Index,
comptime kind: enum { direct, field },
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -7376,9 +7300,6 @@ fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
}
fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
@@ -7469,9 +7390,6 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
}
fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const len_src = block.src(.{ .node_offset_array_type_len = inst_data.src_node });
@@ -7488,9 +7406,6 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
}
fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -7534,9 +7449,6 @@ fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src:
}
fn zirAnyframeType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
if (true) {
return sema.failWithUseOfAsync(block, block.nodeOffset(inst_data.src_node));
@@ -7550,9 +7462,6 @@ fn zirAnyframeType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
}
fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -7613,9 +7522,6 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
}
fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
@@ -7655,9 +7561,6 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
}
fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const io = zcu.comp.io;
@@ -7702,9 +7605,6 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
}
fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
@@ -7759,8 +7659,6 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
_ = block;
- const tracy = trace(@src());
- defer tracy.end();
const pt = sema.pt;
const zcu = pt.zcu;
@@ -7776,9 +7674,6 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
}
fn zirDeclLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index, do_coerce: bool) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -7960,9 +7855,6 @@ fn zirOptionalPayloadPtr(
inst: Zir.Inst.Index,
safety_check: bool,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const optional_ptr = sema.resolveInst(inst_data.operand);
const src = block.nodeOffset(inst_data.src_node);
@@ -8051,9 +7943,6 @@ fn zirOptionalPayload(
inst: Zir.Inst.Index,
safety_check: bool,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
@@ -8105,9 +7994,6 @@ fn zirErrUnionPayload(
block: *Block,
inst: Zir.Inst.Index,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
@@ -8164,9 +8050,6 @@ fn zirErrUnionPayloadPtr(
block: *Block,
inst: Zir.Inst.Index,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const operand = sema.resolveInst(inst_data.operand);
const src = block.nodeOffset(inst_data.src_node);
@@ -8256,9 +8139,6 @@ fn analyzeErrUnionPayloadPtr(
/// Value in, value out
fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const operand = sema.resolveInst(inst_data.operand);
@@ -8292,9 +8172,6 @@ fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air
/// Pointer in, value out
fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const operand = sema.resolveInst(inst_data.operand);
@@ -9088,9 +8965,6 @@ fn zirParamAnytype(
}
fn zirAsNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const extra = sema.code.extraData(Zir.Inst.As, inst_data.payload_index).data;
@@ -9098,9 +8972,6 @@ fn zirAsNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
}
fn zirAsShiftOperand(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const extra = sema.code.extraData(Zir.Inst.As, inst_data.payload_index).data;
@@ -9136,9 +9007,6 @@ fn analyzeAs(
}
fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
@@ -9193,9 +9061,6 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
}
fn zirFieldPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -9218,9 +9083,6 @@ fn zirFieldPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
}
fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -9243,9 +9105,6 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
}
fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -9276,9 +9135,6 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
}
fn zirFieldPtrNamedLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
@@ -9289,9 +9145,6 @@ fn zirFieldPtrNamedLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
}
fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
@@ -9302,9 +9155,6 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
}
fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
@@ -9375,9 +9225,6 @@ fn intCast(
}
fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -9541,9 +9388,6 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
}
fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -9609,9 +9453,6 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
}
fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
@@ -9621,9 +9462,6 @@ fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
}
fn zirElemPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const elem_index_src = block.src(.{ .node_offset_array_access_index = inst_data.src_node });
@@ -9643,9 +9481,6 @@ fn zirElemPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
}
fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;
const array = sema.resolveInst(inst_data.operand);
const elem_index = try sema.pt.intRef(.usize, inst_data.idx);
@@ -9653,9 +9488,6 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
}
fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -9684,9 +9516,6 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
}
fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const elem_index_src = block.src(.{ .node_offset_array_access_index = inst_data.src_node });
@@ -9698,9 +9527,6 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
}
fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -9719,9 +9545,6 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
}
fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const extra = sema.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data;
@@ -9735,9 +9558,6 @@ fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
}
fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const extra = sema.code.extraData(Zir.Inst.SliceEnd, inst_data.payload_index).data;
@@ -9752,9 +9572,6 @@ fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
}
fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const sentinel_src = block.src(.{ .node_offset_slice_sentinel = inst_data.src_node });
@@ -9771,9 +9588,6 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
}
fn zirSliceLength(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const extra = sema.code.extraData(Zir.Inst.SliceLength, inst_data.payload_index).data;
@@ -9793,9 +9607,6 @@ fn zirSliceLength(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
}
fn zirSliceSentinelTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
@@ -9833,9 +9644,6 @@ fn zirSliceSentinelTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
}
fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const gpa = sema.gpa;
@@ -9999,8 +9807,6 @@ fn zirSwitchBlock(
inst: Zir.Inst.Index,
operand_is_ref: bool,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
const zir_switch = sema.code.getSwitchBlock(inst);
const block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
@@ -12847,9 +12653,6 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
}
fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;
@@ -12898,9 +12701,6 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
}
fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
@@ -12935,9 +12735,6 @@ fn zirShl(
inst: Zir.Inst.Index,
air_tag: Air.Inst.Tag,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -13125,9 +12922,6 @@ fn zirShr(
inst: Zir.Inst.Index,
air_tag: Air.Inst.Tag,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -13255,9 +13049,6 @@ fn zirBitwise(
inst: Zir.Inst.Index,
air_tag: Air.Inst.Tag,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -13438,9 +13229,6 @@ fn analyzeTupleCat(
}
fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -13933,9 +13721,6 @@ fn zirArithmetic(
zir_tag: Zir.Inst.Tag,
safety: bool,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
@@ -14663,9 +14448,6 @@ fn zirOverflowArithmetic(
extended: Zir.Inst.Extended.InstData,
zir_tag: Zir.Inst.Extended,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
const src = block.nodeOffset(extra.node);
@@ -15183,9 +14965,6 @@ fn analyzePtrArithmetic(
}
fn zirLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const ptr_src = src; // TODO better source location
@@ -15199,9 +14978,6 @@ fn zirAsm(
extended: Zir.Inst.Extended.InstData,
tmpl_is_expr: bool,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -15393,9 +15169,6 @@ fn zirCmpEq(
op: std.math.CompareOperator,
air_tag: Air.Inst.Tag,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -15509,9 +15282,6 @@ fn zirCmp(
inst: Zir.Inst.Index,
op: std.math.CompareOperator,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
@@ -15852,9 +15622,6 @@ fn zirBuiltinSrc(
block: *Block,
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -17181,9 +16948,6 @@ fn zirTypeofPeer(
extended: Zir.Inst.Extended.InstData,
inst: Zir.Inst.Index,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const extra = sema.code.extraData(Zir.Inst.TypeOfPeer, extended.operand);
const src = block.nodeOffset(extra.data.src_node);
const body = sema.code.bodySlice(extra.data.body_index, extra.data.body_len);
@@ -17249,9 +17013,6 @@ fn zirBoolBr(
inst: Zir.Inst.Index,
is_bool_or: bool,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const gpa = sema.gpa;
@@ -17418,9 +17179,6 @@ fn zirIsNonNull(
block: *Block,
inst: Zir.Inst.Index,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const operand = sema.resolveInst(inst_data.operand);
@@ -17433,9 +17191,6 @@ fn zirIsNonNullPtr(
block: *Block,
inst: Zir.Inst.Index,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
@@ -17472,9 +17227,6 @@ fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
}
fn zirIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const operand = sema.resolveInst(inst_data.operand);
@@ -17483,9 +17235,6 @@ fn zirIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
}
fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
@@ -17500,9 +17249,6 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
}
fn zirRetIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const operand = sema.resolveInst(inst_data.operand);
@@ -17514,9 +17260,6 @@ fn zirCondbr(
parent_block: *Block,
inst: Zir.Inst.Index,
) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -17866,9 +17609,6 @@ fn zirRetImplicit(
block: *Block,
inst: Zir.Inst.Index,
) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
@@ -17913,9 +17653,6 @@ fn zirRetImplicit(
}
fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const operand = sema.resolveInst(inst_data.operand);
const src = block.nodeOffset(inst_data.src_node);
@@ -17924,9 +17661,6 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
}
fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const ret_ptr = sema.resolveInst(inst_data.operand);
@@ -18071,9 +17805,6 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, extended: Zir.Inst.Ex
/// its state at the point `block` was reached (or, if `block` is `none`, the
/// point this function began execution).
fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_block: Zir.Inst.Ref, operand_zir: Zir.Inst.Ref) CompileError!void {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
@@ -18229,9 +17960,6 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool {
}
fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -18361,9 +18089,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
}
fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const ty_src = block.src(.{ .node_offset_init_ty = inst_data.src_node });
@@ -18382,9 +18107,6 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
}
fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_byref: bool) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
@@ -19622,9 +19344,6 @@ fn zirUnaryMath(
air_tag: Air.Inst.Tag,
comptime eval: fn (Value, Type, Allocator, Zcu.PerThread) Allocator.Error!Value,
) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const operand = sema.resolveInst(inst_data.operand);
const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
@@ -23441,9 +23160,6 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
}
fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
@@ -24489,9 +24205,6 @@ fn zirResume(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
}
fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const tracy = trace(@src());
- defer tracy.end();
-
const pt = sema.pt;
const zcu = pt.zcu;
const comp = zcu.comp;
diff --git a/src/Sema/type_resolution.zig b/src/Sema/type_resolution.zig
@@ -13,6 +13,7 @@ const LazySrcLoc = Zcu.LazySrcLoc;
const InternPool = @import("../InternPool.zig");
const Alignment = InternPool.Alignment;
const arith = @import("arith.zig");
+const trace = @import("../tracy.zig").trace;
pub const LayoutResolveReason = enum {
variable,
@@ -174,6 +175,11 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
const gpa = comp.gpa;
const ip = &zcu.intern_pool;
+ const tracy = trace(@src());
+ defer tracy.end();
+ tracy.addText(struct_ty.containerTypeName(ip).toSlice(ip));
+ tracy.addTextFmt("ip_index={d}", .{struct_ty.toIntern()});
+
assert(sema.owner.unwrap().type_layout == struct_ty.toIntern());
const struct_obj = ip.loadStructType(struct_ty.toIntern());
@@ -548,6 +554,11 @@ pub fn resolveStructDefaults(sema: *Sema, struct_ty: Type) CompileError!void {
const gpa = comp.gpa;
const ip = &zcu.intern_pool;
+ const tracy = trace(@src());
+ defer tracy.end();
+ tracy.addText(struct_ty.containerTypeName(ip).toSlice(ip));
+ tracy.addTextFmt("ip_index={d}", .{struct_ty.toIntern()});
+
assert(sema.owner.unwrap().struct_defaults == struct_ty.toIntern());
// We always depend on the layout of `struct_ty`. However, we don't actually need to resolve it
@@ -655,6 +666,11 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
const gpa = comp.gpa;
const ip = &zcu.intern_pool;
+ const tracy = trace(@src());
+ defer tracy.end();
+ tracy.addText(union_ty.containerTypeName(ip).toSlice(ip));
+ tracy.addTextFmt("ip_index={d}", .{union_ty.toIntern()});
+
assert(sema.owner.unwrap().type_layout == union_ty.toIntern());
const union_obj = ip.loadUnionType(union_ty.toIntern());
@@ -1134,6 +1150,11 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
const gpa = comp.gpa;
const ip = &zcu.intern_pool;
+ const tracy = trace(@src());
+ defer tracy.end();
+ tracy.addText(enum_ty.containerTypeName(ip).toSlice(ip));
+ tracy.addTextFmt("ip_index={d}", .{enum_ty.toIntern()});
+
assert(sema.owner.unwrap().type_layout == enum_ty.toIntern());
const enum_obj = ip.loadEnumType(enum_ty.toIntern());
diff --git a/src/Zcu.zig b/src/Zcu.zig
@@ -29,7 +29,7 @@ const Package = @import("Package.zig");
const link = @import("link.zig");
const Air = @import("Air.zig");
const Zir = std.zig.Zir;
-const trace = @import("tracy.zig").trace;
+const tracy = @import("tracy.zig");
const AstGen = std.zig.AstGen;
const Sema = @import("Sema.zig");
const target_util = @import("target.zig");
@@ -2811,6 +2811,7 @@ pub const CompileError = error{
pub fn init(zcu: *Zcu, gpa: Allocator, io: Io, thread_count: usize) !void {
try zcu.intern_pool.init(gpa, io, thread_count);
+ zcu.initTracyPlots();
}
pub fn deinit(zcu: *Zcu) void {
@@ -3161,12 +3162,15 @@ pub fn markDependeeOutdated(
try zcu.markTransitiveDependersPotentiallyOutdated(depender);
}
}
+
+ zcu.updateTracyOutdatedPlots();
}
pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(zcu.comp.io);
defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(zcu.comp.io);
- return markPoDependeeUpToDateInner(zcu, dependee);
+ try markPoDependeeUpToDateInner(zcu, dependee);
+ zcu.updateTracyOutdatedPlots();
}
/// Assumes that `zcu.outdated_lock` is already held exclusively.
fn markPoDependeeUpToDateInner(zcu: *Zcu, dependee: InternPool.Dependee) !void {
@@ -3304,6 +3308,7 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
// Everything is up-to-date. There could be lingering entries in `zcu.potentially_outdated`
// from a dependency loop on a previous update.
zcu.potentially_outdated.clearRetainingCapacity();
+ zcu.updateTracyOutdatedPlots();
log.debug("findOutdatedToAnalyze: all up-to-date", .{});
return null;
}
@@ -3337,6 +3342,7 @@ pub fn flushRetryableFailures(zcu: *Zcu) !void {
try zcu.markTransitiveDependersPotentiallyOutdated(depender);
}
zcu.retryable_failures.clearRetainingCapacity();
+ zcu.updateTracyOutdatedPlots();
}
pub fn mapOldZirToNew(
@@ -3580,6 +3586,7 @@ pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func: InternPool.Index) !void {
try zcu.outdated_ready.funcs.ensureUnusedCapacity(gpa, 1);
zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .func = func }), 0);
zcu.outdated_ready.funcs.putAssumeCapacityNoClobber(func, {});
+ zcu.updateTracyOutdatedPlots();
}
}
@@ -3598,6 +3605,7 @@ pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav: InternPool.Nav.Index) !void {
zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .nav_ty = nav }), 0);
zcu.outdated_ready.other.putAssumeCapacityNoClobber(.wrap(.{ .nav_val = nav }), {});
zcu.outdated_ready.other.putAssumeCapacityNoClobber(.wrap(.{ .nav_ty = nav }), {});
+ zcu.updateTracyOutdatedPlots();
}
}
@@ -3614,6 +3622,7 @@ pub fn queueComptimeUnitAnalysis(zcu: *Zcu, cu: InternPool.ComptimeUnit.Id) Allo
try zcu.outdated_ready.other.ensureUnusedCapacity(gpa, 1);
zcu.outdated.putAssumeCapacityNoClobber(unit, 0);
zcu.outdated_ready.other.putAssumeCapacityNoClobber(unit, {});
+ zcu.updateTracyOutdatedPlots();
}
/// If `unit` was marked as outdated or porentially outdated, clears that status and returns `true`.
@@ -3632,8 +3641,10 @@ pub fn clearOutdatedState(zcu: *Zcu, unit: AnalUnit) bool {
} else {
assert(!was_ready);
}
+ zcu.updateTracyOutdatedPlots();
return true;
} else if (zcu.potentially_outdated.swapRemove(unit)) {
+ zcu.updateTracyOutdatedPlots();
return true;
} else {
return false;
@@ -4164,6 +4175,9 @@ pub fn resolveReferences(zcu: *Zcu) Allocator.Error!*const std.AutoArrayHashMapU
return &zcu.resolved_references.?;
}
fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) {
+ const trace = tracy.trace(@src());
+ defer trace.end();
+
const gpa = zcu.gpa;
const comp = zcu.comp;
const ip = &zcu.intern_pool;
@@ -5265,6 +5279,7 @@ pub const CodegenTaskPool = struct {
mir.deinit(zcu);
}
assert(pool.available_air_bytes == max_air_bytes_in_flight);
+ zcu.updateTracyPlot("air_bytes_in_flight", 0);
}
pub fn start(
@@ -5298,6 +5313,12 @@ pub const CodegenTaskPool = struct {
}
pool.available_air_bytes -= effective_air_bytes;
+
+ zcu.updateTracyPlot("air_bytes_in_flight", @max(
+ max_air_bytes_in_flight - pool.available_air_bytes,
+ actual_air_bytes,
+ ));
+
break :index pool.free.pop().?;
};
@@ -5326,8 +5347,9 @@ pub const CodegenTaskPool = struct {
pub fn wait(
index: Index,
pool: *CodegenTaskPool,
- io: Io,
+ zcu: *const Zcu,
) PerThread.RunCodegenError!struct { InternPool.Index, codegen.AnyMir } {
+ const io = zcu.comp.io;
const func = pool.task_funcs[@intFromEnum(index)];
assert(func != .none);
const effective_air_bytes = pool.task_air_bytes[@intFromEnum(index)];
@@ -5343,6 +5365,7 @@ pub const CodegenTaskPool = struct {
pool.available_air_bytes += effective_air_bytes;
pool.free.appendAssumeCapacity(index);
pool.free_cond.signal(io);
+ zcu.updateTracyPlot("air_bytes_in_flight", max_air_bytes_in_flight - pool.available_air_bytes);
}
return .{ func, try result };
@@ -5376,3 +5399,29 @@ pub const CodegenTaskPool = struct {
return pt.runCodegen(func_index, air);
}
};
+
+fn initTracyPlots(zcu: *const Zcu) void {
+ if (zcu.comp.skip_linker_dependencies) return;
+
+ tracy.plotConfig("air_bytes_in_flight", .{ .format = .memory, .mode = .step });
+
+ tracy.plotConfig("outdated + potentially_outdated", .{ .format = .number, .mode = .step, .color = 0xFFFF00 });
+ tracy.plotConfig("outdated", .{ .format = .number, .mode = .step, .color = 0xFF0000 });
+ tracy.plotConfig("potentially_outdated", .{ .format = .number, .mode = .step, .color = 0xFF7700 });
+ tracy.plotConfig("outdated_ready", .{ .format = .number, .mode = .step, .color = 0x00FF00 });
+}
+
+/// Marked `inline` to prevent binary bloat from trivial generic instances, and to ensure there is
+/// minimal overhead to this call when Tracy is disabled, even in Debug builds.
+inline fn updateTracyPlot(zcu: *const Zcu, comptime name: [*:0]const u8, val: u64) void {
+ if (zcu.comp.skip_linker_dependencies) return;
+ tracy.plotInt(name, @intCast(val));
+}
+
+/// Assumes that `zcu.outdated_lock` is already held.
+fn updateTracyOutdatedPlots(zcu: *const Zcu) void {
+ zcu.updateTracyPlot("outdated + potentially_outdated", zcu.outdated.count() + zcu.potentially_outdated.count());
+ zcu.updateTracyPlot("outdated", zcu.outdated.count());
+ zcu.updateTracyPlot("potentially_outdated", zcu.potentially_outdated.count());
+ zcu.updateTracyPlot("outdated_ready", zcu.outdated_ready.funcs.count() + zcu.outdated_ready.other.count());
+}
diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig
@@ -313,18 +313,22 @@ pub fn update(
// `comptime` declarations, any declarations marked `export`, and `test` declarations in the
// main module if this is a test compilation---become referenced, and so will be picked up
// up by the main semantic analysis loop below.
- for (zcu.analysisRoots()) |analysis_root_mod| {
- const analysis_root_file = zcu.module_roots.get(analysis_root_mod).?.unwrap().?;
- try pt.ensureFilePopulated(analysis_root_file);
+ {
+ const tracy_trace = traceNamed(@src(), "populate_sema_roots");
+ defer tracy_trace.end();
+ for (zcu.analysisRoots()) |analysis_root_mod| {
+ const analysis_root_file = zcu.module_roots.get(analysis_root_mod).?.unwrap().?;
+ try pt.ensureFilePopulated(analysis_root_file);
+ }
}
+ const tracy_trace = traceNamed(@src(), "sema_loop");
+ defer tracy_trace.end();
+
// This is the main semantic analysis loop, which is essentially the main loop of the whole
// Zig compilation pipeline. It selects some `AnalUnit` which we know needs to be analyzed,
// and analyzes it, which may in turn discover more `AnalUnit`s which we need to analyze.
while (try zcu.findOutdatedToAnalyze()) |unit| {
- const tracy_trace = traceNamed(@src(), "analyze_outdated");
- defer tracy_trace.end();
-
const maybe_err: Zcu.SemaError!void = switch (unit.unwrap()) {
.@"comptime" => |cu| pt.ensureComptimeUnitUpToDate(cu),
.nav_ty => |nav| pt.ensureNavTypeUpToDate(nav, null),
@@ -823,6 +827,9 @@ fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void {
const gpa = comp.gpa;
const io = comp.io;
+ const tracy_trace = trace(@src());
+ defer tracy_trace.end();
+
// We need to visit every updated File for every TrackedInst in InternPool.
// This only includes Zig files; ZON files are omitted.
var updated_files: std.AutoArrayHashMapUnmanaged(Zcu.File.Index, UpdatedFile) = .empty;
@@ -1008,9 +1015,6 @@ fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void {
pub fn ensureFilePopulated(pt: Zcu.PerThread, file_index: Zcu.File.Index) (Allocator.Error || Io.Cancelable)!void {
dev.check(.sema);
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
const zcu = pt.zcu;
const comp = zcu.comp;
const io = comp.io;
@@ -1019,6 +1023,9 @@ pub fn ensureFilePopulated(pt: Zcu.PerThread, file_index: Zcu.File.Index) (Alloc
if (zcu.fileRootType(file_index) != .none) return; // already good
+ const tracy_trace = traceNamed(@src(), "create_file_struct");
+ defer tracy_trace.end();
+
if (zcu.comp.time_report) |*tr| tr.stats.n_imported_files += 1;
const file = zcu.fileByIndex(file_index);
@@ -1065,9 +1072,6 @@ pub fn ensureMemoizedStateUpToDate(
/// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
reason: ?*const Zcu.DependencyReason,
) Zcu.SemaError!void {
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
const zcu = pt.zcu;
const gpa = zcu.gpa;
@@ -1142,6 +1146,10 @@ fn analyzeMemoizedState(
log.debug("analyzeMemoizedState({t})", .{stage});
+ const tracy_trace = trace(@src());
+ defer tracy_trace.end();
+ tracy_trace.addText(@tagName(stage));
+
const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
try zcu.analysis_in_progress.putNoClobber(gpa, unit, reason);
@@ -1174,9 +1182,6 @@ fn analyzeMemoizedState(
/// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is
/// free to ignore this, since the error is already registered.
pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu.SemaError!void {
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
const zcu = pt.zcu;
const gpa = zcu.gpa;
@@ -1257,6 +1262,10 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
log.debug("analyzeComptimeUnit {f}", .{zcu.fmtAnalUnit(anal_unit)});
+ const tracy_trace = trace(@src());
+ defer tracy_trace.end();
+ tracy_trace.addTextFmt("cu_id={d}", .{cu_id});
+
const inst_resolved = comptime_unit.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
const file = zcu.fileByIndex(inst_resolved.file);
const zir = file.zir.?;
@@ -1333,9 +1342,6 @@ pub fn ensureTypeLayoutUpToDate(
/// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
reason: ?*const Zcu.DependencyReason,
) Zcu.SemaError!void {
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
const comp = zcu.comp;
@@ -1464,9 +1470,6 @@ pub fn ensureStructDefaultsUpToDate(
/// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
reason: ?*const Zcu.DependencyReason,
) Zcu.SemaError!void {
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
const comp = zcu.comp;
@@ -1572,9 +1575,6 @@ pub fn ensureNavValUpToDate(
/// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
reason: ?*const Zcu.DependencyReason,
) Zcu.SemaError!void {
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
const zcu = pt.zcu;
const gpa = zcu.gpa;
const ip = &zcu.intern_pool;
@@ -1677,6 +1677,11 @@ fn analyzeNavVal(
log.debug("analyzeNavVal {f}", .{zcu.fmtAnalUnit(anal_unit)});
+ const tracy_trace = trace(@src());
+ defer tracy_trace.end();
+ tracy_trace.addText(old_nav.fqn.toSlice(ip));
+ tracy_trace.addTextFmt("nav_id={d}", .{nav_id});
+
const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
const file = zcu.fileByIndex(inst_resolved.file);
const zir = file.zir.?;
@@ -1939,9 +1944,6 @@ pub fn ensureNavTypeUpToDate(
/// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
reason: ?*const Zcu.DependencyReason,
) Zcu.SemaError!void {
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
const zcu = pt.zcu;
const gpa = zcu.gpa;
const ip = &zcu.intern_pool;
@@ -2044,6 +2046,11 @@ fn analyzeNavType(
log.debug("analyzeNavType {f}", .{zcu.fmtAnalUnit(anal_unit)});
+ const tracy_trace = trace(@src());
+ defer tracy_trace.end();
+ tracy_trace.addText(old_nav.fqn.toSlice(ip));
+ tracy_trace.addTextFmt("nav_id={d}", .{nav_id});
+
const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
const file = zcu.fileByIndex(inst_resolved.file);
const zir = file.zir.?;
@@ -2183,9 +2190,6 @@ pub fn ensureFuncBodyUpToDate(
) Zcu.SemaError!void {
dev.check(.sema);
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
const zcu = pt.zcu;
const gpa = zcu.gpa;
const ip = &zcu.intern_pool;
@@ -2283,6 +2287,11 @@ fn analyzeFuncBody(
log.debug("analyzeFuncBody {f}", .{zcu.fmtAnalUnit(anal_unit)});
+ const tracy_trace = trace(@src());
+ defer tracy_trace.end();
+ tracy_trace.addText(ip.getNav(func.owner_nav).fqn.toSlice(ip));
+ tracy_trace.addTextFmt("func_ip_index={d}", .{func_index});
+
var air = try pt.analyzeFuncBodyInner(func_index, reason);
var air_owned = true;
defer if (air_owned) air.deinit(gpa);
@@ -2592,6 +2601,9 @@ fn computeAliveFiles(pt: Zcu.PerThread) Allocator.Error!bool {
const comp = zcu.comp;
const gpa = zcu.gpa;
+ const tracy_trace = trace(@src());
+ defer tracy_trace.end();
+
var any_fatal_files = false;
zcu.multi_module_err = null;
zcu.failed_imports.clearRetainingCapacity();
@@ -3028,14 +3040,16 @@ pub fn scanNamespace(
namespace_index: Zcu.Namespace.Index,
decls: []const Zir.Inst.Index,
) Allocator.Error!void {
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
const gpa = zcu.gpa;
const namespace = zcu.namespacePtr(namespace_index);
+ const tracy_trace = trace(@src());
+ defer tracy_trace.end();
+ tracy_trace.addText(Type.fromInterned(namespace.owner_type).containerTypeName(ip).toSlice(ip));
+ tracy_trace.addTextFmt("type_ip_index={d}", .{namespace.owner_type});
+
const tracked_unit = zcu.trackUnitSema(
Type.fromInterned(namespace.owner_type).containerTypeName(ip).toSlice(ip),
null,
@@ -3247,9 +3261,6 @@ fn analyzeFuncBodyInner(
func_index: InternPool.Index,
reason: ?*const Zcu.DependencyReason,
) Zcu.SemaError!Air {
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
const zcu = pt.zcu;
const comp = zcu.comp;
const gpa = comp.gpa;
@@ -4556,6 +4567,11 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
const codegen_prog_node = zcu.codegen_prog_node.start(fqn.toSlice(ip), 0);
defer codegen_prog_node.end();
+ const tracy_trace = trace(@src());
+ defer tracy_trace.end();
+ tracy_trace.addText(fqn.toSlice(ip));
+ tracy_trace.addTextFmt("func_ip_index={d}", .{func_index});
+
if (codegen.legalizeFeatures(pt, nav)) |features| {
try air.legalize(pt, features);
}
diff --git a/src/codegen.zig b/src/codegen.zig
@@ -186,6 +186,12 @@ pub fn emitFunction(
const zcu = pt.zcu;
const func = zcu.funcInfo(func_index);
const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
+
+ const tracy_trace = trace(@src());
+ defer tracy_trace.end();
+ tracy_trace.addText(zcu.intern_pool.getNav(func.owner_nav).fqn.toSlice(&zcu.intern_pool));
+ tracy_trace.addTextFmt("func_ip_index={d}", .{func_index});
+
switch (target_util.zigBackend(target, zcu.comp.config.use_llvm)) {
else => unreachable,
inline .stage2_aarch64,
@@ -236,6 +242,7 @@ pub fn generateLazySymbol(
) (CodeGenError || std.Io.Writer.Error)!void {
const tracy = trace(@src());
defer tracy.end();
+ tracy.addTextFmt("{t}, {f}", .{ lazy_sym.kind, Type.fromInterned(lazy_sym.ty).fmt(pt) });
const comp = bin_file.comp;
const zcu = pt.zcu;
diff --git a/src/link.zig b/src/link.zig
@@ -1205,6 +1205,7 @@ pub const File = struct {
pub fn loadInput(base: *File, input: Input) anyerror!void {
if (base.tag == .lld) return;
+ assert(!base.post_prelink);
switch (base.tag) {
inline .elf, .elf2, .wasm => |tag| {
dev.check(tag.devFeature());
@@ -1424,6 +1425,8 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
return;
};
+ assert(!base.post_prelink);
+
var timer = comp.startTimer();
defer if (timer.finish(io)) |ns| {
comp.mutex.lockUncancelable(io);
@@ -1573,7 +1576,7 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
},
.link_func => |codegen_task| nav: {
timer.pause(io);
- const func, var mir = codegen_task.wait(&zcu.codegen_task_pool, io) catch |err| switch (err) {
+ const func, var mir = codegen_task.wait(&zcu.codegen_task_pool, zcu) catch |err| switch (err) {
error.Canceled, error.AlreadyReported => {
comp.link_prog_node.completeOne();
return;
@@ -1850,6 +1853,9 @@ pub fn resolveInputs(
var ld_script_bytes: std.ArrayList(u8) = .empty;
defer ld_script_bytes.deinit(gpa);
+ var archive_dedup: ArchiveDedupMap = .empty;
+ defer archive_dedup.deinit(gpa);
+
var failed_libs: std.ArrayList(struct {
name: []const u8,
strategy: UnresolvedInput.SearchStrategy,
@@ -1889,6 +1895,7 @@ pub fn resolveInputs(
resolved_inputs,
&checked_paths,
&ld_script_bytes,
+ &archive_dedup,
lib_directory,
name_query,
target,
@@ -1916,6 +1923,7 @@ pub fn resolveInputs(
resolved_inputs,
&checked_paths,
&ld_script_bytes,
+ &archive_dedup,
lib_directory,
name_query,
target,
@@ -1944,6 +1952,7 @@ pub fn resolveInputs(
resolved_inputs,
&checked_paths,
&ld_script_bytes,
+ &archive_dedup,
lib_directory,
name_query,
target,
@@ -1963,6 +1972,7 @@ pub fn resolveInputs(
resolved_inputs,
&checked_paths,
&ld_script_bytes,
+ &archive_dedup,
lib_directory,
name_query,
target,
@@ -1994,6 +2004,7 @@ pub fn resolveInputs(
unresolved_inputs,
resolved_inputs,
&ld_script_bytes,
+ &archive_dedup,
target,
.{
.path = Path.initCwd(an.name),
@@ -2012,6 +2023,7 @@ pub fn resolveInputs(
unresolved_inputs,
resolved_inputs,
&ld_script_bytes,
+ &archive_dedup,
target,
.{
.path = .{
@@ -2040,6 +2052,7 @@ pub fn resolveInputs(
unresolved_inputs,
resolved_inputs,
&ld_script_bytes,
+ &archive_dedup,
target,
pq,
color,
@@ -2085,6 +2098,8 @@ fn resolveLibInput(
checked_paths: *std.ArrayList(u8),
/// Allocated via `gpa`.
ld_script_bytes: *std.ArrayList(u8),
+ /// Allocated via `gpa`.
+ archive_dedup: *ArchiveDedupMap,
lib_directory: Directory,
name_query: UnresolvedInput.NameQuery,
target: *const std.Target,
@@ -2092,6 +2107,7 @@ fn resolveLibInput(
color: std.zig.Color,
) Allocator.Error!ResolveLibInputResult {
try resolved_inputs.ensureUnusedCapacity(gpa, 1);
+ try archive_dedup.ensureUnusedCapacity(gpa, 1);
const lib_name = name_query.name;
@@ -2107,7 +2123,7 @@ fn resolveLibInput(
else => |e| fatal("unable to search for tbd library '{f}': {s}", .{ test_path, @errorName(e) }),
};
errdefer file.close(io);
- return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
+ return finishResolveLibInput(io, resolved_inputs, archive_dedup, test_path, file, link_mode, name_query.query);
}
{
@@ -2122,7 +2138,7 @@ fn resolveLibInput(
}),
};
try checked_paths.print(gpa, "\n {f}", .{test_path});
- switch (try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, target, .{
+ switch (try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, archive_dedup, target, .{
.path = test_path,
.query = name_query.query,
}, link_mode, color)) {
@@ -2146,7 +2162,7 @@ fn resolveLibInput(
}),
};
errdefer file.close(io);
- return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
+ return finishResolveLibInput(io, resolved_inputs, archive_dedup, test_path, file, link_mode, name_query.query);
}
// In the case of MinGW, the main check will be .lib but we also need to
@@ -2162,26 +2178,61 @@ fn resolveLibInput(
else => |e| fatal("unable to search for static library '{f}': {s}", .{ test_path, @errorName(e) }),
};
errdefer file.close(io);
- return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
+ return finishResolveLibInput(io, resolved_inputs, archive_dedup, test_path, file, link_mode, name_query.query);
}
return .no_match;
}
+/// Deduplicates static archive link inputs based on their path. This is done for efficiency, so
+/// that linker implementations do not need to open and scan the archive just to determine that they
+/// need not extract any objects. At the time of writing, it also helps avoid "multiple definitions
+/// of symbol" errors in incomplete linker implementations.
+///
+/// Key is index into `resolved_inputs` of an `Input.archive`.
+///
+/// Accessed through `ArchiveDedupAdapter`.
+///
+const ArchiveDedupMap = std.array_hash_map.Custom(u32, void, void, true);
+/// Adapter for accessing `ArchiveDedupMap` with an effective key type of `Path`.
+const ArchiveDedupAdapter = struct {
+ resolved_inputs: []const Input,
+ pub fn hash(ctx: ArchiveDedupAdapter, path: Path) u32 {
+ _ = ctx;
+ return Path.TableAdapter.hash(.{}, path);
+ }
+ pub fn eql(ctx: ArchiveDedupAdapter, a_path: Path, b_input_index: u32, _: usize) bool {
+ const b_path = ctx.resolved_inputs[b_input_index].archive.path;
+ return a_path.eql(b_path);
+ }
+};
+
fn finishResolveLibInput(
+ io: Io,
resolved_inputs: *std.ArrayList(Input),
+ archive_dedup: *ArchiveDedupMap,
path: Path,
file: Io.File,
link_mode: std.lang.LinkMode,
query: UnresolvedInput.Query,
) ResolveLibInputResult {
switch (link_mode) {
- .static => resolved_inputs.appendAssumeCapacity(.{ .archive = .{
- .path = path,
- .file = file,
- .must_link = query.must_link,
- .hidden = query.hidden,
- } }),
+ .static => {
+ const ctx: ArchiveDedupAdapter = .{ .resolved_inputs = resolved_inputs.items };
+ const gop = archive_dedup.getOrPutAssumeCapacityAdapted(path, ctx);
+ if (gop.found_existing) {
+ // Ignore duplicate archive input
+ file.close(io);
+ return .ok;
+ }
+ gop.key_ptr.* = @intCast(resolved_inputs.items.len);
+ resolved_inputs.appendAssumeCapacity(.{ .archive = .{
+ .path = path,
+ .file = file,
+ .must_link = query.must_link,
+ .hidden = query.hidden,
+ } });
+ },
.dynamic => resolved_inputs.appendAssumeCapacity(.{ .dso = .{
.path = path,
.file = file,
@@ -2203,13 +2254,15 @@ fn resolvePathInput(
resolved_inputs: *std.ArrayList(Input),
/// Allocated via `gpa`.
ld_script_bytes: *std.ArrayList(u8),
+ /// Allocated via `gpa`.
+ archive_dedup: *ArchiveDedupMap,
target: *const std.Target,
pq: UnresolvedInput.PathQuery,
color: std.zig.Color,
) Allocator.Error!?ResolveLibInputResult {
switch (Compilation.classifyFileExt(pq.path.sub_path)) {
- .static_library => return try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, target, pq, .static, color),
- .shared_library => return try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, target, pq, .dynamic, color),
+ .static_library => return try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, archive_dedup, target, pq, .static, color),
+ .shared_library => return try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, archive_dedup, target, pq, .dynamic, color),
.object => {
var file = pq.path.root_dir.handle.openFile(io, pq.path.sub_path, .{}) catch |err|
fatal("failed to open object {f}: {s}", .{ pq.path, @errorName(err) });
@@ -2246,12 +2299,15 @@ fn resolvePathInputLib(
resolved_inputs: *std.ArrayList(Input),
/// Allocated via `gpa`.
ld_script_bytes: *std.ArrayList(u8),
+ /// Allocated via `gpa`.
+ archive_dedup: *ArchiveDedupMap,
target: *const std.Target,
pq: UnresolvedInput.PathQuery,
link_mode: std.lang.LinkMode,
color: std.zig.Color,
) Allocator.Error!ResolveLibInputResult {
try resolved_inputs.ensureUnusedCapacity(gpa, 1);
+ try archive_dedup.ensureUnusedCapacity(gpa, 1);
const test_path: Path = pq.path;
// In the case of shared libraries, they might actually be "linker scripts"
@@ -2276,7 +2332,7 @@ fn resolvePathInputLib(
mem.startsWith(u8, buf, std.elf.ARMAG_THIN))
{
// Appears to be an ELF or archive file.
- return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
+ return finishResolveLibInput(io, resolved_inputs, archive_dedup, test_path, file, link_mode, pq.query);
}
const stat = file.stat(io) catch |err|
fatal("failed to stat {f}: {t}", .{ test_path, err });
@@ -2346,7 +2402,7 @@ fn resolvePathInputLib(
}),
};
errdefer file.close(io);
- return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
+ return finishResolveLibInput(io, resolved_inputs, archive_dedup, test_path, file, link_mode, pq.query);
}
pub fn openObject(io: Io, path: Path, must_link: bool, hidden: bool) !Input.Object {
diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig
@@ -14,6 +14,7 @@ const InternPool = @import("../InternPool.zig");
const link = @import("../link.zig");
const MappedFile = @import("MappedFile.zig");
const target_util = @import("../target.zig");
+const tracy = @import("../tracy.zig");
const Type = @import("../Type.zig");
const Value = @import("../Value.zig");
const Zcu = @import("../Zcu.zig");
@@ -127,7 +128,7 @@ section_by_name: std.array_hash_map.Auto(String(.shstrtab), void),
changed_symtab_index: std.array_hash_map.Auto(String(.strtab), void),
/// Counts how many relocations are currently in `.rela.dyn` which would require a `DT_TEXTREL`
/// entry in the `.dynamic` section. This allows adding `DT_TEXTREL` to the output `.dynamic`
-/// section in `flush` only when it is actually necessary. See also `nodeRequiresTextrel`.
+/// section in `flush` only when it is actually necessary. See also `nodeWantsDsoRelocation`.
textrel_count: u32,
const_prog_node: std.Progress.Node,
@@ -1127,8 +1128,10 @@ const SymbolReloc = struct {
}
if (reloc.rela_index.unwrap()) |rela_index| {
reloc.relaSection(elf).relaDeleteOne(elf, rela_index);
- if (elf.nodeRequiresTextrel(reloc.node)) {
- elf.textrel_count -= 1;
+ switch (elf.nodeWantsDsoRelocation(reloc.node)) {
+ .no => unreachable, // there *was* a dynamic relocation!
+ .yes => {},
+ .yes_textrel => elf.textrel_count -= 1,
}
}
if (reloc.type.dependsOnTlsSize()) {
@@ -1671,8 +1674,10 @@ fn setGlobalSymbolValue(
assert(reloc.target == Symbol.Id.global(global_name));
if (reloc.rela_index.unwrap()) |rela_index| {
reloc.relaSection(elf).relaDeleteOne(elf, rela_index);
- if (elf.nodeRequiresTextrel(reloc.node)) {
- elf.textrel_count -= 1;
+ switch (elf.nodeWantsDsoRelocation(reloc.node)) {
+ .no => unreachable, // there *was* a dynamic relocation!
+ .yes => {},
+ .yes_textrel => elf.textrel_count -= 1,
}
reloc.rela_index = .none;
}
@@ -1966,17 +1971,6 @@ const Symbol = struct {
fn ptr(si: Symbol.Index, elf: *Elf) *Symbol {
return &elf.symtab.items[@intFromEnum(si)];
}
-
- fn applyTargetRelocs(si: Symbol.Index, elf: *Elf) void {
- assert(elf.ehdrField(.type) != .REL);
- var ri = si.ptr(elf).first_target_reloc;
- while (ri != .none) {
- const reloc = ri.get(elf);
- assert(reloc.target.index(elf) == si);
- reloc.apply(elf);
- ri = reloc.next;
- }
- }
};
/// A `LocalIndex` is a raw index into the symtab like `Index`, but it guarantees that the
@@ -2063,7 +2057,7 @@ const Symbol = struct {
// Re-apply relocations targeting this symbol
if (elf.ehdrField(.type) != .REL) {
- sym_index.applyTargetRelocs(elf);
+ sym_id.applyTargetRelocs(elf);
}
// Update GOT entries targeting this symbol
@@ -2079,6 +2073,17 @@ const Symbol = struct {
}
}
+ fn applyTargetRelocs(sym_id: Symbol.Id, elf: *Elf) void {
+ assert(elf.ehdrField(.type) != .REL);
+ var ri = sym_id.index(elf).ptr(elf).first_target_reloc;
+ while (ri != .none) {
+ const reloc = ri.get(elf);
+ assert(reloc.target == sym_id);
+ reloc.apply(elf);
+ ri = reloc.next;
+ }
+ }
+
/// Returns `true` if the target of `s` has moved, meaning the symbol's value will change at
/// some point due to a call to `flushMoved`.
fn hasMoved(s: Symbol.Id, elf: *Elf) bool {
@@ -4441,7 +4446,7 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void {
elf.addPltEntry(name, global_ptr.dynsym_index);
// ...and therefore, we need to re-apply that symbol's relocations, as
// some might be targeting its PLT entry.
- global_ptr.symtab_index.applyTargetRelocs(elf);
+ Symbol.Id.global(name).applyTargetRelocs(elf);
}
}
}
@@ -5107,8 +5112,10 @@ fn addSymbolRelocAssumeCapacity(
} else elf.globalByName(name).?.dynsym_index,
};
- if (elf.nodeRequiresTextrel(node)) {
- elf.textrel_count += 1;
+ switch (elf.nodeWantsDsoRelocation(node)) {
+ .no => break :r .none,
+ .yes => {},
+ .yes_textrel => elf.textrel_count += 1,
}
// It currently looks like we need a runtime relocation for this.
@@ -5382,13 +5389,18 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void {
};
}
-/// Returns whether a `DT_TEXTREL` dynamic entry is needed to have a runtime relocation in `node`.
-fn nodeRequiresTextrel(elf: *Elf, node: MappedFile.Node.Index) bool {
+/// If `node` cannot contain runtime relocations, returns `.no`.
+///
+/// If `node` can contain runtime relocations, `returns `.yes_textrel` if such a relocation requires
+/// the presence of a `DT_TEXTREL` dynamic entry, or `.yes` otherwise.
+fn nodeWantsDsoRelocation(elf: *Elf, node: MappedFile.Node.Index) enum { yes, yes_textrel, no } {
const shndx = elf.getNodeShndx(node);
const shf: std.elf.SHF = switch (elf.shdrPtr(shndx)) {
inline else => |shdr| elf.targetLoad(&shdr.flags).shf,
};
- return shf.ALLOC and !shf.WRITE;
+ if (!shf.ALLOC) return .no;
+ if (!shf.WRITE) return .yes_textrel;
+ return .yes;
}
pub fn updateNav(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
@@ -5668,7 +5680,7 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool {
};
break :task;
}
- if (elf.changed_symtab_index.pop()) |kv| {
+ while (elf.changed_symtab_index.pop()) |kv| {
// We only need to do work in relocatables, because in ELF modules (non-relocatables)
// our `ElfN.Rela` entries use `.dynsym` indices rather than `.symtab` indices, and
// `.dynsym` indices are (at the time of writing) always immutable.
@@ -5865,6 +5877,8 @@ fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void {
}
fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void {
+ const trace = tracy.trace(@src());
+ defer trace.end();
switch (elf.getNode(ni)) {
.file => unreachable,
.ehdr, .shdr => try elf.flushFileOffset(ni),
@@ -6019,6 +6033,8 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void {
}
fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void {
+ const trace = tracy.trace(@src());
+ defer trace.end();
_, const size = ni.location(&elf.mf).resolve(&elf.mf);
switch (elf.getNode(ni)) {
.file => {},
@@ -6152,7 +6168,7 @@ fn flushMovedPltSection(elf: *Elf, which: enum { plt, plt_sec, got_plt }, old_ad
// specific tracking for PLT relocations---instead just re-apply all relocations
// targeting symbols with PLT entries.
for (elf.plt.keys()) |sym| {
- sym.index(elf).applyTargetRelocs(elf);
+ sym.applyTargetRelocs(elf);
}
// We also need to update all of the references from `.plt.sec` to `.got.plt`.
// However, if there's also a flush pending for `.got.plt`, don't bother doing
diff --git a/src/main.zig b/src/main.zig
@@ -218,8 +218,8 @@ pub fn main(init: std.process.Init.Minimal) anyerror!void {
var environ_map = init.environ.createMap(arena) catch |err| fatal("failed to parse environment: {t}", .{err});
if (tracy.enable_allocation) {
- var gpa_tracy = tracy.tracyAllocator(gpa);
- return mainArgs(gpa_tracy.allocator(), arena, io, args, &environ_map);
+ var tracy_allocator: tracy.Allocator = .{ .parent_allocator = gpa };
+ return mainArgs(tracy_allocator.interface(), arena, io, args, &environ_map);
}
if (native_os == .wasi) {
@@ -4239,7 +4239,6 @@ fn serve(
switch (hdr.tag) {
.exit => return cleanExit(io),
.update => {
- tracy.frameMark();
file_system_inputs.clearRetainingCapacity();
if (arg_mode == .translate_c) {
@@ -4296,7 +4295,6 @@ fn serve(
//);
},
.hot_update => {
- tracy.frameMark();
file_system_inputs.clearRetainingCapacity();
if (child_pid) |pid| {
try comp.hotCodeSwap(main_progress_node, pid);
diff --git a/src/tracy.zig b/src/tracy.zig
@@ -1,11 +1,13 @@
const std = @import("std");
+const assert = std.debug.assert;
+
const builtin = @import("builtin");
const build_options = @import("build_options");
pub const enable = if (builtin.is_test) false else build_options.enable_tracy;
pub const enable_allocation = enable and build_options.enable_tracy_allocation;
pub const enable_callstack = enable and build_options.enable_tracy_callstack;
-pub const callstack_depth = if (enable_callstack and build_options.tracy_callstack_depth > 0) build_options.tracy_callstack_depth else 10;
+pub const callstack_depth = if (enable_callstack) build_options.tracy_callstack_depth else 0;
const ___tracy_c_zone_context = extern struct {
id: u32,
@@ -19,6 +21,12 @@ const ___tracy_c_zone_context = extern struct {
___tracy_emit_zone_text(self, text.ptr, text.len);
}
+ pub inline fn addTextFmt(self: @This(), comptime fmt: []const u8, args: anytype) void {
+ var buf: [512]u8 = undefined;
+ const slice = std.fmt.bufPrint(&buf, fmt, args) catch &buf;
+ self.addText(slice);
+ }
+
pub inline fn setName(self: @This(), name: []const u8) void {
___tracy_emit_zone_name(self, name.ptr, name.len);
}
@@ -42,6 +50,12 @@ pub const Ctx = if (enable) ___tracy_c_zone_context else struct {
_ = text;
}
+ pub inline fn addTextFmt(self: @This(), comptime fmt: []const u8, args: anytype) void {
+ _ = self;
+ _ = fmt;
+ _ = args;
+ }
+
pub inline fn setName(self: @This(), name: []const u8) void {
_ = self;
_ = name;
@@ -71,11 +85,7 @@ pub inline fn trace(comptime src: std.lang.SourceLocation) Ctx {
};
};
- if (enable_callstack) {
- return ___tracy_emit_zone_begin_callstack(&global.loc, callstack_depth, 1);
- } else {
- return ___tracy_emit_zone_begin(&global.loc, 1);
- }
+ return ___tracy_emit_zone_begin_callstack(&global.loc, callstack_depth, 1);
}
pub inline fn traceNamed(comptime src: std.lang.SourceLocation, comptime name: [:0]const u8) Ctx {
@@ -91,11 +101,7 @@ pub inline fn traceNamed(comptime src: std.lang.SourceLocation, comptime name: [
};
};
- if (enable_callstack) {
- return ___tracy_emit_zone_begin_callstack(&global.loc, callstack_depth, 1);
- } else {
- return ___tracy_emit_zone_begin(&global.loc, 1);
- }
+ return ___tracy_emit_zone_begin_callstack(&global.loc, callstack_depth, 1);
}
pub inline fn fiberEnter(fiber: [*:0]const u8) void {
@@ -108,102 +114,93 @@ pub inline fn fiberLeave() void {
___tracy_fiber_leave();
}
-pub fn tracyAllocator(allocator: std.mem.Allocator) TracyAllocator(null) {
- return TracyAllocator(null).init(allocator);
+pub inline fn plotConfig(comptime name: [*:0]const u8, config: PlotConfig) void {
+ if (!enable) return;
+ ___tracy_emit_plot_config(
+ name,
+ config.format,
+ config.mode,
+ @intFromBool(config.fill),
+ // https://github.com/wolfpld/tracy/issues/1232
+ @byteSwap(config.color),
+ );
}
-pub fn TracyAllocator(comptime name: ?[:0]const u8) type {
- return struct {
- parent_allocator: std.mem.Allocator,
+pub inline fn plotInt(comptime name: [*:0]const u8, val: i64) void {
+ if (!enable) return;
+ ___tracy_emit_plot_int(name, val);
+}
- const Self = @This();
+pub const Allocator = struct {
+ parent_allocator: std.mem.Allocator,
- pub fn init(parent_allocator: std.mem.Allocator) Self {
- return .{
- .parent_allocator = parent_allocator,
- };
- }
+ comptime {
+ assert(enable); // used `tracy.Allocator` with Tracy disabled
+ }
- pub fn allocator(self: *Self) std.mem.Allocator {
- return .{
- .ptr = self,
- .vtable = &.{
- .alloc = allocFn,
- .resize = resizeFn,
- .remap = remapFn,
- .free = freeFn,
- },
- };
- }
+ pub fn interface(self: *Allocator) std.mem.Allocator {
+ return .{
+ .ptr = self,
+ .vtable = &.{
+ .alloc = allocFn,
+ .resize = resizeFn,
+ .remap = remapFn,
+ .free = freeFn,
+ },
+ };
+ }
- fn allocFn(ptr: *anyopaque, len: usize, alignment: std.mem.Alignment, ret_addr: usize) ?[*]u8 {
- const self: *Self = @ptrCast(@alignCast(ptr));
- const result = self.parent_allocator.rawAlloc(len, alignment, ret_addr);
- if (result) |memory| {
- if (len != 0) {
- if (name) |n| {
- allocNamed(memory, len, n);
- } else {
- alloc(memory, len);
- }
- }
- } else {
- messageColor("allocation failed", 0xFF0000);
- }
- return result;
+ fn allocFn(ptr: *anyopaque, len: usize, alignment: std.mem.Alignment, ret_addr: usize) ?[*]u8 {
+ const self: *Allocator = @ptrCast(@alignCast(ptr));
+ assert(len > 0);
+ if (self.parent_allocator.rawAlloc(len, alignment, ret_addr)) |memory| {
+ ___tracy_emit_memory_alloc_callstack(memory, len, callstack_depth, 0);
+ return memory;
+ } else {
+ messageColor("allocation failed", 0xFF0000);
+ return null;
}
+ }
- fn resizeFn(ptr: *anyopaque, memory: []u8, alignment: std.mem.Alignment, new_len: usize, ret_addr: usize) bool {
- const self: *Self = @ptrCast(@alignCast(ptr));
- if (self.parent_allocator.rawResize(memory, alignment, new_len, ret_addr)) {
- if (name) |n| {
- freeNamed(memory.ptr, n);
- allocNamed(memory.ptr, new_len, n);
- } else {
- free(memory.ptr);
- alloc(memory.ptr, new_len);
- }
-
- return true;
- }
-
- // during normal operation the compiler hits this case thousands of times due to this
- // emitting messages for it is both slow and causes clutter
+ fn resizeFn(ptr: *anyopaque, memory: []u8, alignment: std.mem.Alignment, new_len: usize, ret_addr: usize) bool {
+ const self: *Allocator = @ptrCast(@alignCast(ptr));
+ assert(memory.len > 0);
+ assert(new_len > 0);
+ // We need to mark the free before calling the implementation to avoid a race.
+ ___tracy_emit_memory_free_callstack(memory.ptr, callstack_depth, 0);
+ if (self.parent_allocator.rawResize(memory, alignment, new_len, ret_addr)) {
+ ___tracy_emit_memory_alloc_callstack(memory.ptr, new_len, callstack_depth, 0);
+ return true;
+ } else {
+ // No `messageColor` call here because this case is hit frequently in normal operation.
+ ___tracy_emit_memory_alloc_callstack(memory.ptr, memory.len, callstack_depth, 0);
return false;
}
+ }
- fn remapFn(ptr: *anyopaque, memory: []u8, alignment: std.mem.Alignment, new_len: usize, ret_addr: usize) ?[*]u8 {
- const self: *Self = @ptrCast(@alignCast(ptr));
- if (self.parent_allocator.rawRemap(memory, alignment, new_len, ret_addr)) |new_memory| {
- if (name) |n| {
- freeNamed(memory.ptr, n);
- allocNamed(new_memory, new_len, n);
- } else {
- free(memory.ptr);
- alloc(new_memory, new_len);
- }
- return new_memory;
- } else {
- messageColor("reallocation failed", 0xFF0000);
- return null;
- }
+ fn remapFn(ptr: *anyopaque, memory: []u8, alignment: std.mem.Alignment, new_len: usize, ret_addr: usize) ?[*]u8 {
+ const self: *Allocator = @ptrCast(@alignCast(ptr));
+ assert(memory.len > 0);
+ assert(new_len > 0);
+ // We need to mark the free before calling the implementation to avoid a race.
+ ___tracy_emit_memory_free_callstack(memory.ptr, callstack_depth, 0);
+ if (self.parent_allocator.rawRemap(memory, alignment, new_len, ret_addr)) |new_memory| {
+ ___tracy_emit_memory_alloc_callstack(new_memory, new_len, callstack_depth, 0);
+ return new_memory;
+ } else {
+ // No `messageColor` call here because this case is hit frequently in normal operation.
+ ___tracy_emit_memory_alloc_callstack(memory.ptr, memory.len, callstack_depth, 0);
+ return null;
}
+ }
- fn freeFn(ptr: *anyopaque, memory: []u8, alignment: std.mem.Alignment, ret_addr: usize) void {
- const self: *Self = @ptrCast(@alignCast(ptr));
- self.parent_allocator.rawFree(memory, alignment, ret_addr);
- // this condition is to handle free being called on an empty slice that was never even allocated
- // example case: `std.process.getSelfExeSharedLibPaths` can return `&[_][:0]u8{}`
- if (memory.len != 0) {
- if (name) |n| {
- freeNamed(memory.ptr, n);
- } else {
- free(memory.ptr);
- }
- }
- }
- };
-}
+ fn freeFn(ptr: *anyopaque, memory: []u8, alignment: std.mem.Alignment, ret_addr: usize) void {
+ const self: *Allocator = @ptrCast(@alignCast(ptr));
+ assert(memory.len > 0);
+ ___tracy_emit_memory_free_callstack(memory.ptr, callstack_depth, 0);
+ self.parent_allocator.rawFree(memory, alignment, ret_addr);
+ }
+};
// This function only accepts comptime-known strings, see `messageCopy` for runtime strings
pub inline fn message(comptime msg: [:0]const u8) void {
@@ -213,7 +210,7 @@ pub inline fn message(comptime msg: [:0]const u8) void {
// This function only accepts comptime-known strings, see `messageColorCopy` for runtime strings
pub inline fn messageColor(comptime msg: [:0]const u8, color: u24) void {
if (!enable) return;
- ___tracy_emit_logStringL(.Info, color, if (enable_callstack) callstack_depth else 0, msg.ptr);
+ ___tracy_emit_logStringL(.Info, color, callstack_depth, msg.ptr);
}
pub inline fn messageCopy(msg: []const u8) void {
@@ -222,84 +219,29 @@ pub inline fn messageCopy(msg: []const u8) void {
pub inline fn messageColorCopy(msg: []const u8, color: u24) void {
if (!enable) return;
- ___tracy_emit_logString(.Info, color, if (enable_callstack) callstack_depth else 0, msg.len, msg.ptr);
+ ___tracy_emit_logString(.Info, color, callstack_depth, msg.len, msg.ptr);
}
-pub inline fn frameMark() void {
- if (!enable) return;
- ___tracy_emit_frame_mark(null);
+/// Used to store strings which Tracy requires to have stable pointers for the program's entire
+/// lifetime. All such strings will be leaked.
+///
+/// The `enable` check ensures that this is not referenced if Tracy is disabled.
+var tracy_arena: std.heap.ArenaAllocator = if (enable) .init(std.heap.page_allocator);
+
+pub inline fn namedFrame(name: []const u8) Frame {
+ if (!enable) return .{ .name = {} };
+ const stable_name = tracy_arena.allocator().dupeSentinel(u8, name, 0) catch @panic("tracy arena OOM");
+ ___tracy_emit_frame_mark_start(stable_name.ptr);
+ return .{ .name = stable_name.ptr };
}
-pub inline fn frameMarkNamed(comptime name: [:0]const u8) void {
- if (!enable) return;
- ___tracy_emit_frame_mark(name.ptr);
-}
-
-pub inline fn namedFrame(comptime name: [:0]const u8) Frame(name) {
- frameMarkStart(name);
- return .{};
-}
-
-pub fn Frame(comptime name: [:0]const u8) type {
- return struct {
- pub fn end(_: @This()) void {
- frameMarkEnd(name);
- }
- };
-}
-
-inline fn frameMarkStart(comptime name: [:0]const u8) void {
- if (!enable) return;
- ___tracy_emit_frame_mark_start(name.ptr);
-}
-
-inline fn frameMarkEnd(comptime name: [:0]const u8) void {
- if (!enable) return;
- ___tracy_emit_frame_mark_end(name.ptr);
-}
-
-extern fn ___tracy_emit_frame_mark_start(name: [*:0]const u8) void;
-extern fn ___tracy_emit_frame_mark_end(name: [*:0]const u8) void;
-
-inline fn alloc(ptr: [*]u8, len: usize) void {
- if (!enable) return;
-
- if (enable_callstack) {
- ___tracy_emit_memory_alloc_callstack(ptr, len, callstack_depth, 0);
- } else {
- ___tracy_emit_memory_alloc(ptr, len, 0);
- }
-}
-
-inline fn allocNamed(ptr: [*]u8, len: usize, comptime name: [:0]const u8) void {
- if (!enable) return;
-
- if (enable_callstack) {
- ___tracy_emit_memory_alloc_callstack_named(ptr, len, callstack_depth, 0, name.ptr);
- } else {
- ___tracy_emit_memory_alloc_named(ptr, len, 0, name.ptr);
- }
-}
-
-inline fn free(ptr: [*]u8) void {
- if (!enable) return;
-
- if (enable_callstack) {
- ___tracy_emit_memory_free_callstack(ptr, callstack_depth, 0);
- } else {
- ___tracy_emit_memory_free(ptr, 0);
+pub const Frame = struct {
+ name: if (enable) [*:0]const u8 else void,
+ pub inline fn end(frame: Frame) void {
+ if (!enable) return;
+ ___tracy_emit_frame_mark_end(frame.name);
}
-}
-
-inline fn freeNamed(ptr: [*]u8, comptime name: [:0]const u8) void {
- if (!enable) return;
-
- if (enable_callstack) {
- ___tracy_emit_memory_free_callstack_named(ptr, callstack_depth, 0, name.ptr);
- } else {
- ___tracy_emit_memory_free_named(ptr, 0, name.ptr);
- }
-}
+};
pub const MessageSeverity = enum(i8) {
Trace, // Broadly track variable states and events in the software program.
@@ -310,24 +252,39 @@ pub const MessageSeverity = enum(i8) {
Fatal, // Describes a critical event that will lead to a software failure/crash.
};
-extern fn ___tracy_emit_zone_begin(srcloc: *const ___tracy_source_location_data, active: i32) ___tracy_c_zone_context;
+pub const PlotConfig = struct {
+ format: Format,
+ mode: Mode,
+ fill: bool = true,
+ color: u24 = 0,
+
+ pub const Format = enum(i32) {
+ number = 0,
+ memory = 1,
+ percentage = 2,
+ watt = 3,
+ };
+
+ pub const Mode = enum(i32) {
+ line = 0,
+ step = 1,
+ };
+};
+
+extern fn ___tracy_emit_frame_mark_start(name: [*:0]const u8) void;
+extern fn ___tracy_emit_frame_mark_end(name: [*:0]const u8) void;
extern fn ___tracy_emit_zone_begin_callstack(srcloc: *const ___tracy_source_location_data, depth: i32, active: i32) ___tracy_c_zone_context;
extern fn ___tracy_emit_zone_text(ctx: ___tracy_c_zone_context, txt: [*]const u8, size: usize) void;
extern fn ___tracy_emit_zone_name(ctx: ___tracy_c_zone_context, txt: [*]const u8, size: usize) void;
extern fn ___tracy_emit_zone_color(ctx: ___tracy_c_zone_context, color: u32) void;
extern fn ___tracy_emit_zone_value(ctx: ___tracy_c_zone_context, value: u64) void;
extern fn ___tracy_emit_zone_end(ctx: ___tracy_c_zone_context) void;
-extern fn ___tracy_emit_memory_alloc(ptr: *const anyopaque, size: usize, secure: i32) void;
extern fn ___tracy_emit_memory_alloc_callstack(ptr: *const anyopaque, size: usize, depth: i32, secure: i32) void;
-extern fn ___tracy_emit_memory_free(ptr: *const anyopaque, secure: i32) void;
extern fn ___tracy_emit_memory_free_callstack(ptr: *const anyopaque, depth: i32, secure: i32) void;
-extern fn ___tracy_emit_memory_alloc_named(ptr: *const anyopaque, size: usize, secure: i32, name: [*:0]const u8) void;
-extern fn ___tracy_emit_memory_alloc_callstack_named(ptr: *const anyopaque, size: usize, depth: i32, secure: i32, name: [*:0]const u8) void;
-extern fn ___tracy_emit_memory_free_named(ptr: *const anyopaque, secure: i32, name: [*:0]const u8) void;
-extern fn ___tracy_emit_memory_free_callstack_named(ptr: *const anyopaque, depth: i32, secure: i32, name: [*:0]const u8) void;
extern fn ___tracy_emit_logString(severity: MessageSeverity, color: i32, callstack_depth: i32, size: usize, txt: [*]const u8) void;
extern fn ___tracy_emit_logStringL(severity: MessageSeverity, color: i32, callstack_depth: i32, txt: [*:0]const u8) void;
-extern fn ___tracy_emit_frame_mark(name: ?[*:0]const u8) void;
+extern fn ___tracy_emit_plot_int(name: [*:0]const u8, val: i64) void;
+extern fn ___tracy_emit_plot_config(name: [*:0]const u8, format: PlotConfig.Format, mode: PlotConfig.Mode, fill: i32, color: u32) void;
extern fn ___tracy_fiber_enter(fiber: [*:0]const u8) void;
extern fn ___tracy_fiber_leave() void;