authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-20 02:44:29-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-20 02:44:40-04:00
log4d31d4d875f32ed49c56151ca053a614b3ae343c
tree763807230cc7bfd4a8291df5e1442e0e9a278a22
parenta1062c63cad1ad80ecd42f6c58403133a608cca2

llvm: cleanup LLVM IR dumping


2 files changed, 63 insertions(+), 39 deletions(-)

src/codegen/llvm.zig+2-17
...@@ -1104,24 +1104,9 @@ pub const Object = struct {...@@ -1104,24 +1104,9 @@ pub const Object = struct {
11041104
1105 if (comp.verbose_llvm_ir) |path| {1105 if (comp.verbose_llvm_ir) |path| {
1106 if (std.mem.eql(u8, path, "-")) {1106 if (std.mem.eql(u8, path, "-")) {
1107 self.llvm_module.dump();1107 self.builder.dump();
1108
1109 const writer = std.io.getStdErr().writer();
1110 try writer.writeAll("\n" ++ "-" ** 200 ++ "\n\n");
1111 try self.builder.dump(writer);
1112 } else {1108 } else {
1113 const path_z = try comp.gpa.dupeZ(u8, path);1109 _ = try self.builder.printToFile(path);
1114 defer comp.gpa.free(path_z);
1115
1116 var error_message: [*:0]const u8 = undefined;
1117
1118 if (self.llvm_module.printModuleToFile(path_z, &error_message).toBool()) {
1119 defer llvm.disposeMessage(error_message);
1120
1121 log.err("dump LLVM module failed ir={s}: {s}", .{
1122 path, error_message,
1123 });
1124 }
1125 }1110 }
1126 }1111 }
11271112
src/codegen/llvm/Builder.zig+61-22
...@@ -1701,7 +1701,7 @@ pub const Function = struct {...@@ -1701,7 +1701,7 @@ pub const Function = struct {
1701 => wip.extraData(Load, instruction.data).type,1701 => wip.extraData(Load, instruction.data).type,
1702 .phi,1702 .phi,
1703 .@"phi fast",1703 .@"phi fast",
1704 => wip.extraData(WipPhi, instruction.data).type,1704 => wip.extraData(Phi, instruction.data).type,
1705 .select,1705 .select,
1706 .@"select fast",1706 .@"select fast",
1707 => wip.extraData(Select, instruction.data).lhs.typeOfWip(wip),1707 => wip.extraData(Select, instruction.data).lhs.typeOfWip(wip),
...@@ -1892,11 +1892,7 @@ pub const Function = struct {...@@ -1892,11 +1892,7 @@ pub const Function = struct {
1892 => function.extraData(Load, instruction.data).type,1892 => function.extraData(Load, instruction.data).type,
1893 .phi,1893 .phi,
1894 .@"phi fast",1894 .@"phi fast",
1895 => {1895 => function.extraData(Phi, instruction.data).type,
1896 var extra = function.extraDataTrail(Phi, instruction.data);
1897 const vals = extra.trail.next(extra.data.incoming_len, Value, function);
1898 return vals[0].typeOf(function_index, builder);
1899 },
1900 .select,1896 .select,
1901 .@"select fast",1897 .@"select fast",
1902 => function.extraData(Select, instruction.data).lhs.typeOf(function_index, builder),1898 => function.extraData(Select, instruction.data).lhs.typeOf(function_index, builder),
...@@ -2055,18 +2051,12 @@ pub const Function = struct {...@@ -2055,18 +2051,12 @@ pub const Function = struct {
2055 pub const Signedness = Constant.Cast.Signedness;2051 pub const Signedness = Constant.Cast.Signedness;
2056 };2052 };
20572053
2058 pub const WipPhi = struct {2054 pub const Phi = struct {
2059 type: Type,2055 type: Type,
2060 //incoming_vals: [block.incoming]Value,2056 //incoming_vals: [block.incoming]Value,
2061 //incoming_blocks: [block.incoming]Block.Index,2057 //incoming_blocks: [block.incoming]Block.Index,
2062 };2058 };
20632059
2064 pub const Phi = struct {
2065 incoming_len: u32,
2066 //incoming_vals: [incoming_len]Value,
2067 //incoming_blocks: [incoming_len]Block.Index,
2068 };
2069
2070 pub const Select = struct {2060 pub const Select = struct {
2071 cond: Value,2061 cond: Value,
2072 lhs: Value,2062 lhs: Value,
...@@ -3117,7 +3107,7 @@ pub const WipFunction = struct {...@@ -3117,7 +3107,7 @@ pub const WipFunction = struct {
3117 const incoming_len = self.block.ptrConst(wip).incoming;3107 const incoming_len = self.block.ptrConst(wip).incoming;
3118 assert(vals.len == incoming_len and blocks.len == incoming_len);3108 assert(vals.len == incoming_len and blocks.len == incoming_len);
3119 const instruction = wip.instructions.get(@intFromEnum(self.instruction));3109 const instruction = wip.instructions.get(@intFromEnum(self.instruction));
3120 var extra = wip.extraDataTrail(Instruction.WipPhi, instruction.data);3110 var extra = wip.extraDataTrail(Instruction.Phi, instruction.data);
3121 for (vals) |val| assert(val.typeOfWip(wip) == extra.data.type);3111 for (vals) |val| assert(val.typeOfWip(wip) == extra.data.type);
3122 @memcpy(extra.trail.nextMut(incoming_len, Value, wip), vals);3112 @memcpy(extra.trail.nextMut(incoming_len, Value, wip), vals);
3123 @memcpy(extra.trail.nextMut(incoming_len, Block.Index, wip), blocks);3113 @memcpy(extra.trail.nextMut(incoming_len, Block.Index, wip), blocks);
...@@ -3563,11 +3553,11 @@ pub const WipFunction = struct {...@@ -3563,11 +3553,11 @@ pub const WipFunction = struct {
3563 .@"phi fast",3553 .@"phi fast",
3564 => {3554 => {
3565 const incoming_len = current_block.incoming;3555 const incoming_len = current_block.incoming;
3566 var extra = self.extraDataTrail(Instruction.WipPhi, instruction.data);3556 var extra = self.extraDataTrail(Instruction.Phi, instruction.data);
3567 const incoming_vals = extra.trail.next(incoming_len, Value, self);3557 const incoming_vals = extra.trail.next(incoming_len, Value, self);
3568 const incoming_blocks = extra.trail.next(incoming_len, Block.Index, self);3558 const incoming_blocks = extra.trail.next(incoming_len, Block.Index, self);
3569 instruction.data = wip_extra.addExtra(Instruction.Phi{3559 instruction.data = wip_extra.addExtra(Instruction.Phi{
3570 .incoming_len = incoming_len,3560 .type = extra.data.type,
3571 });3561 });
3572 wip_extra.appendValues(incoming_vals, instructions);3562 wip_extra.appendValues(incoming_vals, instructions);
3573 wip_extra.appendSlice(incoming_blocks);3563 wip_extra.appendSlice(incoming_blocks);
...@@ -3831,10 +3821,10 @@ pub const WipFunction = struct {...@@ -3831,10 +3821,10 @@ pub const WipFunction = struct {
3831 }3821 }
3832 const incoming = self.cursor.block.ptrConst(self).incoming;3822 const incoming = self.cursor.block.ptrConst(self).incoming;
3833 assert(incoming > 0);3823 assert(incoming > 0);
3834 try self.ensureUnusedExtraCapacity(1, Instruction.WipPhi, incoming * 2);3824 try self.ensureUnusedExtraCapacity(1, Instruction.Phi, incoming * 2);
3835 const instruction = try self.addInst(name, .{3825 const instruction = try self.addInst(name, .{
3836 .tag = tag,3826 .tag = tag,
3837 .data = self.addExtraAssumeCapacity(Instruction.WipPhi{ .type = ty }),3827 .data = self.addExtraAssumeCapacity(Instruction.Phi{ .type = ty }),
3838 });3828 });
3839 _ = self.extra.addManyAsSliceAssumeCapacity(incoming * 2);3829 _ = self.extra.addManyAsSliceAssumeCapacity(incoming * 2);
3840 if (self.builder.useLibLlvm()) {3830 if (self.builder.useLibLlvm()) {
...@@ -5729,7 +5719,51 @@ pub fn binValue(self: *Builder, tag: Constant.Tag, lhs: Constant, rhs: Constant)...@@ -5729,7 +5719,51 @@ pub fn binValue(self: *Builder, tag: Constant.Tag, lhs: Constant, rhs: Constant)
5729 return (try self.binConst(tag, lhs, rhs)).toValue();5719 return (try self.binConst(tag, lhs, rhs)).toValue();
5730}5720}
57315721
5732pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator.Error)!void {5722pub fn dump(self: *Builder) void {
5723 if (self.useLibLlvm())
5724 self.llvm.module.?.dump()
5725 else
5726 self.print(std.io.getStdErr().writer()) catch {};
5727}
5728
5729pub fn printToFile(self: *Builder, path: []const u8) Allocator.Error!bool {
5730 const path_z = try self.gpa.dupeZ(u8, path);
5731 defer self.gpa.free(path_z);
5732 return self.printToFileZ(path_z);
5733}
5734
5735pub fn printToFileZ(self: *Builder, path: [*:0]const u8) bool {
5736 if (self.useLibLlvm()) {
5737 var error_message: [*:0]const u8 = undefined;
5738 if (self.llvm.module.?.printModuleToFile(path, &error_message).toBool()) {
5739 defer llvm.disposeMessage(error_message);
5740 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, error_message });
5741 return false;
5742 }
5743 } else {
5744 var file = std.fs.cwd().createFileZ(path, .{}) catch |err| {
5745 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
5746 return false;
5747 };
5748 defer file.close();
5749 self.print(file.writer()) catch |err| {
5750 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
5751 return false;
5752 };
5753 }
5754 return true;
5755}
5756
5757pub fn print(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator.Error)!void {
5758 var bw = std.io.bufferedWriter(writer);
5759 try self.printUnbuffered(bw.writer());
5760 try bw.flush();
5761}
5762
5763pub fn printUnbuffered(
5764 self: *Builder,
5765 writer: anytype,
5766) (@TypeOf(writer).Error || Allocator.Error)!void {
5733 if (self.source_filename != .none) try writer.print(5767 if (self.source_filename != .none) try writer.print(
5734 \\; ModuleID = '{s}'5768 \\; ModuleID = '{s}'
5735 \\source_filename = {"}5769 \\source_filename = {"}
...@@ -5790,7 +5824,10 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -5790,7 +5824,10 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
5790 });5824 });
5791 for (0..params_len) |arg| {5825 for (0..params_len) |arg| {
5792 if (arg > 0) try writer.writeAll(", ");5826 if (arg > 0) try writer.writeAll(", ");
5793 try writer.print("{%}", .{function.arg(@intCast(arg)).fmt(function_index, self)});5827 if (function.instructions.len > 0)
5828 try writer.print("{%}", .{function.arg(@intCast(arg)).fmt(function_index, self)})
5829 else
5830 try writer.print("{%}", .{global.type.functionParameters(self)[arg].fmt(self)});
5794 }5831 }
5795 switch (global.type.functionKind(self)) {5832 switch (global.type.functionKind(self)) {
5796 .normal => {},5833 .normal => {},
...@@ -5801,6 +5838,7 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -5801,6 +5838,7 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
5801 }5838 }
5802 try writer.print("){}{}", .{ global.unnamed_addr, function.alignment });5839 try writer.print("){}{}", .{ global.unnamed_addr, function.alignment });
5803 if (function.instructions.len > 0) {5840 if (function.instructions.len > 0) {
5841 var block_incoming_len: u32 = undefined;
5804 try writer.writeAll(" {\n");5842 try writer.writeAll(" {\n");
5805 for (params_len..function.instructions.len) |instruction_i| {5843 for (params_len..function.instructions.len) |instruction_i| {
5806 const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);5844 const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);
...@@ -5933,6 +5971,7 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -5933,6 +5971,7 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
5933 },5971 },
5934 .arg => unreachable,5972 .arg => unreachable,
5935 .block => {5973 .block => {
5974 block_incoming_len = instruction.data;
5936 const name = instruction_index.name(&function);5975 const name = instruction_index.name(&function);
5937 if (@intFromEnum(instruction_index) > params_len) try writer.writeByte('\n');5976 if (@intFromEnum(instruction_index) > params_len) try writer.writeByte('\n');
5938 try writer.print("{}:\n", .{name.fmt(self)});5977 try writer.print("{}:\n", .{name.fmt(self)});
...@@ -6076,9 +6115,9 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -6076,9 +6115,9 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
6076 .@"phi fast",6115 .@"phi fast",
6077 => |tag| {6116 => |tag| {
6078 var extra = function.extraDataTrail(Function.Instruction.Phi, instruction.data);6117 var extra = function.extraDataTrail(Function.Instruction.Phi, instruction.data);
6079 const vals = extra.trail.next(extra.data.incoming_len, Value, &function);6118 const vals = extra.trail.next(block_incoming_len, Value, &function);
6080 const blocks =6119 const blocks =
6081 extra.trail.next(extra.data.incoming_len, Function.Block.Index, &function);6120 extra.trail.next(block_incoming_len, Function.Block.Index, &function);
6082 try writer.print(" %{} = {s} {%} ", .{6121 try writer.print(" %{} = {s} {%} ", .{
6083 instruction_index.name(&function).fmt(self),6122 instruction_index.name(&function).fmt(self),
6084 @tagName(tag),6123 @tagName(tag),