authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-02-23 06:17:37+01:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-02-23 06:18:10+01:00
log43daed64fe8ce6e18571154adfea37ace2d84a34
tree6dc65fff060be102bb6066da4b237e15ce5f7325
parent1d4a7e123c8ea07d9cc5adcf0f51c640ccc2784a

Builder: change tuple metadata to not be inlined in llvm ir


1 files changed, 128 insertions(+), 138 deletions(-)

src/codegen/llvm/Builder.zig+128-138
......@@ -7640,7 +7640,6 @@ pub const Metadata = enum(u32) {
76407640 pub fn isInline(tag: Tag) bool {
76417641 return switch (tag) {
76427642 .none,
7643 .tuple,
76447643 .expression,
76457644 .constant,
76467645 => true,
......@@ -7673,6 +7672,7 @@ pub const Metadata = enum(u32) {
76737672 .enumerator_signed_positive,
76747673 .enumerator_signed_negative,
76757674 .subrange,
7675 .tuple,
76767676 .module_flag,
76777677 .local_var,
76787678 .parameter,
......@@ -7988,58 +7988,31 @@ pub const Metadata = enum(u32) {
79887988 need_comma: bool,
79897989 map: std.AutoArrayHashMapUnmanaged(Metadata, void) = .{},
79907990
7991 fn unwrapAssumeExists(formatter: *Formatter, item: Metadata) FormatData.Item {
7992 if (item == .none) return .none;
7993 const unwrapped_metadata = item.unwrap(formatter.builder);
7994 const tag = formatter.builder.metadata_items.items(.tag)[@intFromEnum(unwrapped_metadata)];
7995 return if (tag.isInline())
7996 .{ .@"inline" = unwrapped_metadata }
7997 else
7998 .{ .index = @intCast(formatter.map.getIndex(unwrapped_metadata).?) };
7999 }
8000 fn unwrap(formatter: *Formatter, item: Metadata) Allocator.Error!FormatData.Item {
8001 if (item == .none) return .none;
8002 const builder = formatter.builder;
8003 const unwrapped_metadata = item.unwrap(builder);
8004 const tag = formatter.builder.metadata_items.items(.tag)[@intFromEnum(unwrapped_metadata)];
8005 switch (tag) {
8006 .none => unreachable,
8007 .tuple => {
8008 var extra = builder.metadataExtraDataTrail(
8009 Metadata.Tuple,
8010 builder.metadata_items.items(.data)[@intFromEnum(unwrapped_metadata)],
8011 );
8012 const elements = extra.trail.next(extra.data.elements_len, Metadata, builder);
8013 for (elements) |element| _ = try formatter.unwrap(element);
8014 },
8015 .expression, .constant => {},
8016 else => {
8017 assert(!tag.isInline());
8018 const gop = try formatter.map.getOrPutValue(builder.gpa, unwrapped_metadata, {});
8019 return .{ .index = @intCast(gop.index) };
8020 },
8021 }
8022 return .{ .@"inline" = unwrapped_metadata };
8023 }
8024
80257991 const FormatData = struct {
80267992 formatter: *Formatter,
80277993 prefix: []const u8 = "",
8028 item: FormatData.Item,
7994 node: Node,
80297995
8030 const Item = union(enum) {
7996 const Node = union(enum) {
80317997 none,
80327998 @"inline": Metadata,
80337999 index: u32,
8000
8001 local_value: ValueData,
8002 local_metadata: ValueData,
8003 local_inline: Metadata,
8004 local_index: u32,
8005
80348006 string: MetadataString,
8035 value: struct {
8036 value: Value,
8037 function: Function.Index,
8038 },
80398007 bool: bool,
80408008 u32: u32,
80418009 u64: u64,
80428010 raw: []const u8,
8011
8012 const ValueData = struct {
8013 value: Value,
8014 function: Function.Index,
8015 };
80438016 };
80448017 };
80458018 fn format(
......@@ -8048,146 +8021,154 @@ pub const Metadata = enum(u32) {
80488021 fmt_opts: std.fmt.FormatOptions,
80498022 writer: anytype,
80508023 ) @TypeOf(writer).Error!void {
8051 if (data.item == .none) return;
8024 if (data.node == .none) return;
8025
8026 const is_specialized = fmt_str.len > 0 and fmt_str[0] == 'S';
8027 const recurse_fmt_str = if (is_specialized) fmt_str[1..] else fmt_str;
80528028
80538029 if (data.formatter.need_comma) try writer.writeAll(", ");
80548030 defer data.formatter.need_comma = true;
80558031 try writer.writeAll(data.prefix);
80568032
80578033 const builder = data.formatter.builder;
8058 switch (data.item) {
8034 switch (data.node) {
80598035 .none => unreachable,
8060 .@"inline" => |item| {
8036 .@"inline" => |node| {
80618037 const needed_comma = data.formatter.need_comma;
80628038 defer data.formatter.need_comma = needed_comma;
80638039 data.formatter.need_comma = false;
80648040
8065 const metadata_item = builder.metadata_items.get(@intFromEnum(item));
8066 switch (metadata_item.tag) {
8067 .tuple => {
8068 var extra =
8069 builder.metadataExtraDataTrail(Metadata.Tuple, metadata_item.data);
8070 const elements =
8071 extra.trail.next(extra.data.elements_len, Metadata, builder);
8072 try writer.writeAll("!{");
8073 for (elements) |element| try format(.{
8074 .formatter = data.formatter,
8075 .item = data.formatter.unwrapAssumeExists(element),
8076 }, "%", fmt_opts, writer);
8077 try writer.writeByte('}');
8078 },
8041 const item = builder.metadata_items.get(@intFromEnum(node));
8042 switch (item.tag) {
80798043 .expression => {
8080 var extra =
8081 builder.metadataExtraDataTrail(Metadata.Expression, metadata_item.data);
8044 var extra = builder.metadataExtraDataTrail(Expression, item.data);
80828045 const elements = extra.trail.next(extra.data.elements_len, u32, builder);
80838046 try writer.writeAll("!DIExpression(");
80848047 for (elements) |element| try format(.{
80858048 .formatter = data.formatter,
8086 .item = .{ .u64 = element },
8049 .node = .{ .u64 = element },
80878050 }, "%", fmt_opts, writer);
80888051 try writer.writeByte(')');
80898052 },
80908053 .constant => try Constant.format(.{
8091 .constant = @enumFromInt(metadata_item.data),
8054 .constant = @enumFromInt(item.data),
80928055 .builder = builder,
8093 }, fmt_str, fmt_opts, writer),
8056 }, recurse_fmt_str, fmt_opts, writer),
80948057 else => unreachable,
80958058 }
80968059 },
8097 .index => |item| try writer.print("!{d}", .{item}),
8098 .value => |item| switch (item.value.unwrap()) {
8099 .instruction, .constant => try Value.format(.{
8100 .value = item.value,
8101 .function = item.function,
8102 .builder = builder,
8103 }, fmt_str, fmt_opts, writer),
8104 .metadata => |metadata| if (@intFromEnum(metadata) >=
8105 Metadata.first_local_metadata)
8106 try Value.format(.{
8107 .value = item.function.ptrConst(builder).debug_values[
8108 @intFromEnum(metadata) - Metadata.first_local_metadata
8109 ].toValue(),
8110 .function = item.function,
8111 .builder = builder,
8112 }, "%", fmt_opts, writer)
8113 else if (metadata != .none) {
8114 if (comptime std.mem.eql(u8, fmt_str, "%"))
8115 try writer.print("{%} ", .{Type.metadata.fmt(builder)});
8116 try Metadata.Formatter.format(.{
8117 .formatter = data.formatter,
8118 .item = data.formatter.unwrapAssumeExists(metadata),
8119 }, "", fmt_opts, writer);
8120 },
8060 .index => |node| try writer.print("!{d}", .{node}),
8061 inline .local_value, .local_metadata => |node, tag| try Value.format(.{
8062 .value = node.value,
8063 .function = node.function,
8064 .builder = builder,
8065 }, switch (tag) {
8066 .local_value => recurse_fmt_str,
8067 .local_metadata => "%",
8068 else => unreachable,
8069 }, fmt_opts, writer),
8070 inline .local_inline, .local_index => |node, tag| {
8071 if (comptime std.mem.eql(u8, recurse_fmt_str, "%"))
8072 try writer.print("{%} ", .{Type.metadata.fmt(builder)});
8073 try format(.{
8074 .formatter = data.formatter,
8075 .node = @unionInit(FormatData.Node, @tagName(tag)["local_".len..], node),
8076 }, "", fmt_opts, writer);
81218077 },
8122 .string => |item| try writer.print("{}", .{item.fmt(data.formatter.builder)}),
8123 inline .bool, .u32, .u64 => |item| try writer.print("{}", .{item}),
8124 .raw => |item| try writer.writeAll(item),
8078 .string => |node| try writer.print("{s}{}", .{
8079 if (is_specialized) "" else "!",
8080 node.fmt(builder),
8081 }),
8082 inline .bool, .u32, .u64 => |node| try writer.print("{}", .{node}),
8083 .raw => |node| try writer.writeAll(node),
81258084 }
81268085 }
8127 inline fn fmt(formatter: *Formatter, prefix: []const u8, item: anytype) switch (@TypeOf(item)) {
8086 inline fn fmt(formatter: *Formatter, prefix: []const u8, node: anytype) switch (@TypeOf(node)) {
81288087 Metadata => Allocator.Error,
81298088 else => error{},
81308089 }!std.fmt.Formatter(format) {
8090 const Node = @TypeOf(node);
8091 const MaybeNode = switch (@typeInfo(Node)) {
8092 .Optional => Node,
8093 .Null => ?noreturn,
8094 else => ?Node,
8095 };
8096 const Some = @typeInfo(MaybeNode).Optional.child;
81318097 return .{ .data = .{
81328098 .formatter = formatter,
81338099 .prefix = prefix,
8134 .item = switch (@typeInfo(@TypeOf(item))) {
8135 .Null => .none,
8136 .Enum => |enum_info| switch (@TypeOf(item)) {
8137 Metadata => try formatter.unwrap(item),
8138 MetadataString => .{ .string = item },
8100 .node = if (@as(MaybeNode, node)) |some| switch (@typeInfo(Some)) {
8101 .Enum => |enum_info| switch (Some) {
8102 Metadata => switch (some) {
8103 .none => .none,
8104 else => try formatter.refUnwrapped(some.unwrap(formatter.builder)),
8105 },
8106 MetadataString => .{ .string = some },
81398107 else => if (enum_info.is_exhaustive)
8140 .{ .raw = @tagName(item) }
8108 .{ .raw = @tagName(some) }
81418109 else
8142 @compileError("unknown type to format: " ++ @typeName(@TypeOf(item))),
8143 },
8144 .EnumLiteral => .{ .raw = @tagName(item) },
8145 .Bool => .{ .bool = item },
8146 .Struct => .{ .u32 = @bitCast(item) },
8147 .Int, .ComptimeInt => .{ .u64 = item },
8148 .Pointer => .{ .raw = item },
8149 .Optional => if (item) |some| switch (@typeInfo(@TypeOf(some))) {
8150 .Enum => |enum_info| switch (@TypeOf(some)) {
8151 Metadata => try formatter.unwrap(some),
8152 MetadataString => .{ .string = some },
8153 else => if (enum_info.is_exhaustive)
8154 .{ .raw = @tagName(some) }
8155 else
8156 @compileError("unknown type to format: " ++ @typeName(@TypeOf(item))),
8157 },
8158 .Bool => .{ .bool = some },
8159 .Struct => .{ .u32 = @bitCast(some) },
8160 .Int => .{ .u64 = some },
8161 .Pointer => .{ .raw = some },
8162 else => @compileError("unknown type to format: " ++ @typeName(@TypeOf(item))),
8163 } else .none,
8164 else => @compileError("unknown type to format: " ++ @typeName(@TypeOf(item))),
8110 @compileError("unknown type to format: " ++ @typeName(Node)),
8111 },
8112 .EnumLiteral => .{ .raw = @tagName(some) },
8113 .Bool => .{ .bool = some },
8114 .Struct => .{ .u32 = @bitCast(some) },
8115 .Int, .ComptimeInt => .{ .u64 = some },
8116 .Pointer => .{ .raw = some },
8117 else => @compileError("unknown type to format: " ++ @typeName(Node)),
8118 } else switch (@typeInfo(Node)) {
8119 .Optional, .Null => .none,
8120 else => unreachable,
81658121 },
81668122 } };
81678123 }
81688124 inline fn fmtLocal(
81698125 formatter: *Formatter,
81708126 prefix: []const u8,
8171 item: Value,
8127 value: Value,
81728128 function: Function.Index,
81738129 ) Allocator.Error!std.fmt.Formatter(format) {
81748130 return .{ .data = .{
81758131 .formatter = formatter,
81768132 .prefix = prefix,
8177 .item = .{ .value = .{
8178 .value = switch (item.unwrap()) {
8179 .instruction, .constant => item,
8180 .metadata => |metadata| value: {
8181 const unwrapped_metadata = metadata.unwrap(formatter.builder);
8182 if (@intFromEnum(unwrapped_metadata) < Metadata.first_local_metadata)
8183 _ = try formatter.unwrap(unwrapped_metadata);
8184 break :value unwrapped_metadata.toValue();
8185 },
8133 .node = switch (value.unwrap()) {
8134 .instruction, .constant => .{ .local_value = .{
8135 .value = value,
8136 .function = function,
8137 } },
8138 .metadata => |metadata| if (value == .none) .none else node: {
8139 const unwrapped = metadata.unwrap(formatter.builder);
8140 break :node if (@intFromEnum(unwrapped) >= first_local_metadata)
8141 .{ .local_metadata = .{
8142 .value = function.ptrConst(formatter.builder).debug_values[
8143 @intFromEnum(unwrapped) - first_local_metadata
8144 ].toValue(),
8145 .function = function,
8146 } }
8147 else switch (try formatter.refUnwrapped(unwrapped)) {
8148 .@"inline" => |node| .{ .local_inline = node },
8149 .index => |node| .{ .local_index = node },
8150 else => unreachable,
8151 };
81868152 },
8187 .function = function,
8188 } },
8153 },
81898154 } };
81908155 }
8156 fn refUnwrapped(formatter: *Formatter, node: Metadata) Allocator.Error!FormatData.Node {
8157 assert(node != .none);
8158 assert(@intFromEnum(node) < first_forward_reference);
8159 const builder = formatter.builder;
8160 const unwrapped_metadata = node.unwrap(builder);
8161 const tag = formatter.builder.metadata_items.items(.tag)[@intFromEnum(unwrapped_metadata)];
8162 switch (tag) {
8163 .none => unreachable,
8164 .expression, .constant => return .{ .@"inline" = unwrapped_metadata },
8165 else => {
8166 assert(!tag.isInline());
8167 const gop = try formatter.map.getOrPutValue(builder.gpa, unwrapped_metadata, {});
8168 return .{ .index = @intCast(gop.index) };
8169 },
8170 }
8171 }
81918172
81928173 inline fn specialized(
81938174 formatter: *Formatter,
......@@ -8208,11 +8189,11 @@ pub const Metadata = enum(u32) {
82088189 DIGlobalVariable,
82098190 DIGlobalVariableExpression,
82108191 },
8211 items: anytype,
8192 nodes: anytype,
82128193 writer: anytype,
82138194 ) !void {
82148195 comptime var fmt_str: []const u8 = "";
8215 const names = comptime std.meta.fieldNames(@TypeOf(items));
8196 const names = comptime std.meta.fieldNames(@TypeOf(nodes));
82168197 comptime var fields: [2 + names.len]std.builtin.Type.StructField = undefined;
82178198 inline for (fields[0..2], .{ "distinct", "node" }) |*field, name| {
82188199 fmt_str = fmt_str ++ "{[" ++ name ++ "]s}";
......@@ -8226,7 +8207,7 @@ pub const Metadata = enum(u32) {
82268207 }
82278208 fmt_str = fmt_str ++ "(";
82288209 inline for (fields[2..], names) |*field, name| {
8229 fmt_str = fmt_str ++ "{[" ++ name ++ "]}";
8210 fmt_str = fmt_str ++ "{[" ++ name ++ "]S}";
82308211 field.* = .{
82318212 .name = name,
82328213 .type = std.fmt.Formatter(format),
......@@ -8247,7 +8228,7 @@ pub const Metadata = enum(u32) {
82478228 fmt_args.node = @tagName(node);
82488229 inline for (names) |name| @field(fmt_args, name) = try formatter.fmt(
82498230 name ++ ": ",
8250 @field(items, name),
8231 @field(nodes, name),
82518232 );
82528233 try writer.print(fmt_str, fmt_args);
82538234 }
......@@ -9877,7 +9858,7 @@ pub fn printUnbuffered(
98779858 metadata_formatter.need_comma = false;
98789859 defer metadata_formatter.need_comma = undefined;
98799860 switch (metadata_item.tag) {
9880 .none, .tuple, .expression, .constant => unreachable,
9861 .none, .expression, .constant => unreachable,
98819862 .file => {
98829863 const extra = self.metadataExtraData(Metadata.File, metadata_item.data);
98839864 try metadata_formatter.specialized(.@"!", .DIFile, .{
......@@ -10139,11 +10120,20 @@ pub fn printUnbuffered(
1013910120 .stride = null,
1014010121 }, writer);
1014110122 },
10123 .tuple => {
10124 var extra = self.metadataExtraDataTrail(Metadata.Tuple, metadata_item.data);
10125 const elements = extra.trail.next(extra.data.elements_len, Metadata, self);
10126 try writer.writeAll("!{");
10127 for (elements) |element| try writer.print("{[element]%}", .{
10128 .element = try metadata_formatter.fmt("", element),
10129 });
10130 try writer.writeAll("}\n");
10131 },
1014210132 .module_flag => {
1014310133 const extra = self.metadataExtraData(Metadata.ModuleFlag, metadata_item.data);
1014410134 try writer.print("!{{{[behavior]%}{[name]%}{[constant]%}}}\n", .{
1014510135 .behavior = try metadata_formatter.fmt("", extra.behavior),
10146 .name = try metadata_formatter.fmt("!", extra.name),
10136 .name = try metadata_formatter.fmt("", extra.name),
1014710137 .constant = try metadata_formatter.fmt("", extra.constant),
1014810138 });
1014910139 },