authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-03 21:56:21-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-03 21:56:21-07:00
logedfede575c3113c3611b14a868e8d1e956ca9ef5
tree76e5e77bccee9103c2fe659191ebe438818e4cf6
parenta33efc74ed303517aa458109acfcd5c40dc97703

self-hosted: add build option for log scopes

Now you can enable a set of log scopes by passing -Dlog=<scope>

4 files changed, 59 insertions(+), 49 deletions(-)

build.zig+3
...@@ -77,6 +77,9 @@ pub fn build(b: *Builder) !void {...@@ -77,6 +77,9 @@ pub fn build(b: *Builder) !void {
77 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse false;77 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse false;
78 if (link_libc) exe.linkLibC();78 if (link_libc) exe.linkLibC();
7979
80 const log_scopes = b.option([]const []const u8, "log", "Which log scopes to enable") orelse &[0][]const u8{};
81
82 exe.addBuildOption([]const []const u8, "log_scopes", log_scopes);
80 exe.addBuildOption(bool, "enable_tracy", tracy != null);83 exe.addBuildOption(bool, "enable_tracy", tracy != null);
81 if (tracy) |tracy_path| {84 if (tracy) |tracy_path| {
82 const client_cpp = fs.path.join(85 const client_cpp = fs.path.join(
lib/std/build.zig+31-19
...@@ -430,9 +430,9 @@ pub const Builder = struct {...@@ -430,9 +430,9 @@ pub const Builder = struct {
430 const entry = self.user_input_options.getEntry(name) orelse return null;430 const entry = self.user_input_options.getEntry(name) orelse return null;
431 entry.value.used = true;431 entry.value.used = true;
432 switch (type_id) {432 switch (type_id) {
433 TypeId.Bool => switch (entry.value.value) {433 .Bool => switch (entry.value.value) {
434 UserValue.Flag => return true,434 .Flag => return true,
435 UserValue.Scalar => |s| {435 .Scalar => |s| {
436 if (mem.eql(u8, s, "true")) {436 if (mem.eql(u8, s, "true")) {
437 return true;437 return true;
438 } else if (mem.eql(u8, s, "false")) {438 } else if (mem.eql(u8, s, "false")) {
...@@ -443,21 +443,21 @@ pub const Builder = struct {...@@ -443,21 +443,21 @@ pub const Builder = struct {
443 return null;443 return null;
444 }444 }
445 },445 },
446 UserValue.List => {446 .List => {
447 warn("Expected -D{} to be a boolean, but received a list.\n", .{name});447 warn("Expected -D{} to be a boolean, but received a list.\n", .{name});
448 self.markInvalidUserInput();448 self.markInvalidUserInput();
449 return null;449 return null;
450 },450 },
451 },451 },
452 TypeId.Int => panic("TODO integer options to build script", .{}),452 .Int => panic("TODO integer options to build script", .{}),
453 TypeId.Float => panic("TODO float options to build script", .{}),453 .Float => panic("TODO float options to build script", .{}),
454 TypeId.Enum => switch (entry.value.value) {454 .Enum => switch (entry.value.value) {
455 UserValue.Flag => {455 .Flag => {
456 warn("Expected -D{} to be a string, but received a boolean.\n", .{name});456 warn("Expected -D{} to be a string, but received a boolean.\n", .{name});
457 self.markInvalidUserInput();457 self.markInvalidUserInput();
458 return null;458 return null;
459 },459 },
460 UserValue.Scalar => |s| {460 .Scalar => |s| {
461 if (std.meta.stringToEnum(T, s)) |enum_lit| {461 if (std.meta.stringToEnum(T, s)) |enum_lit| {
462 return enum_lit;462 return enum_lit;
463 } else {463 } else {
...@@ -466,33 +466,35 @@ pub const Builder = struct {...@@ -466,33 +466,35 @@ pub const Builder = struct {
466 return null;466 return null;
467 }467 }
468 },468 },
469 UserValue.List => {469 .List => {
470 warn("Expected -D{} to be a string, but received a list.\n", .{name});470 warn("Expected -D{} to be a string, but received a list.\n", .{name});
471 self.markInvalidUserInput();471 self.markInvalidUserInput();
472 return null;472 return null;
473 },473 },
474 },474 },
475 TypeId.String => switch (entry.value.value) {475 .String => switch (entry.value.value) {
476 UserValue.Flag => {476 .Flag => {
477 warn("Expected -D{} to be a string, but received a boolean.\n", .{name});477 warn("Expected -D{} to be a string, but received a boolean.\n", .{name});
478 self.markInvalidUserInput();478 self.markInvalidUserInput();
479 return null;479 return null;
480 },480 },
481 UserValue.List => {481 .List => {
482 warn("Expected -D{} to be a string, but received a list.\n", .{name});482 warn("Expected -D{} to be a string, but received a list.\n", .{name});
483 self.markInvalidUserInput();483 self.markInvalidUserInput();
484 return null;484 return null;
485 },485 },
486 UserValue.Scalar => |s| return s,486 .Scalar => |s| return s,
487 },487 },
488 TypeId.List => switch (entry.value.value) {488 .List => switch (entry.value.value) {
489 UserValue.Flag => {489 .Flag => {
490 warn("Expected -D{} to be a list, but received a boolean.\n", .{name});490 warn("Expected -D{} to be a list, but received a boolean.\n", .{name});
491 self.markInvalidUserInput();491 self.markInvalidUserInput();
492 return null;492 return null;
493 },493 },
494 UserValue.Scalar => |s| return &[_][]const u8{s},494 .Scalar => |s| {
495 UserValue.List => |lst| return lst.span(),495 return self.allocator.dupe([]const u8, &[_][]const u8{s}) catch unreachable;
496 },
497 .List => |lst| return lst.span(),
496 },498 },
497 }499 }
498 }500 }
...@@ -1706,9 +1708,19 @@ pub const LibExeObjStep = struct {...@@ -1706,9 +1708,19 @@ pub const LibExeObjStep = struct {
17061708
1707 pub fn addBuildOption(self: *LibExeObjStep, comptime T: type, name: []const u8, value: T) void {1709 pub fn addBuildOption(self: *LibExeObjStep, comptime T: type, name: []const u8, value: T) void {
1708 const out = self.build_options_contents.outStream();1710 const out = self.build_options_contents.outStream();
1711 if (T == []const []const u8) {
1712 out.print("pub const {}: []const []const u8 = &[_][]const u8{{\n", .{name}) catch unreachable;
1713 for (value) |slice| {
1714 out.writeAll(" ") catch unreachable;
1715 std.zig.renderStringLiteral(slice, out) catch unreachable;
1716 out.writeAll(",\n") catch unreachable;
1717 }
1718 out.writeAll("};\n") catch unreachable;
1719 return;
1720 }
1709 switch (@typeInfo(T)) {1721 switch (@typeInfo(T)) {
1710 .Enum => |enum_info| {1722 .Enum => |enum_info| {
1711 out.print("const {} = enum {{\n", .{@typeName(T)}) catch unreachable;1723 out.print("pub const {} = enum {{\n", .{@typeName(T)}) catch unreachable;
1712 inline for (enum_info.fields) |field| {1724 inline for (enum_info.fields) |field| {
1713 out.print(" {},\n", .{field.name}) catch unreachable;1725 out.print(" {},\n", .{field.name}) catch unreachable;
1714 }1726 }
src-self-hosted/Module.zig+16-17
...@@ -6,6 +6,7 @@ const Value = @import("value.zig").Value;...@@ -6,6 +6,7 @@ const Value = @import("value.zig").Value;
6const Type = @import("type.zig").Type;6const Type = @import("type.zig").Type;
7const TypedValue = @import("TypedValue.zig");7const TypedValue = @import("TypedValue.zig");
8const assert = std.debug.assert;8const assert = std.debug.assert;
9const log = std.log;
9const BigIntConst = std.math.big.int.Const;10const BigIntConst = std.math.big.int.Const;
10const BigIntMutable = std.math.big.int.Mutable;11const BigIntMutable = std.math.big.int.Mutable;
11const Target = std.Target;12const Target = std.Target;
...@@ -235,7 +236,7 @@ pub const Decl = struct {...@@ -235,7 +236,7 @@ pub const Decl = struct {
235236
236 pub fn dump(self: *Decl) void {237 pub fn dump(self: *Decl) void {
237 const loc = std.zig.findLineColumn(self.scope.source.bytes, self.src);238 const loc = std.zig.findLineColumn(self.scope.source.bytes, self.src);
238 std.debug.warn("{}:{}:{} name={} status={}", .{239 std.debug.print("{}:{}:{} name={} status={}", .{
239 self.scope.sub_file_path,240 self.scope.sub_file_path,
240 loc.line + 1,241 loc.line + 1,
241 loc.column + 1,242 loc.column + 1,
...@@ -243,9 +244,9 @@ pub const Decl = struct {...@@ -243,9 +244,9 @@ pub const Decl = struct {
243 @tagName(self.analysis),244 @tagName(self.analysis),
244 });245 });
245 if (self.typedValueManaged()) |tvm| {246 if (self.typedValueManaged()) |tvm| {
246 std.debug.warn(" ty={} val={}", .{ tvm.typed_value.ty, tvm.typed_value.val });247 std.debug.print(" ty={} val={}", .{ tvm.typed_value.ty, tvm.typed_value.val });
247 }248 }
248 std.debug.warn("\n", .{});249 std.debug.print("\n", .{});
249 }250 }
250251
251 pub fn typedValueManaged(self: *Decl) ?*TypedValue.Managed {252 pub fn typedValueManaged(self: *Decl) ?*TypedValue.Managed {
...@@ -544,7 +545,7 @@ pub const Scope = struct {...@@ -544,7 +545,7 @@ pub const Scope = struct {
544545
545 pub fn dumpSrc(self: *File, src: usize) void {546 pub fn dumpSrc(self: *File, src: usize) void {
546 const loc = std.zig.findLineColumn(self.source.bytes, src);547 const loc = std.zig.findLineColumn(self.source.bytes, src);
547 std.debug.warn("{}:{}:{}\n", .{ self.sub_file_path, loc.line + 1, loc.column + 1 });548 std.debug.print("{}:{}:{}\n", .{ self.sub_file_path, loc.line + 1, loc.column + 1 });
548 }549 }
549550
550 pub fn getSource(self: *File, module: *Module) ![:0]const u8 {551 pub fn getSource(self: *File, module: *Module) ![:0]const u8 {
...@@ -646,7 +647,7 @@ pub const Scope = struct {...@@ -646,7 +647,7 @@ pub const Scope = struct {
646647
647 pub fn dumpSrc(self: *ZIRModule, src: usize) void {648 pub fn dumpSrc(self: *ZIRModule, src: usize) void {
648 const loc = std.zig.findLineColumn(self.source.bytes, src);649 const loc = std.zig.findLineColumn(self.source.bytes, src);
649 std.debug.warn("{}:{}:{}\n", .{ self.sub_file_path, loc.line + 1, loc.column + 1 });650 std.debug.print("{}:{}:{}\n", .{ self.sub_file_path, loc.line + 1, loc.column + 1 });
650 }651 }
651652
652 pub fn getSource(self: *ZIRModule, module: *Module) ![:0]const u8 {653 pub fn getSource(self: *ZIRModule, module: *Module) ![:0]const u8 {
...@@ -946,7 +947,6 @@ pub fn update(self: *Module) !void {...@@ -946,7 +947,6 @@ pub fn update(self: *Module) !void {
946 }947 }
947948
948 self.link_error_flags = self.bin_file.errorFlags();949 self.link_error_flags = self.bin_file.errorFlags();
949 std.log.debug(.module, "link_error_flags: {}\n", .{self.link_error_flags});
950950
951 // If there are any errors, we anticipate the source files being loaded951 // If there are any errors, we anticipate the source files being loaded
952 // to report error messages. Otherwise we unload all source files to save memory.952 // to report error messages. Otherwise we unload all source files to save memory.
...@@ -1109,7 +1109,7 @@ pub fn ensureDeclAnalyzed(self: *Module, decl: *Decl) InnerError!void {...@@ -1109,7 +1109,7 @@ pub fn ensureDeclAnalyzed(self: *Module, decl: *Decl) InnerError!void {
1109 assert(decl.analysis == .complete);1109 assert(decl.analysis == .complete);
1110 return;1110 return;
1111 }1111 }
1112 //std.debug.warn("re-analyzing {}\n", .{decl.name});1112 log.debug(.module, "re-analyzing {}\n", .{decl.name});
11131113
1114 // The exports this Decl performs will be re-discovered, so we remove them here1114 // The exports this Decl performs will be re-discovered, so we remove them here
1115 // prior to re-analysis.1115 // prior to re-analysis.
...@@ -1546,7 +1546,7 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void {...@@ -1546,7 +1546,7 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void {
1546 // Handle explicitly deleted decls from the source code. Not to be confused1546 // Handle explicitly deleted decls from the source code. Not to be confused
1547 // with when we delete decls because they are no longer referenced.1547 // with when we delete decls because they are no longer referenced.
1548 for (deleted_decls.items()) |entry| {1548 for (deleted_decls.items()) |entry| {
1549 //std.debug.warn("noticed '{}' deleted from source\n", .{entry.key.name});1549 log.debug(.module, "noticed '{}' deleted from source\n", .{entry.key.name});
1550 try self.deleteDecl(entry.key);1550 try self.deleteDecl(entry.key);
1551 }1551 }
1552}1552}
...@@ -1575,7 +1575,6 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {...@@ -1575,7 +1575,6 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
1575 const name_hash = root_scope.fullyQualifiedNameHash(src_decl.name);1575 const name_hash = root_scope.fullyQualifiedNameHash(src_decl.name);
1576 if (self.decl_table.get(name_hash)) |decl| {1576 if (self.decl_table.get(name_hash)) |decl| {
1577 deleted_decls.removeAssertDiscard(decl);1577 deleted_decls.removeAssertDiscard(decl);
1578 //std.debug.warn("'{}' contents: '{}'\n", .{ src_decl.name, src_decl.contents });
1579 if (!srcHashEql(src_decl.contents_hash, decl.contents_hash)) {1578 if (!srcHashEql(src_decl.contents_hash, decl.contents_hash)) {
1580 try self.markOutdatedDecl(decl);1579 try self.markOutdatedDecl(decl);
1581 decl.contents_hash = src_decl.contents_hash;1580 decl.contents_hash = src_decl.contents_hash;
...@@ -1600,7 +1599,7 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {...@@ -1600,7 +1599,7 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
1600 // Handle explicitly deleted decls from the source code. Not to be confused1599 // Handle explicitly deleted decls from the source code. Not to be confused
1601 // with when we delete decls because they are no longer referenced.1600 // with when we delete decls because they are no longer referenced.
1602 for (deleted_decls.items()) |entry| {1601 for (deleted_decls.items()) |entry| {
1603 //std.debug.warn("noticed '{}' deleted from source\n", .{entry.key.name});1602 log.debug(.module, "noticed '{}' deleted from source\n", .{entry.key.name});
1604 try self.deleteDecl(entry.key);1603 try self.deleteDecl(entry.key);
1605 }1604 }
1606}1605}
...@@ -1612,7 +1611,7 @@ fn deleteDecl(self: *Module, decl: *Decl) !void {...@@ -1612,7 +1611,7 @@ fn deleteDecl(self: *Module, decl: *Decl) !void {
1612 // not be present in the set, and this does nothing.1611 // not be present in the set, and this does nothing.
1613 decl.scope.removeDecl(decl);1612 decl.scope.removeDecl(decl);
16141613
1615 //std.debug.warn("deleting decl '{}'\n", .{decl.name});1614 log.debug(.module, "deleting decl '{}'\n", .{decl.name});
1616 const name_hash = decl.fullyQualifiedNameHash();1615 const name_hash = decl.fullyQualifiedNameHash();
1617 self.decl_table.removeAssertDiscard(name_hash);1616 self.decl_table.removeAssertDiscard(name_hash);
1618 // Remove itself from its dependencies, because we are about to destroy the decl pointer.1617 // Remove itself from its dependencies, because we are about to destroy the decl pointer.
...@@ -1698,17 +1697,17 @@ fn analyzeFnBody(self: *Module, decl: *Decl, func: *Fn) !void {...@@ -1698,17 +1697,17 @@ fn analyzeFnBody(self: *Module, decl: *Decl, func: *Fn) !void {
1698 const fn_zir = func.analysis.queued;1697 const fn_zir = func.analysis.queued;
1699 defer fn_zir.arena.promote(self.gpa).deinit();1698 defer fn_zir.arena.promote(self.gpa).deinit();
1700 func.analysis = .{ .in_progress = {} };1699 func.analysis = .{ .in_progress = {} };
1701 //std.debug.warn("set {} to in_progress\n", .{decl.name});1700 log.debug(.module, "set {} to in_progress\n", .{decl.name});
17021701
1703 try zir_sema.analyzeBody(self, &inner_block.base, fn_zir.body);1702 try zir_sema.analyzeBody(self, &inner_block.base, fn_zir.body);
17041703
1705 const instructions = try arena.allocator.dupe(*Inst, inner_block.instructions.items);1704 const instructions = try arena.allocator.dupe(*Inst, inner_block.instructions.items);
1706 func.analysis = .{ .success = .{ .instructions = instructions } };1705 func.analysis = .{ .success = .{ .instructions = instructions } };
1707 //std.debug.warn("set {} to success\n", .{decl.name});1706 log.debug(.module, "set {} to success\n", .{decl.name});
1708}1707}
17091708
1710fn markOutdatedDecl(self: *Module, decl: *Decl) !void {1709fn markOutdatedDecl(self: *Module, decl: *Decl) !void {
1711 //std.debug.warn("mark {} outdated\n", .{decl.name});1710 log.debug(.module, "mark {} outdated\n", .{decl.name});
1712 try self.work_queue.writeItem(.{ .analyze_decl = decl });1711 try self.work_queue.writeItem(.{ .analyze_decl = decl });
1713 if (self.failed_decls.remove(decl)) |entry| {1712 if (self.failed_decls.remove(decl)) |entry| {
1714 entry.value.destroy(self.gpa);1713 entry.value.destroy(self.gpa);
...@@ -2817,7 +2816,7 @@ pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {...@@ -2817,7 +2816,7 @@ pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {
2817 const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source");2816 const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source");
2818 const loc = std.zig.findLineColumn(source, inst.src);2817 const loc = std.zig.findLineColumn(source, inst.src);
2819 if (inst.tag == .constant) {2818 if (inst.tag == .constant) {
2820 std.debug.warn("constant ty={} val={} src={}:{}:{}\n", .{2819 std.debug.print("constant ty={} val={} src={}:{}:{}\n", .{
2821 inst.ty,2820 inst.ty,
2822 inst.castTag(.constant).?.val,2821 inst.castTag(.constant).?.val,
2823 zir_module.subFilePath(),2822 zir_module.subFilePath(),
...@@ -2825,7 +2824,7 @@ pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {...@@ -2825,7 +2824,7 @@ pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {
2825 loc.column + 1,2824 loc.column + 1,
2826 });2825 });
2827 } else if (inst.deaths == 0) {2826 } else if (inst.deaths == 0) {
2828 std.debug.warn("{} ty={} src={}:{}:{}\n", .{2827 std.debug.print("{} ty={} src={}:{}:{}\n", .{
2829 @tagName(inst.tag),2828 @tagName(inst.tag),
2830 inst.ty,2829 inst.ty,
2831 zir_module.subFilePath(),2830 zir_module.subFilePath(),
...@@ -2833,7 +2832,7 @@ pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {...@@ -2833,7 +2832,7 @@ pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {
2833 loc.column + 1,2832 loc.column + 1,
2834 });2833 });
2835 } else {2834 } else {
2836 std.debug.warn("{} ty={} deaths={b} src={}:{}:{}\n", .{2835 std.debug.print("{} ty={} deaths={b} src={}:{}:{}\n", .{
2837 @tagName(inst.tag),2836 @tagName(inst.tag),
2838 inst.ty,2837 inst.ty,
2839 inst.deaths,2838 inst.deaths,
src-self-hosted/main.zig+9-13
...@@ -10,9 +10,7 @@ const Module = @import("Module.zig");...@@ -10,9 +10,7 @@ const Module = @import("Module.zig");
10const link = @import("link.zig");10const link = @import("link.zig");
11const Package = @import("Package.zig");11const Package = @import("Package.zig");
12const zir = @import("zir.zig");12const zir = @import("zir.zig");
1313const build_options = @import("build_options");
14// TODO Improve async I/O enough that we feel comfortable doing this.
15//pub const io_mode = .evented;
1614
17pub const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB15pub const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB
1816
...@@ -47,18 +45,16 @@ pub fn log(...@@ -47,18 +45,16 @@ pub fn log(
47 if (@enumToInt(level) > @enumToInt(std.log.level))45 if (@enumToInt(level) > @enumToInt(std.log.level))
48 return;46 return;
4947
50 const scope_prefix = "(" ++ switch (scope) {48 const scope_name = @tagName(scope);
51 // Uncomment to hide logs49 const ok = comptime for (build_options.log_scopes) |log_scope| {
52 //.compiler,50 if (mem.eql(u8, log_scope, scope_name))
53 .module,51 break true;
54 .liveness,52 } else false;
55 .link,
56 => return,
5753
58 else => @tagName(scope),54 if (!ok)
59 } ++ "): ";55 return;
6056
61 const prefix = "[" ++ @tagName(level) ++ "] " ++ scope_prefix;57 const prefix = "[" ++ @tagName(level) ++ "] " ++ "(" ++ @tagName(scope) ++ "): ";
6258
63 // Print the message to stderr, silently ignoring any errors59 // Print the message to stderr, silently ignoring any errors
64 std.debug.print(prefix ++ format, args);60 std.debug.print(prefix ++ format, args);