| ... | @@ -7,6 +7,8 @@ const leb128 = std.leb; | ... | @@ -7,6 +7,8 @@ const leb128 = std.leb; |
| 7 | const link = @import("../../link.zig"); | 7 | const link = @import("../../link.zig"); |
| 8 | const log = std.log.scoped(.codegen); | 8 | const log = std.log.scoped(.codegen); |
| 9 | const tracking_log = std.log.scoped(.tracking); | 9 | const tracking_log = std.log.scoped(.tracking); |
| | 10 | const verbose_tracking_log = std.log.scoped(.verbose_tracking); |
| | 11 | const wip_mir_log = std.log.scoped(.wip_mir); |
| 10 | const math = std.math; | 12 | const math = std.math; |
| 11 | const mem = std.mem; | 13 | const mem = std.mem; |
| 12 | const trace = @import("../../tracy.zig").trace; | 14 | const trace = @import("../../tracy.zig").trace; |
| ... | @@ -48,9 +50,6 @@ const sse = abi.RegisterClass.sse; | ... | @@ -48,9 +50,6 @@ const sse = abi.RegisterClass.sse; |
| 48 | | 50 | |
| 49 | const InnerError = CodeGenError || error{OutOfRegisters}; | 51 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| 50 | | 52 | |
| 51 | const debug_wip_mir = false; | | |
| 52 | const debug_tracking = false; | | |
| 53 | | | |
| 54 | gpa: Allocator, | 53 | gpa: Allocator, |
| 55 | air: Air, | 54 | air: Air, |
| 56 | liveness: Liveness, | 55 | liveness: Liveness, |
| ... | @@ -575,12 +574,6 @@ pub fn generate( | ... | @@ -575,12 +574,6 @@ pub fn generate( |
| 575 | assert(fn_owner_decl.has_tv); | 574 | assert(fn_owner_decl.has_tv); |
| 576 | const fn_type = fn_owner_decl.ty; | 575 | const fn_type = fn_owner_decl.ty; |
| 577 | | 576 | |
| 578 | if (debug_wip_mir) { | | |
| 579 | const stderr = std.io.getStdErr().writer(); | | |
| 580 | fn_owner_decl.renderFullyQualifiedName(mod, stderr) catch {}; | | |
| 581 | stderr.writeAll(":\n") catch {}; | | |
| 582 | } | | |
| 583 | | | |
| 584 | const gpa = bin_file.allocator; | 577 | const gpa = bin_file.allocator; |
| 585 | var function = Self{ | 578 | var function = Self{ |
| 586 | .gpa = gpa, | 579 | .gpa = gpa, |
| ... | @@ -614,6 +607,8 @@ pub fn generate( | ... | @@ -614,6 +607,8 @@ pub fn generate( |
| 614 | if (builtin.mode == .Debug) function.mir_to_air_map.deinit(gpa); | 607 | if (builtin.mode == .Debug) function.mir_to_air_map.deinit(gpa); |
| 615 | } | 608 | } |
| 616 | | 609 | |
| | 610 | wip_mir_log.debug("{}:", .{function.fmtDecl(module_fn.owner_decl)}); |
| | 611 | |
| 617 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); | 612 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); |
| 618 | function.frame_allocs.set( | 613 | function.frame_allocs.set( |
| 619 | @enumToInt(FrameIndex.stack_frame), | 614 | @enumToInt(FrameIndex.stack_frame), |
| ... | @@ -715,48 +710,104 @@ pub fn generate( | ... | @@ -715,48 +710,104 @@ pub fn generate( |
| 715 | } | 710 | } |
| 716 | } | 711 | } |
| 717 | | 712 | |
| 718 | fn dumpWipMir(self: *Self, inst: Mir.Inst) !void { | 713 | const FormatDeclData = struct { |
| 719 | if (!debug_wip_mir) return; | 714 | mod: *Module, |
| 720 | const stderr = std.io.getStdErr().writer(); | 715 | decl_index: Module.Decl.Index, |
| | 716 | }; |
| | 717 | fn formatDecl( |
| | 718 | data: FormatDeclData, |
| | 719 | comptime _: []const u8, |
| | 720 | _: std.fmt.FormatOptions, |
| | 721 | writer: anytype, |
| | 722 | ) @TypeOf(writer).Error!void { |
| | 723 | try data.mod.declPtr(data.decl_index).renderFullyQualifiedName(data.mod, writer); |
| | 724 | } |
| | 725 | fn fmtDecl(self: *Self, decl_index: Module.Decl.Index) std.fmt.Formatter(formatDecl) { |
| | 726 | return .{ .data = .{ |
| | 727 | .mod = self.bin_file.options.module.?, |
| | 728 | .decl_index = decl_index, |
| | 729 | } }; |
| | 730 | } |
| | 731 | |
| | 732 | const FormatAirData = struct { |
| | 733 | self: *Self, |
| | 734 | inst: Air.Inst.Index, |
| | 735 | }; |
| | 736 | fn formatAir( |
| | 737 | data: FormatAirData, |
| | 738 | comptime _: []const u8, |
| | 739 | _: std.fmt.FormatOptions, |
| | 740 | writer: anytype, |
| | 741 | ) @TypeOf(writer).Error!void { |
| | 742 | @import("../../print_air.zig").dumpInst( |
| | 743 | data.inst, |
| | 744 | data.self.bin_file.options.module.?, |
| | 745 | data.self.air, |
| | 746 | data.self.liveness, |
| | 747 | ); |
| | 748 | } |
| | 749 | fn fmtAir(self: *Self, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) { |
| | 750 | return .{ .data = .{ .self = self, .inst = inst } }; |
| | 751 | } |
| 721 | | 752 | |
| | 753 | const FormatWipMirData = struct { |
| | 754 | self: *Self, |
| | 755 | inst: Mir.Inst.Index, |
| | 756 | }; |
| | 757 | fn formatWipMir( |
| | 758 | data: FormatWipMirData, |
| | 759 | comptime _: []const u8, |
| | 760 | _: std.fmt.FormatOptions, |
| | 761 | writer: anytype, |
| | 762 | ) @TypeOf(writer).Error!void { |
| 722 | var lower = Lower{ | 763 | var lower = Lower{ |
| 723 | .allocator = self.gpa, | 764 | .allocator = data.self.gpa, |
| 724 | .mir = .{ | 765 | .mir = .{ |
| 725 | .instructions = self.mir_instructions.slice(), | 766 | .instructions = data.self.mir_instructions.slice(), |
| 726 | .extra = self.mir_extra.items, | 767 | .extra = data.self.mir_extra.items, |
| 727 | .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(), | 768 | .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(), |
| 728 | }, | 769 | }, |
| 729 | .target = self.target, | 770 | .target = data.self.target, |
| 730 | .src_loc = self.src_loc, | 771 | .src_loc = data.self.src_loc, |
| 731 | }; | 772 | }; |
| 732 | for (lower.lowerMir(inst) catch |err| switch (err) { | 773 | for (lower.lowerMir(data.self.mir_instructions.get(data.inst)) catch |err| switch (err) { |
| 733 | error.LowerFail => { | 774 | error.LowerFail => { |
| 734 | defer { | 775 | defer { |
| 735 | lower.err_msg.?.deinit(self.gpa); | 776 | lower.err_msg.?.deinit(data.self.gpa); |
| 736 | lower.err_msg = null; | 777 | lower.err_msg = null; |
| 737 | } | 778 | } |
| 738 | try stderr.print("{s}\n", .{lower.err_msg.?.msg}); | 779 | try writer.writeAll(lower.err_msg.?.msg); |
| 739 | return; | 780 | return; |
| 740 | }, | 781 | }, |
| 741 | error.InvalidInstruction, error.CannotEncode => |e| { | 782 | error.OutOfMemory, error.InvalidInstruction, error.CannotEncode => |e| { |
| 742 | try stderr.writeAll(switch (e) { | 783 | try writer.writeAll(switch (e) { |
| 743 | error.InvalidInstruction => "CodeGen failed to find a viable instruction.\n", | 784 | error.OutOfMemory => "Out of memory", |
| 744 | error.CannotEncode => "CodeGen failed to encode the instruction.\n", | 785 | error.InvalidInstruction => "CodeGen failed to find a viable instruction.", |
| | 786 | error.CannotEncode => "CodeGen failed to encode the instruction.", |
| 745 | }); | 787 | }); |
| 746 | return; | 788 | return; |
| 747 | }, | 789 | }, |
| 748 | else => |e| return e, | 790 | else => |e| return e, |
| 749 | }) |lower_inst| { | 791 | }) |lower_inst| try writer.print(" | {}", .{lower_inst}); |
| 750 | try stderr.print(" | {}\n", .{lower_inst}); | 792 | } |
| 751 | } | 793 | fn fmtWipMir(self: *Self, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMir) { |
| | 794 | return .{ .data = .{ .self = self, .inst = inst } }; |
| 752 | } | 795 | } |
| 753 | | 796 | |
| 754 | fn dumpTracking(self: *Self) !void { | 797 | const FormatTrackingData = struct { |
| 755 | if (!debug_tracking) return; | 798 | self: *Self, |
| 756 | const stderr = std.io.getStdErr().writer(); | 799 | }; |
| 757 | | 800 | fn formatTracking( |
| 758 | var it = self.inst_tracking.iterator(); | 801 | data: FormatTrackingData, |
| 759 | while (it.next()) |entry| try stderr.print("%{d} = {}\n", .{ entry.key_ptr.*, entry.value_ptr.* }); | 802 | comptime _: []const u8, |
| | 803 | _: std.fmt.FormatOptions, |
| | 804 | writer: anytype, |
| | 805 | ) @TypeOf(writer).Error!void { |
| | 806 | var it = data.self.inst_tracking.iterator(); |
| | 807 | while (it.next()) |entry| try writer.print("\n%{d} = {}", .{ entry.key_ptr.*, entry.value_ptr.* }); |
| | 808 | } |
| | 809 | fn fmtTracking(self: *Self) std.fmt.Formatter(formatTracking) { |
| | 810 | return .{ .data = .{ .self = self } }; |
| 760 | } | 811 | } |
| 761 | | 812 | |
| 762 | fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { | 813 | fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { |
| ... | @@ -764,7 +815,14 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { | ... | @@ -764,7 +815,14 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { |
| 764 | try self.mir_instructions.ensureUnusedCapacity(gpa, 1); | 815 | try self.mir_instructions.ensureUnusedCapacity(gpa, 1); |
| 765 | const result_index = @intCast(Mir.Inst.Index, self.mir_instructions.len); | 816 | const result_index = @intCast(Mir.Inst.Index, self.mir_instructions.len); |
| 766 | self.mir_instructions.appendAssumeCapacity(inst); | 817 | self.mir_instructions.appendAssumeCapacity(inst); |
| 767 | self.dumpWipMir(inst) catch {}; | 818 | switch (inst.tag) { |
| | 819 | else => wip_mir_log.debug("{}", .{self.fmtWipMir(result_index)}), |
| | 820 | .dbg_line, |
| | 821 | .dbg_prologue_end, |
| | 822 | .dbg_epilogue_begin, |
| | 823 | .dead, |
| | 824 | => {}, |
| | 825 | } |
| 768 | return result_index; | 826 | return result_index; |
| 769 | } | 827 | } |
| 770 | | 828 | |
| ... | @@ -1186,13 +1244,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -1186,13 +1244,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 1186 | } | 1244 | } |
| 1187 | | 1245 | |
| 1188 | if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) continue; | 1246 | if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) continue; |
| 1189 | if (debug_wip_mir) @import("../../print_air.zig").dumpInst( | 1247 | wip_mir_log.debug("{}", .{self.fmtAir(inst)}); |
| 1190 | inst, | 1248 | verbose_tracking_log.debug("{}", .{self.fmtTracking()}); |
| 1191 | self.bin_file.options.module.?, | | |
| 1192 | self.air, | | |
| 1193 | self.liveness, | | |
| 1194 | ); | | |
| 1195 | self.dumpTracking() catch {}; | | |
| 1196 | | 1249 | |
| 1197 | const old_air_bookkeeping = self.air_bookkeeping; | 1250 | const old_air_bookkeeping = self.air_bookkeeping; |
| 1198 | try self.inst_tracking.ensureUnusedCapacity(self.gpa, 1); | 1251 | try self.inst_tracking.ensureUnusedCapacity(self.gpa, 1); |
| ... | @@ -1453,7 +1506,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -1453,7 +1506,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 1453 | } | 1506 | } |
| 1454 | } | 1507 | } |
| 1455 | } | 1508 | } |
| 1456 | self.dumpTracking() catch {}; | 1509 | verbose_tracking_log.debug("{}", .{self.fmtTracking()}); |
| 1457 | } | 1510 | } |
| 1458 | | 1511 | |
| 1459 | fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { | 1512 | fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { |