authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2023-07-25 23:29:55-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-26 02:20:29-07:00
loga8a2f2b58bd6f876258bb01b370a66c31d82f330
tree436b43c06157e63d7f5b3cec31a932fd566a0b78
parent6cee98eb3074fcb99297f23f30e3a230a14e8db7

Add --verbose-generic-instances to provide visibility on the number of generic function instantiations


3 files changed, 75 insertions(+), 0 deletions(-)

src/Compilation.zig+13
......@@ -89,6 +89,7 @@ clang_preprocessor_mode: ClangPreprocessorMode,
8989verbose_cc: bool,
9090verbose_air: bool,
9191verbose_intern_pool: bool,
92verbose_generic_instances: bool,
9293verbose_llvm_ir: ?[]const u8,
9394verbose_llvm_bc: ?[]const u8,
9495verbose_cimport: bool,
......@@ -596,6 +597,7 @@ pub const InitOptions = struct {
596597 verbose_link: bool = false,
597598 verbose_air: bool = false,
598599 verbose_intern_pool: bool = false,
600 verbose_generic_instances: bool = false,
599601 verbose_llvm_ir: ?[]const u8 = null,
600602 verbose_llvm_bc: ?[]const u8 = null,
601603 verbose_cimport: bool = false,
......@@ -1606,6 +1608,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
16061608 .verbose_cc = options.verbose_cc,
16071609 .verbose_air = options.verbose_air,
16081610 .verbose_intern_pool = options.verbose_intern_pool,
1611 .verbose_generic_instances = options.verbose_generic_instances,
16091612 .verbose_llvm_ir = options.verbose_llvm_ir,
16101613 .verbose_llvm_bc = options.verbose_llvm_bc,
16111614 .verbose_cimport = options.verbose_cimport,
......@@ -2071,6 +2074,14 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
20712074 module.intern_pool.dump();
20722075 }
20732076
2077 if (builtin.mode == .Debug and comp.verbose_generic_instances) {
2078 std.debug.print("generic instances for '{s}:0x{x}':\n", .{
2079 comp.bin_file.options.root_name,
2080 @as(usize, @intFromPtr(module)),
2081 });
2082 module.intern_pool.dumpGenericInstances(comp.gpa);
2083 }
2084
20742085 if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) {
20752086 // The `test_functions` decl has been intentionally postponed until now,
20762087 // at which point we must populate it with the list of test functions that
......@@ -5491,6 +5502,7 @@ fn buildOutputFromZig(
54915502 .verbose_link = comp.bin_file.options.verbose_link,
54925503 .verbose_air = comp.verbose_air,
54935504 .verbose_intern_pool = comp.verbose_intern_pool,
5505 .verbose_generic_instances = comp.verbose_intern_pool,
54945506 .verbose_llvm_ir = comp.verbose_llvm_ir,
54955507 .verbose_llvm_bc = comp.verbose_llvm_bc,
54965508 .verbose_cimport = comp.verbose_cimport,
......@@ -5570,6 +5582,7 @@ pub fn build_crt_file(
55705582 .verbose_link = comp.bin_file.options.verbose_link,
55715583 .verbose_air = comp.verbose_air,
55725584 .verbose_intern_pool = comp.verbose_intern_pool,
5585 .verbose_generic_instances = comp.verbose_generic_instances,
55735586 .verbose_llvm_ir = comp.verbose_llvm_ir,
55745587 .verbose_llvm_bc = comp.verbose_llvm_bc,
55755588 .verbose_cimport = comp.verbose_cimport,
src/InternPool.zig+57
......@@ -6266,6 +6266,59 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
62666266 try bw.flush();
62676267}
62686268
6269pub fn dumpGenericInstances(ip: *const InternPool, allocator: Allocator) void {
6270 ip.dumpGenericInstancesFallible(allocator) catch return;
6271}
6272
6273pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) anyerror!void {
6274 var arena_allocator = std.heap.ArenaAllocator.init(allocator);
6275 defer arena_allocator.deinit();
6276 const arena = arena_allocator.allocator();
6277
6278 var bw = std.io.bufferedWriter(std.io.getStdErr().writer());
6279 const w = bw.writer();
6280
6281 var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .{};
6282 const datas = ip.items.items(.data);
6283 for (ip.items.items(.tag), 0..) |tag, i| {
6284 if (tag != .func_instance) continue;
6285 const info = ip.extraData(Tag.FuncInstance, datas[i]);
6286
6287 const gop = try instances.getOrPut(arena, info.generic_owner);
6288 if (!gop.found_existing) gop.value_ptr.* = .{};
6289
6290 try gop.value_ptr.append(arena, @enumFromInt(i));
6291 }
6292
6293 const SortContext = struct {
6294 values: []std.ArrayListUnmanaged(Index),
6295 pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool {
6296 return ctx.values[a_index].items.len > ctx.values[b_index].items.len;
6297 }
6298 };
6299
6300 instances.sort(SortContext{ .values = instances.values() });
6301 var it = instances.iterator();
6302 while (it.next()) |entry| {
6303 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));
6304 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });
6305 for (entry.value_ptr.items) |index| {
6306 const func = ip.extraFuncInstance(datas[@intFromEnum(index)]);
6307 const owner_decl = ip.declPtrConst(func.owner_decl);
6308 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});
6309 for (func.comptime_args.get(ip)) |arg| {
6310 if (arg != .none) {
6311 const key = ip.indexToKey(arg);
6312 try w.print(" {} ", .{key});
6313 }
6314 }
6315 try w.writeAll(")\n");
6316 }
6317 }
6318
6319 try bw.flush();
6320}
6321
62696322pub fn structPtr(ip: *InternPool, index: Module.Struct.Index) *Module.Struct {
62706323 return ip.allocated_structs.at(@intFromEnum(index));
62716324}
......@@ -6290,6 +6343,10 @@ pub fn declPtr(ip: *InternPool, index: Module.Decl.Index) *Module.Decl {
62906343 return ip.allocated_decls.at(@intFromEnum(index));
62916344}
62926345
6346pub fn declPtrConst(ip: *const InternPool, index: Module.Decl.Index) *const Module.Decl {
6347 return ip.allocated_decls.at(@intFromEnum(index));
6348}
6349
62936350pub fn namespacePtr(ip: *InternPool, index: Module.Namespace.Index) *Module.Namespace {
62946351 return ip.allocated_namespaces.at(@intFromEnum(index));
62956352}
src/main.zig+5
......@@ -571,6 +571,7 @@ const usage_build_generic =
571571 \\ --verbose-cc Display C compiler invocations
572572 \\ --verbose-air Enable compiler debug output for Zig AIR
573573 \\ --verbose-intern-pool Enable compiler debug output for InternPool
574 \\ --verbose-generic-instances Enable compiler debug output for generic instance generation
574575 \\ --verbose-llvm-ir[=path] Enable compiler debug output for unoptimized LLVM IR
575576 \\ --verbose-llvm-bc=[path] Enable compiler debug output for unoptimized LLVM BC
576577 \\ --verbose-cimport Enable compiler debug output for C imports
......@@ -741,6 +742,7 @@ fn buildOutputType(
741742 var verbose_cc = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_CC");
742743 var verbose_air = false;
743744 var verbose_intern_pool = false;
745 var verbose_generic_instances = false;
744746 var verbose_llvm_ir: ?[]const u8 = null;
745747 var verbose_llvm_bc: ?[]const u8 = null;
746748 var verbose_cimport = false;
......@@ -1469,6 +1471,8 @@ fn buildOutputType(
14691471 verbose_air = true;
14701472 } else if (mem.eql(u8, arg, "--verbose-intern-pool")) {
14711473 verbose_intern_pool = true;
1474 } else if (mem.eql(u8, arg, "--verbose-generic-instances")) {
1475 verbose_generic_instances = true;
14721476 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
14731477 verbose_llvm_ir = "-";
14741478 } else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) {
......@@ -3166,6 +3170,7 @@ fn buildOutputType(
31663170 .verbose_link = verbose_link,
31673171 .verbose_air = verbose_air,
31683172 .verbose_intern_pool = verbose_intern_pool,
3173 .verbose_generic_instances = verbose_generic_instances,
31693174 .verbose_llvm_ir = verbose_llvm_ir,
31703175 .verbose_llvm_bc = verbose_llvm_bc,
31713176 .verbose_cimport = verbose_cimport,