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,...@@ -89,6 +89,7 @@ clang_preprocessor_mode: ClangPreprocessorMode,
89verbose_cc: bool,89verbose_cc: bool,
90verbose_air: bool,90verbose_air: bool,
91verbose_intern_pool: bool,91verbose_intern_pool: bool,
92verbose_generic_instances: bool,
92verbose_llvm_ir: ?[]const u8,93verbose_llvm_ir: ?[]const u8,
93verbose_llvm_bc: ?[]const u8,94verbose_llvm_bc: ?[]const u8,
94verbose_cimport: bool,95verbose_cimport: bool,
...@@ -596,6 +597,7 @@ pub const InitOptions = struct {...@@ -596,6 +597,7 @@ pub const InitOptions = struct {
596 verbose_link: bool = false,597 verbose_link: bool = false,
597 verbose_air: bool = false,598 verbose_air: bool = false,
598 verbose_intern_pool: bool = false,599 verbose_intern_pool: bool = false,
600 verbose_generic_instances: bool = false,
599 verbose_llvm_ir: ?[]const u8 = null,601 verbose_llvm_ir: ?[]const u8 = null,
600 verbose_llvm_bc: ?[]const u8 = null,602 verbose_llvm_bc: ?[]const u8 = null,
601 verbose_cimport: bool = false,603 verbose_cimport: bool = false,
...@@ -1606,6 +1608,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1606,6 +1608,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1606 .verbose_cc = options.verbose_cc,1608 .verbose_cc = options.verbose_cc,
1607 .verbose_air = options.verbose_air,1609 .verbose_air = options.verbose_air,
1608 .verbose_intern_pool = options.verbose_intern_pool,1610 .verbose_intern_pool = options.verbose_intern_pool,
1611 .verbose_generic_instances = options.verbose_generic_instances,
1609 .verbose_llvm_ir = options.verbose_llvm_ir,1612 .verbose_llvm_ir = options.verbose_llvm_ir,
1610 .verbose_llvm_bc = options.verbose_llvm_bc,1613 .verbose_llvm_bc = options.verbose_llvm_bc,
1611 .verbose_cimport = options.verbose_cimport,1614 .verbose_cimport = options.verbose_cimport,
...@@ -2071,6 +2074,14 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void...@@ -2071,6 +2074,14 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
2071 module.intern_pool.dump();2074 module.intern_pool.dump();
2072 }2075 }
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
2074 if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) {2085 if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) {
2075 // The `test_functions` decl has been intentionally postponed until now,2086 // The `test_functions` decl has been intentionally postponed until now,
2076 // at which point we must populate it with the list of test functions that2087 // at which point we must populate it with the list of test functions that
...@@ -5491,6 +5502,7 @@ fn buildOutputFromZig(...@@ -5491,6 +5502,7 @@ fn buildOutputFromZig(
5491 .verbose_link = comp.bin_file.options.verbose_link,5502 .verbose_link = comp.bin_file.options.verbose_link,
5492 .verbose_air = comp.verbose_air,5503 .verbose_air = comp.verbose_air,
5493 .verbose_intern_pool = comp.verbose_intern_pool,5504 .verbose_intern_pool = comp.verbose_intern_pool,
5505 .verbose_generic_instances = comp.verbose_intern_pool,
5494 .verbose_llvm_ir = comp.verbose_llvm_ir,5506 .verbose_llvm_ir = comp.verbose_llvm_ir,
5495 .verbose_llvm_bc = comp.verbose_llvm_bc,5507 .verbose_llvm_bc = comp.verbose_llvm_bc,
5496 .verbose_cimport = comp.verbose_cimport,5508 .verbose_cimport = comp.verbose_cimport,
...@@ -5570,6 +5582,7 @@ pub fn build_crt_file(...@@ -5570,6 +5582,7 @@ pub fn build_crt_file(
5570 .verbose_link = comp.bin_file.options.verbose_link,5582 .verbose_link = comp.bin_file.options.verbose_link,
5571 .verbose_air = comp.verbose_air,5583 .verbose_air = comp.verbose_air,
5572 .verbose_intern_pool = comp.verbose_intern_pool,5584 .verbose_intern_pool = comp.verbose_intern_pool,
5585 .verbose_generic_instances = comp.verbose_generic_instances,
5573 .verbose_llvm_ir = comp.verbose_llvm_ir,5586 .verbose_llvm_ir = comp.verbose_llvm_ir,
5574 .verbose_llvm_bc = comp.verbose_llvm_bc,5587 .verbose_llvm_bc = comp.verbose_llvm_bc,
5575 .verbose_cimport = comp.verbose_cimport,5588 .verbose_cimport = comp.verbose_cimport,
src/InternPool.zig+57
...@@ -6266,6 +6266,59 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {...@@ -6266,6 +6266,59 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
6266 try bw.flush();6266 try bw.flush();
6267}6267}
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
6269pub fn structPtr(ip: *InternPool, index: Module.Struct.Index) *Module.Struct {6322pub fn structPtr(ip: *InternPool, index: Module.Struct.Index) *Module.Struct {
6270 return ip.allocated_structs.at(@intFromEnum(index));6323 return ip.allocated_structs.at(@intFromEnum(index));
6271}6324}
...@@ -6290,6 +6343,10 @@ pub fn declPtr(ip: *InternPool, index: Module.Decl.Index) *Module.Decl {...@@ -6290,6 +6343,10 @@ pub fn declPtr(ip: *InternPool, index: Module.Decl.Index) *Module.Decl {
6290 return ip.allocated_decls.at(@intFromEnum(index));6343 return ip.allocated_decls.at(@intFromEnum(index));
6291}6344}
62926345
6346pub fn declPtrConst(ip: *const InternPool, index: Module.Decl.Index) *const Module.Decl {
6347 return ip.allocated_decls.at(@intFromEnum(index));
6348}
6349
6293pub fn namespacePtr(ip: *InternPool, index: Module.Namespace.Index) *Module.Namespace {6350pub fn namespacePtr(ip: *InternPool, index: Module.Namespace.Index) *Module.Namespace {
6294 return ip.allocated_namespaces.at(@intFromEnum(index));6351 return ip.allocated_namespaces.at(@intFromEnum(index));
6295}6352}
src/main.zig+5
...@@ -571,6 +571,7 @@ const usage_build_generic =...@@ -571,6 +571,7 @@ const usage_build_generic =
571 \\ --verbose-cc Display C compiler invocations571 \\ --verbose-cc Display C compiler invocations
572 \\ --verbose-air Enable compiler debug output for Zig AIR572 \\ --verbose-air Enable compiler debug output for Zig AIR
573 \\ --verbose-intern-pool Enable compiler debug output for InternPool573 \\ --verbose-intern-pool Enable compiler debug output for InternPool
574 \\ --verbose-generic-instances Enable compiler debug output for generic instance generation
574 \\ --verbose-llvm-ir[=path] Enable compiler debug output for unoptimized LLVM IR575 \\ --verbose-llvm-ir[=path] Enable compiler debug output for unoptimized LLVM IR
575 \\ --verbose-llvm-bc=[path] Enable compiler debug output for unoptimized LLVM BC576 \\ --verbose-llvm-bc=[path] Enable compiler debug output for unoptimized LLVM BC
576 \\ --verbose-cimport Enable compiler debug output for C imports577 \\ --verbose-cimport Enable compiler debug output for C imports
...@@ -741,6 +742,7 @@ fn buildOutputType(...@@ -741,6 +742,7 @@ fn buildOutputType(
741 var verbose_cc = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_CC");742 var verbose_cc = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_CC");
742 var verbose_air = false;743 var verbose_air = false;
743 var verbose_intern_pool = false;744 var verbose_intern_pool = false;
745 var verbose_generic_instances = false;
744 var verbose_llvm_ir: ?[]const u8 = null;746 var verbose_llvm_ir: ?[]const u8 = null;
745 var verbose_llvm_bc: ?[]const u8 = null;747 var verbose_llvm_bc: ?[]const u8 = null;
746 var verbose_cimport = false;748 var verbose_cimport = false;
...@@ -1469,6 +1471,8 @@ fn buildOutputType(...@@ -1469,6 +1471,8 @@ fn buildOutputType(
1469 verbose_air = true;1471 verbose_air = true;
1470 } else if (mem.eql(u8, arg, "--verbose-intern-pool")) {1472 } else if (mem.eql(u8, arg, "--verbose-intern-pool")) {
1471 verbose_intern_pool = true;1473 verbose_intern_pool = true;
1474 } else if (mem.eql(u8, arg, "--verbose-generic-instances")) {
1475 verbose_generic_instances = true;
1472 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {1476 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
1473 verbose_llvm_ir = "-";1477 verbose_llvm_ir = "-";
1474 } else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) {1478 } else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) {
...@@ -3166,6 +3170,7 @@ fn buildOutputType(...@@ -3166,6 +3170,7 @@ fn buildOutputType(
3166 .verbose_link = verbose_link,3170 .verbose_link = verbose_link,
3167 .verbose_air = verbose_air,3171 .verbose_air = verbose_air,
3168 .verbose_intern_pool = verbose_intern_pool,3172 .verbose_intern_pool = verbose_intern_pool,
3173 .verbose_generic_instances = verbose_generic_instances,
3169 .verbose_llvm_ir = verbose_llvm_ir,3174 .verbose_llvm_ir = verbose_llvm_ir,
3170 .verbose_llvm_bc = verbose_llvm_bc,3175 .verbose_llvm_bc = verbose_llvm_bc,
3171 .verbose_cimport = verbose_cimport,3176 .verbose_cimport = verbose_cimport,