diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Compilation.zig | 13 | ||||
| -rw-r--r-- | src/InternPool.zig | 57 | ||||
| -rw-r--r-- | src/main.zig | 5 |
3 files changed, 75 insertions, 0 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index fe3682ac96..4019e43c8d 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -89,6 +89,7 @@ clang_preprocessor_mode: ClangPreprocessorMode, verbose_cc: bool, verbose_air: bool, verbose_intern_pool: bool, +verbose_generic_instances: bool, verbose_llvm_ir: ?[]const u8, verbose_llvm_bc: ?[]const u8, verbose_cimport: bool, @@ -596,6 +597,7 @@ pub const InitOptions = struct { verbose_link: bool = false, verbose_air: bool = false, verbose_intern_pool: bool = false, + verbose_generic_instances: bool = false, verbose_llvm_ir: ?[]const u8 = null, verbose_llvm_bc: ?[]const u8 = null, verbose_cimport: bool = false, @@ -1606,6 +1608,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .verbose_cc = options.verbose_cc, .verbose_air = options.verbose_air, .verbose_intern_pool = options.verbose_intern_pool, + .verbose_generic_instances = options.verbose_generic_instances, .verbose_llvm_ir = options.verbose_llvm_ir, .verbose_llvm_bc = options.verbose_llvm_bc, .verbose_cimport = options.verbose_cimport, @@ -2071,6 +2074,14 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void module.intern_pool.dump(); } + if (builtin.mode == .Debug and comp.verbose_generic_instances) { + std.debug.print("generic instances for '{s}:0x{x}':\n", .{ + comp.bin_file.options.root_name, + @as(usize, @intFromPtr(module)), + }); + module.intern_pool.dumpGenericInstances(comp.gpa); + } + if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) { // The `test_functions` decl has been intentionally postponed until now, // at which point we must populate it with the list of test functions that @@ -5491,6 +5502,7 @@ fn buildOutputFromZig( .verbose_link = comp.bin_file.options.verbose_link, .verbose_air = comp.verbose_air, .verbose_intern_pool = comp.verbose_intern_pool, + .verbose_generic_instances = comp.verbose_intern_pool, .verbose_llvm_ir = comp.verbose_llvm_ir, .verbose_llvm_bc = comp.verbose_llvm_bc, .verbose_cimport = comp.verbose_cimport, @@ -5570,6 +5582,7 @@ pub fn build_crt_file( .verbose_link = comp.bin_file.options.verbose_link, .verbose_air = comp.verbose_air, .verbose_intern_pool = comp.verbose_intern_pool, + .verbose_generic_instances = comp.verbose_generic_instances, .verbose_llvm_ir = comp.verbose_llvm_ir, .verbose_llvm_bc = comp.verbose_llvm_bc, .verbose_cimport = comp.verbose_cimport, diff --git a/src/InternPool.zig b/src/InternPool.zig index 0c01c9988c..178bc6870c 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -6266,6 +6266,59 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void { try bw.flush(); } +pub fn dumpGenericInstances(ip: *const InternPool, allocator: Allocator) void { + ip.dumpGenericInstancesFallible(allocator) catch return; +} + +pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) anyerror!void { + var arena_allocator = std.heap.ArenaAllocator.init(allocator); + defer arena_allocator.deinit(); + const arena = arena_allocator.allocator(); + + var bw = std.io.bufferedWriter(std.io.getStdErr().writer()); + const w = bw.writer(); + + var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .{}; + const datas = ip.items.items(.data); + for (ip.items.items(.tag), 0..) |tag, i| { + if (tag != .func_instance) continue; + const info = ip.extraData(Tag.FuncInstance, datas[i]); + + const gop = try instances.getOrPut(arena, info.generic_owner); + if (!gop.found_existing) gop.value_ptr.* = .{}; + + try gop.value_ptr.append(arena, @enumFromInt(i)); + } + + const SortContext = struct { + values: []std.ArrayListUnmanaged(Index), + pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool { + return ctx.values[a_index].items.len > ctx.values[b_index].items.len; + } + }; + + instances.sort(SortContext{ .values = instances.values() }); + var it = instances.iterator(); + while (it.next()) |entry| { + const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*)); + try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len }); + for (entry.value_ptr.items) |index| { + const func = ip.extraFuncInstance(datas[@intFromEnum(index)]); + const owner_decl = ip.declPtrConst(func.owner_decl); + try w.print(" {}: (", .{owner_decl.name.fmt(ip)}); + for (func.comptime_args.get(ip)) |arg| { + if (arg != .none) { + const key = ip.indexToKey(arg); + try w.print(" {} ", .{key}); + } + } + try w.writeAll(")\n"); + } + } + + try bw.flush(); +} + pub fn structPtr(ip: *InternPool, index: Module.Struct.Index) *Module.Struct { return ip.allocated_structs.at(@intFromEnum(index)); } @@ -6290,6 +6343,10 @@ pub fn declPtr(ip: *InternPool, index: Module.Decl.Index) *Module.Decl { return ip.allocated_decls.at(@intFromEnum(index)); } +pub fn declPtrConst(ip: *const InternPool, index: Module.Decl.Index) *const Module.Decl { + return ip.allocated_decls.at(@intFromEnum(index)); +} + pub fn namespacePtr(ip: *InternPool, index: Module.Namespace.Index) *Module.Namespace { return ip.allocated_namespaces.at(@intFromEnum(index)); } diff --git a/src/main.zig b/src/main.zig index dcc64f085c..39a7adc424 100644 --- a/src/main.zig +++ b/src/main.zig @@ -571,6 +571,7 @@ const usage_build_generic = \\ --verbose-cc Display C compiler invocations \\ --verbose-air Enable compiler debug output for Zig AIR \\ --verbose-intern-pool Enable compiler debug output for InternPool + \\ --verbose-generic-instances Enable compiler debug output for generic instance generation \\ --verbose-llvm-ir[=path] Enable compiler debug output for unoptimized LLVM IR \\ --verbose-llvm-bc=[path] Enable compiler debug output for unoptimized LLVM BC \\ --verbose-cimport Enable compiler debug output for C imports @@ -741,6 +742,7 @@ fn buildOutputType( var verbose_cc = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_CC"); var verbose_air = false; var verbose_intern_pool = false; + var verbose_generic_instances = false; var verbose_llvm_ir: ?[]const u8 = null; var verbose_llvm_bc: ?[]const u8 = null; var verbose_cimport = false; @@ -1469,6 +1471,8 @@ fn buildOutputType( verbose_air = true; } else if (mem.eql(u8, arg, "--verbose-intern-pool")) { verbose_intern_pool = true; + } else if (mem.eql(u8, arg, "--verbose-generic-instances")) { + verbose_generic_instances = true; } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) { verbose_llvm_ir = "-"; } else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) { @@ -3166,6 +3170,7 @@ fn buildOutputType( .verbose_link = verbose_link, .verbose_air = verbose_air, .verbose_intern_pool = verbose_intern_pool, + .verbose_generic_instances = verbose_generic_instances, .verbose_llvm_ir = verbose_llvm_ir, .verbose_llvm_bc = verbose_llvm_bc, .verbose_cimport = verbose_cimport, |
