diff --git a/lib/std/zig/llvm/Builder.zig b/lib/std/zig/llvm/Builder.zig index 4afb0b8734..3bad020b9a 100644 --- a/lib/std/zig/llvm/Builder.zig +++ b/lib/std/zig/llvm/Builder.zig @@ -56,8 +56,8 @@ metadata_map: std.AutoArrayHashMapUnmanaged(void, void), metadata_items: std.MultiArrayList(Metadata.Item), metadata_extra: std.ArrayListUnmanaged(u32), metadata_limbs: std.ArrayListUnmanaged(std.math.big.Limb), -metadata_forward_references: std.ArrayListUnmanaged(Metadata), -metadata_named: std.AutoArrayHashMapUnmanaged(MetadataString, struct { +metadata_forward_references: std.ArrayListUnmanaged(Metadata.Optional), +metadata_named: std.AutoArrayHashMapUnmanaged(String, struct { len: u32, index: Metadata.Item.ExtraIndex, }), @@ -265,19 +265,20 @@ pub const Type = enum(u32) { }; pub const Simple = enum(u5) { - void = 2, - half = 10, - bfloat = 23, - float = 3, - double = 4, - fp128 = 14, - x86_fp80 = 13, - ppc_fp128 = 15, - x86_amx = 24, - x86_mmx = 17, - label = 5, - token = 22, - metadata = 16, + const Code = ir.ModuleBlock.TypeBlock.Code; + void = @intFromEnum(Code.VOID), + half = @intFromEnum(Code.HALF), + bfloat = @intFromEnum(Code.BFLOAT), + float = @intFromEnum(Code.FLOAT), + double = @intFromEnum(Code.DOUBLE), + fp128 = @intFromEnum(Code.FP128), + x86_fp80 = @intFromEnum(Code.X86_FP80), + ppc_fp128 = @intFromEnum(Code.PPC_FP128), + x86_amx = @intFromEnum(Code.X86_AMX), + x86_mmx = @intFromEnum(Code.X86_MMX), + label = @intFromEnum(Code.LABEL), + token = @intFromEnum(Code.TOKEN), + metadata = @intFromEnum(Code.METADATA), }; pub const Function = struct { @@ -1325,8 +1326,8 @@ pub const Attribute = union(Kind) { .none => unreachable, } } - pub fn fmt(self: Index, builder: *const Builder, mode: FormatData.mode) std.fmt.Alt(FormatData, format) { - return .{ .data = .{ .attribute_index = self, .builder = builder, .mode = mode } }; + pub fn fmt(self: Index, builder: *const Builder, flags: FormatData.Flags) std.fmt.Alt(FormatData, format) { + return .{ .data = .{ .attribute_index = self, .builder = builder, .flags = flags } }; } fn toStorage(self: Index, builder: *const Builder) Storage { @@ -2295,7 +2296,7 @@ pub const Global = struct { externally_initialized: ExternallyInitialized = .default, type: Type, partition: String = .none, - dbg: Metadata = .none, + dbg: Metadata.Optional = .none, kind: union(enum) { alias: Alias.Index, variable: Variable.Index, @@ -2375,7 +2376,11 @@ pub const Global = struct { } pub fn setDebugMetadata(self: Index, dbg: Metadata, builder: *Builder) void { - self.ptr(builder).dbg = dbg; + self.ptr(builder).dbg = dbg.toOptional(); + } + + pub fn getDebugMetadata(self: Index, builder: *const Builder) Metadata.Optional { + return self.ptrConst(builder).dbg; } const FormatData = struct { @@ -2606,6 +2611,10 @@ pub const Variable = struct { pub fn setGlobalVariableExpression(self: Index, expression: Metadata, builder: *Builder) void { self.ptrConst(builder).global.setDebugMetadata(expression, builder); } + + pub fn getGlobalVariableExpression(self: Index, builder: *Builder) Metadata.Optional { + return self.ptrConst(builder).global.getDebugMetadata(builder); + } }; }; @@ -4107,6 +4116,10 @@ pub const Function = struct { pub fn setSubprogram(self: Index, subprogram: Metadata, builder: *Builder) void { self.ptrConst(builder).global.setDebugMetadata(subprogram, builder); } + + pub fn getSubprogram(self: Index, builder: *const Builder) Metadata.Optional { + return self.ptrConst(builder).global.getDebugMetadata(builder); + } }; pub const Block = struct { @@ -4869,13 +4882,20 @@ pub const Function = struct { then: Block.Index, @"else": Block.Index, weights: Weights, + pub const Weights = enum(u32) { - // We can do this as metadata indices 0 and 1 are reserved. - none = 0, - unpredictable = 1, - /// These values should be converted to `Metadata` to be used - /// in a `prof` annotation providing branch weights. + none = @bitCast(Metadata.Optional.none), + unpredictable, _, + + pub fn fromMetadata(metadata: Metadata) Weights { + assert(metadata.kind == .node); + return @enumFromInt(metadata.index); + } + + pub fn toMetadata(weights: Weights) Metadata { + return .{ .index = @intCast(@intFromEnum(weights)), .kind = .node }; + } }; }; @@ -5130,19 +5150,19 @@ pub const DebugLocation = union(enum) { pub const Location = struct { line: u32, column: u32, - scope: Builder.Metadata, - inlined_at: Builder.Metadata, + scope: Builder.Metadata.Optional, + inlined_at: Builder.Metadata.Optional, }; - pub fn toMetadata(self: DebugLocation, builder: *Builder) Allocator.Error!Metadata { + pub fn toMetadata(self: DebugLocation, builder: *Builder) Allocator.Error!Metadata.Optional { return switch (self) { .no_location => .none, - .location => |location| try builder.debugLocation( + .location => |location| (try builder.debugLocation( location.line, location.column, - location.scope, - location.inlined_at, - ), + location.scope.unwrap().?, + location.inlined_at.unwrap(), + )).toOptional(), }; } }; @@ -5280,20 +5300,19 @@ pub const WipFunction = struct { .cond = cond, .then = then, .@"else" = @"else", - .weights = switch (weights) { + .weights = weights: switch (weights) { .none => .none, .unpredictable => .unpredictable, - .then_likely, .else_likely => w: { + .then_likely, .else_likely => { const branch_weights_str = try self.builder.metadataString("branch_weights"); const unlikely_const = try self.builder.metadataConstant(try self.builder.intConst(.i32, 1)); const likely_const = try self.builder.metadataConstant(try self.builder.intConst(.i32, 2000)); - const weight_vals: [2]Metadata = switch (weights) { + const weight_vals: [3]Metadata = switch (weights) { .none, .unpredictable => unreachable, - .then_likely => .{ likely_const, unlikely_const }, - .else_likely => .{ unlikely_const, likely_const }, + .then_likely => .{ branch_weights_str.toMetadata(), likely_const, unlikely_const }, + .else_likely => .{ branch_weights_str.toMetadata(), unlikely_const, likely_const }, }; - const tuple = try self.builder.strTuple(branch_weights_str, &weight_vals); - break :w @enumFromInt(@intFromEnum(tuple)); + break :weights .fromMetadata(try self.builder.metadataTuple(&weight_vals)); }, }, }), @@ -6197,20 +6216,18 @@ pub const WipFunction = struct { return instruction.toValue(); } - pub fn debugValue(self: *WipFunction, value: Value) Allocator.Error!Metadata { + pub fn debugValue(self: *WipFunction, value: Value) Allocator.Error!Metadata.Optional { if (self.strip) return .none; - return switch (value.unwrap()) { - .instruction => |instr_index| blk: { + const metadata: Metadata = metadata: switch (value.unwrap()) { + .instruction => |instr_index| { const gop = try self.debug_values.getOrPut(self.builder.gpa, instr_index); - - const metadata: Metadata = @enumFromInt(Metadata.first_local_metadata + gop.index); if (!gop.found_existing) gop.key_ptr.* = instr_index; - - break :blk metadata; + break :metadata .{ .index = @intCast(gop.index), .kind = .local }; }, .constant => |constant| try self.builder.metadataConstant(constant), .metadata => |metadata| metadata, }; + return metadata.toOptional(); } pub fn finish(self: *WipFunction) Allocator.Error!void { @@ -7820,7 +7837,7 @@ pub const Value = enum(u32) { else if (@intFromEnum(self) < first_metadata) .{ .constant = @enumFromInt(@intFromEnum(self) - first_constant) } else - .{ .metadata = @enumFromInt(@intFromEnum(self) - first_metadata) }; + .{ .metadata = @bitCast(@intFromEnum(self) - first_metadata) }; } pub fn typeOfWip(self: Value, wip: *const WipFunction) Type { @@ -7873,50 +7890,110 @@ pub const Value = enum(u32) { } }; -pub const MetadataString = enum(u32) { - none = 0, - _, +pub const Metadata = packed struct(u32) { + index: u29, + kind: Kind, + unused: enum(u1) { unused = 0 } = .unused, - pub fn slice(self: MetadataString, builder: *const Builder) []const u8 { - const index = @intFromEnum(self); - const start = builder.metadata_string_indices.items[index]; - const end = builder.metadata_string_indices.items[index + 1]; - return builder.metadata_string_bytes.items[start..end]; - } - - const Adapter = struct { - builder: *const Builder, - pub fn hash(_: Adapter, key: []const u8) u32 { - return @truncate(std.hash.Wyhash.hash(0, key)); - } - pub fn eql(ctx: Adapter, lhs_key: []const u8, _: void, rhs_index: usize) bool { - const rhs_metadata_string: MetadataString = @enumFromInt(rhs_index); - return std.mem.eql(u8, lhs_key, rhs_metadata_string.slice(ctx.builder)); - } + pub const Kind = enum(u2) { + string, + node, + forward, + local, }; - const FormatData = struct { - metadata_string: MetadataString, - builder: *const Builder, + pub const empty_tuple: Metadata = .{ .kind = .node, .index = 0 }; + + pub const Optional = packed struct(u32) { + index: u29, + kind: Metadata.Kind, + is_none: bool, + + pub const none: Metadata.Optional = .{ .index = 0, .kind = .string, .is_none = true }; + pub const empty_tuple: Metadata.Optional = Metadata.empty_tuple.toOptional(); + + pub fn wrap(metadata: ?Metadata) Metadata.Optional { + return (metadata orelse return .none).toOptional(); + } + pub fn unwrap(metadata: Metadata.Optional) ?Metadata { + return if (metadata.is_none) null else .{ .index = metadata.index, .kind = metadata.kind }; + } + pub fn toValue(metadata: Metadata.Optional) Value { + return if (metadata.unwrap()) |m| m.toValue() else .none; + } + pub fn toString(metadata: Metadata.Optional) Metadata.String.Optional { + return if (metadata.unwrap()) |m| m.toString().toOptional() else .none; + } }; - fn format(data: FormatData, w: *Writer) Writer.Error!void { - try printEscapedString(data.metadata_string.slice(data.builder), .always_quote, w); + pub fn toOptional(metadata: Metadata) Metadata.Optional { + return .{ .index = metadata.index, .kind = metadata.kind, .is_none = false }; } - fn fmt(self: MetadataString, builder: *const Builder) std.fmt.Alt(FormatData, format) { - return .{ .data = .{ .metadata_string = self, .builder = builder } }; + pub fn toValue(metadata: Metadata) Value { + return @enumFromInt(Value.first_metadata + @as(u32, @bitCast(metadata))); } -}; -pub const Metadata = enum(u32) { - none = 0, - empty_tuple = 1, - _, + pub const String = enum(u32) { + _, - const first_forward_reference = 1 << 29; - const first_local_metadata = 1 << 30; + pub const Optional = enum(u32) { + none = @bitCast(Metadata.Optional.none), + _, + + pub fn wrap(metadata: ?Metadata.String) Metadata.String.Optional { + return (metadata orelse return .none).toOptional(); + } + pub fn unwrap(metadata: Metadata.String.Optional) ?Metadata.String { + return switch (metadata) { + .none => null, + else => @enumFromInt(@intFromEnum(metadata)), + }; + } + pub fn toMetadata(metadata: Metadata.String.Optional) Metadata.Optional { + return if (metadata.unwrap()) |m| m.toMetadata().toOptional() else .none; + } + }; + pub fn toOptional(metadata: Metadata.String) Metadata.String.Optional { + return @enumFromInt(@intFromEnum(metadata)); + } + pub fn toMetadata(metadata: Metadata.String) Metadata { + return .{ .index = @intCast(@intFromEnum(metadata)), .kind = .string }; + } + + pub fn slice(metadata: Metadata.String, builder: *const Builder) []const u8 { + const index = @intFromEnum(metadata); + const start = builder.metadata_string_indices.items[index]; + const end = builder.metadata_string_indices.items[index + 1]; + return builder.metadata_string_bytes.items[start..end]; + } + + const Adapter = struct { + builder: *const Builder, + pub fn hash(_: Adapter, key: []const u8) u32 { + return @truncate(std.hash.Wyhash.hash(0, key)); + } + pub fn eql(ctx: Adapter, lhs_key: []const u8, _: void, rhs_index: usize) bool { + const rhs_metadata: Metadata.String = @enumFromInt(rhs_index); + return std.mem.eql(u8, lhs_key, rhs_metadata.slice(ctx.builder)); + } + }; + + const FormatData = struct { + metadata: Metadata.String, + builder: *const Builder, + }; + fn format(data: FormatData, w: *Writer) Writer.Error!void { + try printEscapedString(data.metadata.slice(data.builder), .always_quote, w); + } + fn fmt(self: Metadata.String, builder: *const Builder) std.fmt.Alt(FormatData, format) { + return .{ .data = .{ .metadata = self, .builder = builder } }; + } + }; + pub fn toString(metadata: Metadata) Metadata.String { + assert(metadata.kind == .string); + return @enumFromInt(metadata.index); + } pub const Tag = enum(u6) { - none, file, compile_unit, @"compile_unit optimized", @@ -7947,8 +8024,6 @@ pub const Metadata = enum(u32) { enumerator_signed_negative, subrange, tuple, - str_tuple, - module_flag, expression, local_var, parameter, @@ -7957,9 +8032,8 @@ pub const Metadata = enum(u32) { global_var_expression, constant, - pub fn isInline(tag: Tag) bool { - return switch (tag) { - .none, + pub fn isInline(metadata_tag: Metadata.Tag) bool { + return switch (metadata_tag) { .expression, .constant, => true, @@ -7993,8 +8067,6 @@ pub const Metadata = enum(u32) { .enumerator_signed_negative, .subrange, .tuple, - .str_tuple, - .module_flag, .local_var, .parameter, .global_var, @@ -8005,20 +8077,31 @@ pub const Metadata = enum(u32) { } }; - pub fn isInline(self: Metadata, builder: *const Builder) bool { - return builder.metadata_items.items(.tag)[@intFromEnum(self)].isInline(); + pub fn tag(metadata: Metadata, builder: *const Builder) Tag { + assert(metadata.kind == .node); + return builder.metadata_items.items(.tag)[metadata.index]; } - pub fn unwrap(self: Metadata, builder: *const Builder) Metadata { - var metadata = self; - while (@intFromEnum(metadata) >= Metadata.first_forward_reference and - @intFromEnum(metadata) < Metadata.first_local_metadata) - { - const index = @intFromEnum(metadata) - Metadata.first_forward_reference; - metadata = builder.metadata_forward_references.items[index]; - assert(metadata != .none); + pub fn item(metadata: Metadata, builder: *const Builder) Item { + assert(metadata.kind == .node); + return builder.metadata_items.get(metadata.index); + } + + pub fn isInline(metadata: Metadata, builder: *const Builder) bool { + return metadata.tag(builder).isInline(); + } + + pub fn unwrap(metadata: Metadata, builder: *const Builder) Metadata { + switch (metadata.kind) { + .string, .node, .local => return metadata, + .forward => { + const referenced = builder.metadata_forward_references.items[metadata.index].unwrap().?; + switch (referenced.kind) { + .string, .node => return referenced, + .forward, .local => unreachable, + } + }, } - return metadata; } pub const Item = struct { @@ -8086,8 +8169,8 @@ pub const Metadata = enum(u32) { }; pub const File = struct { - filename: MetadataString, - directory: MetadataString, + filename: Metadata.String.Optional, + directory: Metadata.String.Optional, }; pub const CompileUnit = struct { @@ -8095,10 +8178,10 @@ pub const Metadata = enum(u32) { optimized: bool, }; - file: Metadata, - producer: MetadataString, - enums: Metadata, - globals: Metadata, + file: Metadata.Optional, + producer: Metadata.String.Optional, + enums: Metadata.Optional, + globals: Metadata.Optional, }; pub const Subprogram = struct { @@ -8142,19 +8225,34 @@ pub const Metadata = enum(u32) { } }; - file: Metadata, - name: MetadataString, - linkage_name: MetadataString, + file: Metadata.Optional, + name: Metadata.String.Optional, + linkage_name: Metadata.String.Optional, line: u32, scope_line: u32, - ty: Metadata, + ty: Metadata.Optional, di_flags: DIFlags, - compile_unit: Metadata, + compile_unit: Metadata.Optional, }; + pub fn getSubprogram(metadata: Metadata, builder: *const Builder) Subprogram { + const metadata_item = metadata.item(builder); + switch (metadata_item.tag) { + else => unreachable, + .subprogram, + .@"subprogram local", + .@"subprogram definition", + .@"subprogram local definition", + .@"subprogram optimized", + .@"subprogram optimized local", + .@"subprogram optimized definition", + .@"subprogram optimized local definition", + => return builder.metadataExtraData(Metadata.Subprogram, metadata_item.data), + } + } pub const LexicalBlock = struct { - scope: Metadata, - file: Metadata, + scope: Metadata.Optional, + file: Metadata.Optional, line: u32, column: u32, }; @@ -8163,11 +8261,11 @@ pub const Metadata = enum(u32) { line: u32, column: u32, scope: Metadata, - inlined_at: Metadata, + inlined_at: Metadata.Optional, }; pub const BasicType = struct { - name: MetadataString, + name: Metadata.String.Optional, size_in_bits_lo: u32, size_in_bits_hi: u32, @@ -8177,16 +8275,16 @@ pub const Metadata = enum(u32) { }; pub const CompositeType = struct { - name: MetadataString, - file: Metadata, - scope: Metadata, + name: Metadata.String.Optional, + file: Metadata.Optional, + scope: Metadata.Optional, line: u32, - underlying_type: Metadata, + underlying_type: Metadata.Optional, size_in_bits_lo: u32, size_in_bits_hi: u32, align_in_bits_lo: u32, align_in_bits_hi: u32, - fields_tuple: Metadata, + fields_tuple: Metadata.Optional, pub fn bitSize(self: CompositeType) u64 { return @as(u64, self.size_in_bits_hi) << 32 | self.size_in_bits_lo; @@ -8197,11 +8295,11 @@ pub const Metadata = enum(u32) { }; pub const DerivedType = struct { - name: MetadataString, - file: Metadata, - scope: Metadata, + name: Metadata.String.Optional, + file: Metadata.Optional, + scope: Metadata.Optional, line: u32, - underlying_type: Metadata, + underlying_type: Metadata.Optional, size_in_bits_lo: u32, size_in_bits_hi: u32, align_in_bits_lo: u32, @@ -8221,19 +8319,19 @@ pub const Metadata = enum(u32) { }; pub const SubroutineType = struct { - types_tuple: Metadata, + types_tuple: Metadata.Optional, }; pub const Enumerator = struct { - name: MetadataString, + name: Metadata.String.Optional, bit_width: u32, limbs_index: u32, limbs_len: u32, }; pub const Subrange = struct { - lower_bound: Metadata, - count: Metadata, + lower_bound: Metadata.Optional, + count: Metadata.Optional, }; pub const Expression = struct { @@ -8248,33 +8346,20 @@ pub const Metadata = enum(u32) { // elements: [elements_len]Metadata }; - pub const StrTuple = struct { - str: MetadataString, - elements_len: u32, - - // elements: [elements_len]Metadata - }; - - pub const ModuleFlag = struct { - behavior: Metadata, - name: MetadataString, - constant: Metadata, - }; - pub const LocalVar = struct { - name: MetadataString, - file: Metadata, - scope: Metadata, + name: Metadata.String.Optional, + file: Metadata.Optional, + scope: Metadata.Optional, line: u32, - ty: Metadata, + ty: Metadata.Optional, }; pub const Parameter = struct { - name: MetadataString, - file: Metadata, - scope: Metadata, + name: Metadata.String.Optional, + file: Metadata.Optional, + scope: Metadata.Optional, line: u32, - ty: Metadata, + ty: Metadata.Optional, arg_no: u32, }; @@ -8283,24 +8368,20 @@ pub const Metadata = enum(u32) { local: bool, }; - name: MetadataString, - linkage_name: MetadataString, - file: Metadata, - scope: Metadata, + name: Metadata.String.Optional, + linkage_name: Metadata.String.Optional, + file: Metadata.Optional, + scope: Metadata.Optional, line: u32, - ty: Metadata, + ty: Metadata.Optional, variable: Variable.Index, }; pub const GlobalVarExpression = struct { - variable: Metadata, - expression: Metadata, + variable: Metadata.Optional, + expression: Metadata.Optional, }; - pub fn toValue(self: Metadata) Value { - return @enumFromInt(Value.first_metadata + @intFromEnum(self)); - } - const Formatter = struct { builder: *Builder, need_comma: bool, @@ -8325,7 +8406,7 @@ pub const Metadata = enum(u32) { local_inline: Metadata, local_index: u32, - string: MetadataString, + string: Metadata.String, bool: bool, u32: u32, u64: u64, @@ -8356,10 +8437,10 @@ pub const Metadata = enum(u32) { defer data.formatter.need_comma = needed_comma; data.formatter.need_comma = false; - const item = builder.metadata_items.get(@intFromEnum(node)); - switch (item.tag) { + const node_item = node.item(builder); + switch (node_item.tag) { .expression => { - var extra = builder.metadataExtraDataTrail(Expression, item.data); + var extra = builder.metadataExtraDataTrail(Expression, node_item.data); const elements = extra.trail.next(extra.data.elements_len, u32, builder); try w.writeAll("!DIExpression("); for (elements) |element| try format(.{ @@ -8370,7 +8451,7 @@ pub const Metadata = enum(u32) { try w.writeByte(')'); }, .constant => try Constant.format(.{ - .constant = @enumFromInt(item.data), + .constant = @enumFromInt(node_item.data), .builder = builder, .flags = data.specialized orelse .{}, }, w), @@ -8378,17 +8459,17 @@ pub const Metadata = enum(u32) { } }, .index => |node| try w.print("!{d}", .{node}), - inline .local_value, .local_metadata => |node, tag| try Value.format(.{ + inline .local_value, .local_metadata => |node, node_tag| try Value.format(.{ .value = node.value, .function = node.function, .builder = builder, - .flags = switch (tag) { + .flags = switch (node_tag) { .local_value => data.specialized orelse .{}, .local_metadata => .{ .percent = true }, else => unreachable, }, }, w), - inline .local_inline, .local_index => |node, tag| { + inline .local_inline, .local_index => |node, node_tag| { if (data.specialized) |flags| { if (flags.onlyPercent()) { try w.print("{f} ", .{Type.metadata.fmt(builder, .percent)}); @@ -8396,39 +8477,43 @@ pub const Metadata = enum(u32) { } try format(.{ .formatter = data.formatter, - .node = @unionInit(FormatData.Node, @tagName(tag)["local_".len..], node), + .node = @unionInit(FormatData.Node, @tagName(node_tag)["local_".len..], node), .specialized = .{ .percent = true }, }, w); }, - .string => |node| try w.print("{s}{f}", .{ - @as([]const u8, if (is_specialized) "!" else ""), node.fmt(builder), - }), + .string => |s| { + if (is_specialized) try w.writeByte('!'); + try w.print("{f}", .{s.fmt(builder)}); + }, inline .bool, .u32, .u64 => |node| try w.print("{}", .{node}), inline .di_flags, .sp_flags => |node| try w.print("{f}", .{node}), .raw => |node| try w.writeAll(node), } } inline fn fmt(formatter: *Formatter, prefix: []const u8, node: anytype, special: ?FormatFlags) switch (@TypeOf(node)) { - Metadata => Allocator.Error, + Metadata, Metadata.Optional, ?Metadata => Allocator.Error, else => error{}, }!std.fmt.Alt(FormatData, format) { const Node = @TypeOf(node); - const MaybeNode = switch (@typeInfo(Node)) { - .optional => Node, - .null => ?noreturn, - else => ?Node, + const MaybeNode = switch (Node) { + Metadata.Optional => ?Metadata, + Metadata.String.Optional => ?Metadata.String, + else => switch (@typeInfo(Node)) { + .optional => Node, + .null => ?noreturn, + else => ?Node, + }, }; const Some = @typeInfo(MaybeNode).optional.child; return .{ .data = .{ .formatter = formatter, .prefix = prefix, - .node = if (@as(MaybeNode, node)) |some| switch (@typeInfo(Some)) { + .node = if (@as(MaybeNode, switch (Node) { + Metadata.Optional, Metadata.String.Optional => node.unwrap(), + else => node, + })) |some| switch (@typeInfo(Some)) { .@"enum" => |enum_info| switch (Some) { - Metadata => switch (some) { - .none => .none, - else => try formatter.refUnwrapped(some.unwrap(formatter.builder)), - }, - MetadataString => .{ .string = some }, + Metadata.String => .{ .string = some }, else => if (enum_info.is_exhaustive) .{ .raw = @tagName(some) } else @@ -8438,15 +8523,23 @@ pub const Metadata = enum(u32) { .bool => .{ .bool = some }, .@"struct" => switch (Some) { DIFlags => .{ .di_flags = some }, + Metadata => switch (some.kind) { + .string => .{ .string = some.toString() }, + .node, .forward => try formatter.refUnwrapped(some.unwrap(formatter.builder)), + .local => unreachable, + }, Subprogram.DISPFlags => .{ .sp_flags = some }, else => @compileError("unknown type to format: " ++ @typeName(Node)), }, .int, .comptime_int => .{ .u64 = some }, .pointer => .{ .raw = some }, else => @compileError("unknown type to format: " ++ @typeName(Node)), - } else switch (@typeInfo(Node)) { - .optional, .null => .none, - else => unreachable, + } else switch (Node) { + Metadata.Optional, Metadata.String.Optional => .none, + else => switch (@typeInfo(Node)) { + .optional, .null => .none, + else => unreachable, + }, }, .specialized = special, } }; @@ -8460,24 +8553,26 @@ pub const Metadata = enum(u32) { return .{ .data = .{ .formatter = formatter, .prefix = prefix, - .node = switch (value.unwrap()) { + .node = node: switch (value.unwrap()) { .instruction, .constant => .{ .local_value = .{ .value = value, .function = function, } }, - .metadata => |metadata| if (value == .none) .none else node: { + .metadata => |metadata| if (value == .none) .none else { const unwrapped = metadata.unwrap(formatter.builder); - break :node if (@intFromEnum(unwrapped) >= first_local_metadata) - .{ .local_metadata = .{ + break :node switch (unwrapped.kind) { + .string, .node => switch (try formatter.refUnwrapped(unwrapped)) { + .@"inline" => |node| .{ .local_inline = node }, + .index => |node| .{ .local_index = node }, + else => unreachable, + }, + .forward => unreachable, + .local => .{ .local_metadata = .{ .value = function.ptrConst(formatter.builder).debug_values[ - @intFromEnum(unwrapped) - first_local_metadata + unwrapped.index ].toValue(), .function = function, - } } - else switch (try formatter.refUnwrapped(unwrapped)) { - .@"inline" => |node| .{ .local_inline = node }, - .index => |node| .{ .local_index = node }, - else => unreachable, + } }, }; }, }, @@ -8485,16 +8580,12 @@ pub const Metadata = enum(u32) { } }; } fn refUnwrapped(formatter: *Formatter, node: Metadata) Allocator.Error!FormatData.Node { - assert(node != .none); - assert(@intFromEnum(node) < first_forward_reference); const builder = formatter.builder; const unwrapped_metadata = node.unwrap(builder); - const tag = formatter.builder.metadata_items.items(.tag)[@intFromEnum(unwrapped_metadata)]; - switch (tag) { - .none => unreachable, + switch (unwrapped_metadata.tag(builder)) { .expression, .constant => return .{ .@"inline" = unwrapped_metadata }, - else => { - assert(!tag.isInline()); + else => |metadata_tag| { + assert(!metadata_tag.isInline()); const gop = try formatter.map.getOrPut(builder.gpa, .{ .metadata = unwrapped_metadata }); return .{ .index = @intCast(gop.index) }; }, @@ -8669,11 +8760,9 @@ pub fn init(options: Options) Allocator.Error!Builder { assert(try self.intConst(.i32, 1) == .@"1"); assert(try self.noneConst(.token) == .none); - assert(try self.metadataNone() == .none); - assert(try self.metadataTuple(&.{}) == .empty_tuple); + assert(try self.metadataTuple(&.{}) == Metadata.empty_tuple); try self.metadata_string_indices.append(self.gpa, 0); - assert(try self.metadataString("") == .none); return self; } @@ -9232,8 +9321,8 @@ pub fn halfConst(self: *Builder, val: f16) Allocator.Error!Constant { return self.halfConstAssumeCapacity(val); } -pub fn halfValue(self: *Builder, ty: Type, value: f16) Allocator.Error!Value { - return (try self.halfConst(ty, value)).toValue(); +pub fn halfValue(self: *Builder, value: f16) Allocator.Error!Value { + return (try self.halfConst(value)).toValue(); } pub fn bfloatConst(self: *Builder, val: f32) Allocator.Error!Constant { @@ -9241,8 +9330,8 @@ pub fn bfloatConst(self: *Builder, val: f32) Allocator.Error!Constant { return self.bfloatConstAssumeCapacity(val); } -pub fn bfloatValue(self: *Builder, ty: Type, value: f32) Allocator.Error!Value { - return (try self.bfloatConst(ty, value)).toValue(); +pub fn bfloatValue(self: *Builder, value: f32) Allocator.Error!Value { + return (try self.bfloatConst(value)).toValue(); } pub fn floatConst(self: *Builder, val: f32) Allocator.Error!Constant { @@ -9250,8 +9339,8 @@ pub fn floatConst(self: *Builder, val: f32) Allocator.Error!Constant { return self.floatConstAssumeCapacity(val); } -pub fn floatValue(self: *Builder, ty: Type, value: f32) Allocator.Error!Value { - return (try self.floatConst(ty, value)).toValue(); +pub fn floatValue(self: *Builder, value: f32) Allocator.Error!Value { + return (try self.floatConst(value)).toValue(); } pub fn doubleConst(self: *Builder, val: f64) Allocator.Error!Constant { @@ -9259,8 +9348,8 @@ pub fn doubleConst(self: *Builder, val: f64) Allocator.Error!Constant { return self.doubleConstAssumeCapacity(val); } -pub fn doubleValue(self: *Builder, ty: Type, value: f64) Allocator.Error!Value { - return (try self.doubleConst(ty, value)).toValue(); +pub fn doubleValue(self: *Builder, value: f64) Allocator.Error!Value { + return (try self.doubleConst(value)).toValue(); } pub fn fp128Const(self: *Builder, val: f128) Allocator.Error!Constant { @@ -9268,8 +9357,8 @@ pub fn fp128Const(self: *Builder, val: f128) Allocator.Error!Constant { return self.fp128ConstAssumeCapacity(val); } -pub fn fp128Value(self: *Builder, ty: Type, value: f128) Allocator.Error!Value { - return (try self.fp128Const(ty, value)).toValue(); +pub fn fp128Value(self: *Builder, value: f128) Allocator.Error!Value { + return (try self.fp128Const(value)).toValue(); } pub fn x86_fp80Const(self: *Builder, val: f80) Allocator.Error!Constant { @@ -9277,8 +9366,8 @@ pub fn x86_fp80Const(self: *Builder, val: f80) Allocator.Error!Constant { return self.x86_fp80ConstAssumeCapacity(val); } -pub fn x86_fp80Value(self: *Builder, ty: Type, value: f80) Allocator.Error!Value { - return (try self.x86_fp80Const(ty, value)).toValue(); +pub fn x86_fp80Value(self: *Builder, value: f80) Allocator.Error!Value { + return (try self.x86_fp80Const(value)).toValue(); } pub fn ppc_fp128Const(self: *Builder, val: [2]f64) Allocator.Error!Constant { @@ -9286,8 +9375,8 @@ pub fn ppc_fp128Const(self: *Builder, val: [2]f64) Allocator.Error!Constant { return self.ppc_fp128ConstAssumeCapacity(val); } -pub fn ppc_fp128Value(self: *Builder, ty: Type, value: [2]f64) Allocator.Error!Value { - return (try self.ppc_fp128Const(ty, value)).toValue(); +pub fn ppc_fp128Value(self: *Builder, value: [2]f64) Allocator.Error!Value { + return (try self.ppc_fp128Const(value)).toValue(); } pub fn nullConst(self: *Builder, ty: Type) Allocator.Error!Constant { @@ -9870,7 +9959,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void .none => {}, .unpredictable => try w.writeAll("!unpredictable !{}"), _ => try w.print("{f}", .{ - try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.weights))), null), + try metadata_formatter.fmt("!prof ", extra.weights.toMetadata(), null), }), } }, @@ -10153,7 +10242,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void .none => {}, .unpredictable => try w.writeAll("!unpredictable !{}"), _ => try w.print("{f}", .{ - try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.data.weights))), null), + try metadata_formatter.fmt("!prof ", extra.data.weights.toMetadata(), null), }), } }, @@ -10193,7 +10282,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void const elements: []const Metadata = @ptrCast(self.metadata_extra.items[data.index..][0..data.len]); try w.writeByte('!'); - try printEscapedString(name.slice(self), .quote_unless_valid_identifier, w); + try printEscapedString(name.slice(self).?, .quote_unless_valid_identifier, w); try w.writeAll(" = !{"); metadata_formatter.need_comma = false; defer metadata_formatter.need_comma = undefined; @@ -10223,11 +10312,11 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void }, w); continue; }, - .metadata => |metadata| self.metadata_items.get(@intFromEnum(metadata)), + .metadata => |metadata| metadata.item(self), }; switch (metadata_item.tag) { - .none, .expression, .constant => unreachable, + .expression, .constant => unreachable, .file => { const extra = self.metadataExtraData(Metadata.File, metadata_item.data); try metadata_formatter.specialized(.@"!", .DIFile, .{ @@ -10330,10 +10419,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void const extra = self.metadataExtraData(Metadata.BasicType, metadata_item.data); try metadata_formatter.specialized(.@"!", .DIBasicType, .{ .tag = null, - .name = switch (extra.name) { - .none => null, - else => extra.name, - }, + .name = extra.name, .size = extra.bitSize(), .@"align" = null, .encoding = @as(enum { @@ -10371,10 +10457,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void .composite_array_type, .composite_vector_type => .DW_TAG_array_type, else => unreachable, }), - .name = switch (extra.name) { - .none => null, - else => extra.name, - }, + .name = extra.name, .scope = extra.scope, .file = null, .line = null, @@ -10409,10 +10492,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void .derived_member_type => .DW_TAG_member, else => unreachable, }), - .name = switch (extra.name) { - .none => null, - else => extra.name, - }, + .name = extra.name, .scope = extra.scope, .file = null, .line = null, @@ -10505,25 +10585,6 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void }); try w.writeAll("}\n"); }, - .str_tuple => { - var extra = self.metadataExtraDataTrail(Metadata.StrTuple, metadata_item.data); - const elements = extra.trail.next(extra.data.elements_len, Metadata, self); - try w.print("!{{{[str]f}", .{ - .str = try metadata_formatter.fmt("", extra.data.str, .{ .percent = true }), - }); - for (elements) |element| try w.print("{[element]f}", .{ - .element = try metadata_formatter.fmt("", element, .{ .percent = true }), - }); - try w.writeAll("}\n"); - }, - .module_flag => { - const extra = self.metadataExtraData(Metadata.ModuleFlag, metadata_item.data); - try w.print("!{{{[behavior]f}{[name]f}{[constant]f}}}\n", .{ - .behavior = try metadata_formatter.fmt("", extra.behavior, .{ .percent = true }), - .name = try metadata_formatter.fmt("", extra.name, .{ .percent = true }), - .constant = try metadata_formatter.fmt("", extra.constant, .{ .percent = true }), - }); - }, .local_var => { const extra = self.metadataExtraData(Metadata.LocalVar, metadata_item.data); try metadata_formatter.specialized(.@"!", .DILocalVariable, .{ @@ -11914,8 +11975,8 @@ fn addMetadataExtraAssumeCapacity(self: *Builder, extra: anytype) Metadata.Item. const value = @field(extra, field.name); self.metadata_extra.appendAssumeCapacity(switch (field.type) { u32 => value, - MetadataString, Metadata, Variable.Index, Value => @intFromEnum(value), - Metadata.DIFlags => @bitCast(value), + Metadata.String, Metadata.String.Optional, Variable.Index, Value => @intFromEnum(value), + Metadata, Metadata.Optional, Metadata.DIFlags => @bitCast(value), else => @compileError("bad field type: " ++ @typeName(field.type)), }); } @@ -11953,8 +12014,8 @@ fn metadataExtraDataTrail( inline for (fields, self.metadata_extra.items[index..][0..fields.len]) |field, value| @field(result, field.name) = switch (field.type) { u32 => value, - MetadataString, Metadata, Variable.Index, Value => @enumFromInt(value), - Metadata.DIFlags => @bitCast(value), + Metadata.String, Metadata.String.Optional, Variable.Index, Value => @enumFromInt(value), + Metadata, Metadata.Optional, Metadata.DIFlags => @bitCast(value), else => @compileError("bad field type: " ++ @typeName(field.type)), }; return .{ @@ -11967,48 +12028,65 @@ fn metadataExtraData(self: *const Builder, comptime T: type, index: Metadata.Ite return self.metadataExtraDataTrail(T, index).data; } -pub fn metadataString(self: *Builder, bytes: []const u8) Allocator.Error!MetadataString { +pub fn metadataString(self: *Builder, bytes: []const u8) Allocator.Error!Metadata.String { + assert(bytes.len > 0); try self.metadata_string_bytes.ensureUnusedCapacity(self.gpa, bytes.len); try self.metadata_string_indices.ensureUnusedCapacity(self.gpa, 1); try self.metadata_string_map.ensureUnusedCapacity(self.gpa, 1); const gop = self.metadata_string_map.getOrPutAssumeCapacityAdapted( bytes, - MetadataString.Adapter{ .builder = self }, + Metadata.String.Adapter{ .builder = self }, ); if (!gop.found_existing) { self.metadata_string_bytes.appendSliceAssumeCapacity(bytes); - self.metadata_string_indices.appendAssumeCapacity(@intCast(self.metadata_string_bytes.items.len)); + self.metadata_string_indices.appendAssumeCapacity( + @intCast(self.metadata_string_bytes.items.len), + ); } return @enumFromInt(gop.index); } -pub fn metadataStringFromStrtabString(self: *Builder, str: StrtabString) Allocator.Error!MetadataString { - if (str == .none or str == .empty) return MetadataString.none; +pub fn metadataStringFromStrtabString( + self: *Builder, + str: StrtabString, +) Allocator.Error!Metadata.String { return try self.metadataString(str.slice(self).?); } -pub fn metadataStringFmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) Allocator.Error!MetadataString { +pub fn metadataStringFmt( + self: *Builder, + comptime fmt_str: []const u8, + fmt_args: anytype, +) Allocator.Error!Metadata.String { try self.metadata_string_map.ensureUnusedCapacity(self.gpa, 1); - try self.metadata_string_bytes.ensureUnusedCapacity(self.gpa, @intCast(std.fmt.count(fmt_str, fmt_args))); + try self.metadata_string_bytes.ensureUnusedCapacity( + self.gpa, + @intCast(std.fmt.count(fmt_str, fmt_args)), + ); try self.metadata_string_indices.ensureUnusedCapacity(self.gpa, 1); return self.metadataStringFmtAssumeCapacity(fmt_str, fmt_args); } -pub fn metadataStringFmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) MetadataString { +pub fn metadataStringFmtAssumeCapacity( + self: *Builder, + comptime fmt_str: []const u8, + fmt_args: anytype, +) Metadata.String { self.metadata_string_bytes.printAssumeCapacity(fmt_str, fmt_args); return self.trailingMetadataStringAssumeCapacity(); } -pub fn trailingMetadataString(self: *Builder) Allocator.Error!MetadataString { +pub fn trailingMetadataString(self: *Builder) Allocator.Error!Metadata.String { try self.metadata_string_indices.ensureUnusedCapacity(self.gpa, 1); try self.metadata_string_map.ensureUnusedCapacity(self.gpa, 1); return self.trailingMetadataStringAssumeCapacity(); } -pub fn trailingMetadataStringAssumeCapacity(self: *Builder) MetadataString { +pub fn trailingMetadataStringAssumeCapacity(self: *Builder) Metadata.String { const start = self.metadata_string_indices.getLast(); const bytes: []const u8 = self.metadata_string_bytes.items[start..]; + assert(bytes.len > 0); const gop = self.metadata_string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self }); if (gop.found_existing) { self.metadata_string_bytes.shrinkRetainingCapacity(start); @@ -12018,21 +12096,16 @@ pub fn trailingMetadataStringAssumeCapacity(self: *Builder) MetadataString { return @enumFromInt(gop.index); } -pub fn metadataNamed(self: *Builder, name: MetadataString, operands: []const Metadata) Allocator.Error!void { +pub fn addNamedMetadata(self: *Builder, name: String, operands: []const Metadata) Allocator.Error!void { try self.metadata_extra.ensureUnusedCapacity(self.gpa, operands.len); try self.metadata_named.ensureUnusedCapacity(self.gpa, 1); - self.metadataNamedAssumeCapacity(name, operands); -} - -fn metadataNone(self: *Builder) Allocator.Error!Metadata { - try self.ensureUnusedMetadataCapacity(1, NoExtra, 0); - return self.metadataNoneAssumeCapacity(); + self.addNamedMetadataAssumeCapacity(name, operands); } pub fn debugFile( self: *Builder, - filename: MetadataString, - directory: MetadataString, + filename: ?Metadata.String, + directory: ?Metadata.String, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.File, 0); return self.debugFileAssumeCapacity(filename, directory); @@ -12040,10 +12113,10 @@ pub fn debugFile( pub fn debugCompileUnit( self: *Builder, - file: Metadata, - producer: MetadataString, - enums: Metadata, - globals: Metadata, + file: ?Metadata, + producer: ?Metadata.String, + enums: ?Metadata, + globals: ?Metadata, options: Metadata.CompileUnit.Options, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompileUnit, 0); @@ -12052,14 +12125,14 @@ pub fn debugCompileUnit( pub fn debugSubprogram( self: *Builder, - file: Metadata, - name: MetadataString, - linkage_name: MetadataString, + file: ?Metadata, + name: ?Metadata.String, + linkage_name: ?Metadata.String, line: u32, scope_line: u32, - ty: Metadata, + ty: ?Metadata, options: Metadata.Subprogram.Options, - compile_unit: Metadata, + compile_unit: ?Metadata, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.Subprogram, 0); return self.debugSubprogramAssumeCapacity( @@ -12074,32 +12147,60 @@ pub fn debugSubprogram( ); } -pub fn debugLexicalBlock(self: *Builder, scope: Metadata, file: Metadata, line: u32, column: u32) Allocator.Error!Metadata { +pub fn debugLexicalBlock( + self: *Builder, + scope: ?Metadata, + file: ?Metadata, + line: u32, + column: u32, +) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.LexicalBlock, 0); return self.debugLexicalBlockAssumeCapacity(scope, file, line, column); } -pub fn debugLocation(self: *Builder, line: u32, column: u32, scope: Metadata, inlined_at: Metadata) Allocator.Error!Metadata { +pub fn debugLocation( + self: *Builder, + line: u32, + column: u32, + scope: Metadata, + inlined_at: ?Metadata, +) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.Location, 0); return self.debugLocationAssumeCapacity(line, column, scope, inlined_at); } -pub fn debugBoolType(self: *Builder, name: MetadataString, size_in_bits: u64) Allocator.Error!Metadata { +pub fn debugBoolType( + self: *Builder, + name: ?Metadata.String, + size_in_bits: u64, +) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0); return self.debugBoolTypeAssumeCapacity(name, size_in_bits); } -pub fn debugUnsignedType(self: *Builder, name: MetadataString, size_in_bits: u64) Allocator.Error!Metadata { +pub fn debugUnsignedType( + self: *Builder, + name: ?Metadata.String, + size_in_bits: u64, +) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0); return self.debugUnsignedTypeAssumeCapacity(name, size_in_bits); } -pub fn debugSignedType(self: *Builder, name: MetadataString, size_in_bits: u64) Allocator.Error!Metadata { +pub fn debugSignedType( + self: *Builder, + name: ?Metadata.String, + size_in_bits: u64, +) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0); return self.debugSignedTypeAssumeCapacity(name, size_in_bits); } -pub fn debugFloatType(self: *Builder, name: MetadataString, size_in_bits: u64) Allocator.Error!Metadata { +pub fn debugFloatType( + self: *Builder, + name: ?Metadata.String, + size_in_bits: u64, +) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0); return self.debugFloatTypeAssumeCapacity(name, size_in_bits); } @@ -12111,14 +12212,14 @@ pub fn debugForwardReference(self: *Builder) Allocator.Error!Metadata { pub fn debugStructType( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); return self.debugStructTypeAssumeCapacity( @@ -12135,14 +12236,14 @@ pub fn debugStructType( pub fn debugUnionType( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); return self.debugUnionTypeAssumeCapacity( @@ -12159,14 +12260,14 @@ pub fn debugUnionType( pub fn debugEnumerationType( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); return self.debugEnumerationTypeAssumeCapacity( @@ -12183,14 +12284,14 @@ pub fn debugEnumerationType( pub fn debugArrayType( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); return self.debugArrayTypeAssumeCapacity( @@ -12207,14 +12308,14 @@ pub fn debugArrayType( pub fn debugVectorType( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); return self.debugVectorTypeAssumeCapacity( @@ -12231,11 +12332,11 @@ pub fn debugVectorType( pub fn debugPointerType( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, offset_in_bits: u64, @@ -12255,11 +12356,11 @@ pub fn debugPointerType( pub fn debugMemberType( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, offset_in_bits: u64, @@ -12277,17 +12378,14 @@ pub fn debugMemberType( ); } -pub fn debugSubroutineType( - self: *Builder, - types_tuple: Metadata, -) Allocator.Error!Metadata { +pub fn debugSubroutineType(self: *Builder, types_tuple: ?Metadata) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.SubroutineType, 0); return self.debugSubroutineTypeAssumeCapacity(types_tuple); } pub fn debugEnumerator( self: *Builder, - name: MetadataString, + name: ?Metadata.String, unsigned: bool, bit_width: u32, value: std.math.big.int.Const, @@ -12300,55 +12398,37 @@ pub fn debugEnumerator( pub fn debugSubrange( self: *Builder, - lower_bound: Metadata, - count: Metadata, + lower_bound: ?Metadata, + count: ?Metadata, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.Subrange, 0); return self.debugSubrangeAssumeCapacity(lower_bound, count); } -pub fn debugExpression( - self: *Builder, - elements: []const u32, -) Allocator.Error!Metadata { +pub fn debugExpression(self: *Builder, elements: []const u32) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.Expression, elements.len); return self.debugExpressionAssumeCapacity(elements); } -pub fn metadataTuple( +pub fn metadataTuple(self: *Builder, elements: []const Metadata) Allocator.Error!Metadata { + return self.metadataTupleOptionals(@ptrCast(elements)); +} + +pub fn metadataTupleOptionals( self: *Builder, - elements: []const Metadata, + elements: []const Metadata.Optional, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.Tuple, elements.len); - return self.metadataTupleAssumeCapacity(elements); -} - -pub fn strTuple( - self: *Builder, - str: MetadataString, - elements: []const Metadata, -) Allocator.Error!Metadata { - try self.ensureUnusedMetadataCapacity(1, Metadata.StrTuple, elements.len); - return self.strTupleAssumeCapacity(str, elements); -} - -pub fn metadataModuleFlag( - self: *Builder, - behavior: Metadata, - name: MetadataString, - constant: Metadata, -) Allocator.Error!Metadata { - try self.ensureUnusedMetadataCapacity(1, Metadata.ModuleFlag, 0); - return self.metadataModuleFlagAssumeCapacity(behavior, name, constant); + return self.metadataTupleOptionalsAssumeCapacity(elements); } pub fn debugLocalVar( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - ty: Metadata, + ty: ?Metadata, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.LocalVar, 0); return self.debugLocalVarAssumeCapacity(name, file, scope, line, ty); @@ -12356,11 +12436,11 @@ pub fn debugLocalVar( pub fn debugParameter( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - ty: Metadata, + ty: ?Metadata, arg_no: u32, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.Parameter, 0); @@ -12369,12 +12449,12 @@ pub fn debugParameter( pub fn debugGlobalVar( self: *Builder, - name: MetadataString, - linkage_name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + linkage_name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - ty: Metadata, + ty: ?Metadata, variable: Variable.Index, options: Metadata.GlobalVar.Options, ) Allocator.Error!Metadata { @@ -12393,8 +12473,8 @@ pub fn debugGlobalVar( pub fn debugGlobalVarExpression( self: *Builder, - variable: Metadata, - expression: Metadata, + variable: ?Metadata, + expression: ?Metadata, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.GlobalVarExpression, 0); return self.debugGlobalVarExpressionAssumeCapacity(variable, expression); @@ -12405,13 +12485,11 @@ pub fn metadataConstant(self: *Builder, value: Constant) Allocator.Error!Metadat return self.metadataConstantAssumeCapacity(value); } -pub fn debugForwardReferenceSetType(self: *Builder, fwd_ref: Metadata, ty: Metadata) void { - assert( - @intFromEnum(fwd_ref) >= Metadata.first_forward_reference and - @intFromEnum(fwd_ref) <= Metadata.first_local_metadata, - ); - const index = @intFromEnum(fwd_ref) - Metadata.first_forward_reference; - self.metadata_forward_references.items[index] = ty; +pub fn resolveDebugForwardReference(self: *Builder, fwd_ref: Metadata, value: Metadata) void { + assert(fwd_ref.kind == .forward); + const resolved = &self.metadata_forward_references.items[fwd_ref.index]; + assert(resolved.is_none); + resolved.* = value.toOptional(); } fn metadataSimpleAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytype) Metadata { @@ -12450,41 +12528,20 @@ fn metadataSimpleAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytyp .data = self.addMetadataExtraAssumeCapacity(value), }); } - return @enumFromInt(gop.index); + return .{ .index = @intCast(gop.index), .kind = .node }; } fn metadataDistinctAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytype) Metadata { - const Key = struct { tag: Metadata.Tag, index: Metadata }; - const Adapter = struct { - pub fn hash(_: @This(), key: Key) u32 { - return @truncate(std.hash.Wyhash.hash( - std.hash.int(@intFromEnum(key.tag)), - std.mem.asBytes(&key.index), - )); - } - - pub fn eql(_: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { - return @intFromEnum(lhs_key.index) == rhs_index; - } - }; - - const gop = self.metadata_map.getOrPutAssumeCapacityAdapted( - Key{ .tag = tag, .index = @enumFromInt(self.metadata_map.count()) }, - Adapter{}, - ); - - if (!gop.found_existing) { - gop.key_ptr.* = {}; - gop.value_ptr.* = {}; - self.metadata_items.appendAssumeCapacity(.{ - .tag = tag, - .data = self.addMetadataExtraAssumeCapacity(value), - }); - } - return @enumFromInt(gop.index); + const index = self.metadata_items.len; + _ = self.metadata_map.entries.addOneAssumeCapacity(); + self.metadata_items.appendAssumeCapacity(.{ + .tag = tag, + .data = self.addMetadataExtraAssumeCapacity(value), + }); + return .{ .index = @intCast(index), .kind = .node }; } -fn metadataNamedAssumeCapacity(self: *Builder, name: MetadataString, operands: []const Metadata) void { +fn addNamedMetadataAssumeCapacity(self: *Builder, name: String, operands: []const Metadata) void { assert(name != .none); const extra_index: u32 = @intCast(self.metadata_extra.items.len); self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(operands)); @@ -12496,119 +12553,127 @@ fn metadataNamedAssumeCapacity(self: *Builder, name: MetadataString, operands: [ }; } -pub fn metadataNoneAssumeCapacity(self: *Builder) Metadata { - return self.metadataSimpleAssumeCapacity(.none, .{}); -} - fn debugFileAssumeCapacity( self: *Builder, - filename: MetadataString, - directory: MetadataString, + filename: ?Metadata.String, + directory: ?Metadata.String, ) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.file, Metadata.File{ - .filename = filename, - .directory = directory, + .filename = .wrap(filename), + .directory = .wrap(directory), }); } pub fn debugCompileUnitAssumeCapacity( self: *Builder, - file: Metadata, - producer: MetadataString, - enums: Metadata, - globals: Metadata, + file: ?Metadata, + producer: ?Metadata.String, + enums: ?Metadata, + globals: ?Metadata, options: Metadata.CompileUnit.Options, ) Metadata { assert(!self.strip); return self.metadataDistinctAssumeCapacity( if (options.optimized) .@"compile_unit optimized" else .compile_unit, Metadata.CompileUnit{ - .file = file, - .producer = producer, - .enums = enums, - .globals = globals, + .file = .wrap(file), + .producer = .wrap(producer), + .enums = .wrap(enums), + .globals = .wrap(globals), }, ); } fn debugSubprogramAssumeCapacity( self: *Builder, - file: Metadata, - name: MetadataString, - linkage_name: MetadataString, + file: ?Metadata, + name: ?Metadata.String, + linkage_name: ?Metadata.String, line: u32, scope_line: u32, - ty: Metadata, + ty: ?Metadata, options: Metadata.Subprogram.Options, - compile_unit: Metadata, + compile_unit: ?Metadata, ) Metadata { assert(!self.strip); const tag: Metadata.Tag = @enumFromInt(@intFromEnum(Metadata.Tag.subprogram) + @as(u3, @truncate(@as(u32, @bitCast(options.sp_flags)) >> 2))); return self.metadataDistinctAssumeCapacity(tag, Metadata.Subprogram{ - .file = file, - .name = name, - .linkage_name = linkage_name, + .file = .wrap(file), + .name = .wrap(name), + .linkage_name = .wrap(linkage_name), .line = line, .scope_line = scope_line, - .ty = ty, + .ty = .wrap(ty), .di_flags = options.di_flags, - .compile_unit = compile_unit, + .compile_unit = .wrap(compile_unit), }); } -fn debugLexicalBlockAssumeCapacity(self: *Builder, scope: Metadata, file: Metadata, line: u32, column: u32) Metadata { +fn debugLexicalBlockAssumeCapacity( + self: *Builder, + scope: ?Metadata, + file: ?Metadata, + line: u32, + column: u32, +) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.lexical_block, Metadata.LexicalBlock{ - .scope = scope, - .file = file, + .scope = .wrap(scope), + .file = .wrap(file), .line = line, .column = column, }); } -fn debugLocationAssumeCapacity(self: *Builder, line: u32, column: u32, scope: Metadata, inlined_at: Metadata) Metadata { +fn debugLocationAssumeCapacity( + self: *Builder, + line: u32, + column: u32, + scope: Metadata, + inlined_at: ?Metadata, +) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.location, Metadata.Location{ .line = line, .column = column, .scope = scope, - .inlined_at = inlined_at, + .inlined_at = .wrap(inlined_at), }); } -fn debugBoolTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { +fn debugBoolTypeAssumeCapacity(self: *Builder, name: ?Metadata.String, size_in_bits: u64) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.basic_bool_type, Metadata.BasicType{ - .name = name, + .name = .wrap(name), .size_in_bits_lo = @truncate(size_in_bits), .size_in_bits_hi = @truncate(size_in_bits >> 32), }); } -fn debugUnsignedTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { +fn debugUnsignedTypeAssumeCapacity(self: *Builder, name: ?Metadata.String, size_in_bits: u64) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.basic_unsigned_type, Metadata.BasicType{ - .name = name, + .name = .wrap(name), .size_in_bits_lo = @truncate(size_in_bits), .size_in_bits_hi = @truncate(size_in_bits >> 32), }); } -fn debugSignedTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { +fn debugSignedTypeAssumeCapacity(self: *Builder, name: ?Metadata.String, size_in_bits: u64) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.basic_signed_type, Metadata.BasicType{ - .name = name, + .name = .wrap(name), .size_in_bits_lo = @truncate(size_in_bits), .size_in_bits_hi = @truncate(size_in_bits >> 32), }); } -fn debugFloatTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { +fn debugFloatTypeAssumeCapacity(self: *Builder, name: ?Metadata.String, size_in_bits: u64) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.basic_float_type, Metadata.BasicType{ - .name = name, + .name = .wrap(name), .size_in_bits_lo = @truncate(size_in_bits), .size_in_bits_hi = @truncate(size_in_bits >> 32), }); @@ -12616,21 +12681,21 @@ fn debugFloatTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bi fn debugForwardReferenceAssumeCapacity(self: *Builder) Metadata { assert(!self.strip); - const index = Metadata.first_forward_reference + self.metadata_forward_references.items.len; + const index = self.metadata_forward_references.items.len; self.metadata_forward_references.appendAssumeCapacity(.none); - return @enumFromInt(index); + return .{ .index = @intCast(index), .kind = .forward }; } fn debugStructTypeAssumeCapacity( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Metadata { assert(!self.strip); return self.debugCompositeTypeAssumeCapacity( @@ -12648,14 +12713,14 @@ fn debugStructTypeAssumeCapacity( fn debugUnionTypeAssumeCapacity( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Metadata { assert(!self.strip); return self.debugCompositeTypeAssumeCapacity( @@ -12673,14 +12738,14 @@ fn debugUnionTypeAssumeCapacity( fn debugEnumerationTypeAssumeCapacity( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Metadata { assert(!self.strip); return self.debugCompositeTypeAssumeCapacity( @@ -12698,14 +12763,14 @@ fn debugEnumerationTypeAssumeCapacity( fn debugArrayTypeAssumeCapacity( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Metadata { assert(!self.strip); return self.debugCompositeTypeAssumeCapacity( @@ -12723,14 +12788,14 @@ fn debugArrayTypeAssumeCapacity( fn debugVectorTypeAssumeCapacity( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Metadata { assert(!self.strip); return self.debugCompositeTypeAssumeCapacity( @@ -12749,48 +12814,48 @@ fn debugVectorTypeAssumeCapacity( fn debugCompositeTypeAssumeCapacity( self: *Builder, tag: Metadata.Tag, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, - fields_tuple: Metadata, + fields_tuple: ?Metadata, ) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(tag, Metadata.CompositeType{ - .name = name, - .file = file, - .scope = scope, + .name = .wrap(name), + .file = .wrap(file), + .scope = .wrap(scope), .line = line, - .underlying_type = underlying_type, + .underlying_type = .wrap(underlying_type), .size_in_bits_lo = @truncate(size_in_bits), .size_in_bits_hi = @truncate(size_in_bits >> 32), .align_in_bits_lo = @truncate(align_in_bits), .align_in_bits_hi = @truncate(align_in_bits >> 32), - .fields_tuple = fields_tuple, + .fields_tuple = .wrap(fields_tuple), }); } fn debugPointerTypeAssumeCapacity( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, offset_in_bits: u64, ) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.derived_pointer_type, Metadata.DerivedType{ - .name = name, - .file = file, - .scope = scope, + .name = .wrap(name), + .file = .wrap(file), + .scope = .wrap(scope), .line = line, - .underlying_type = underlying_type, + .underlying_type = .wrap(underlying_type), .size_in_bits_lo = @truncate(size_in_bits), .size_in_bits_hi = @truncate(size_in_bits >> 32), .align_in_bits_lo = @truncate(align_in_bits), @@ -12802,22 +12867,22 @@ fn debugPointerTypeAssumeCapacity( fn debugMemberTypeAssumeCapacity( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - underlying_type: Metadata, + underlying_type: ?Metadata, size_in_bits: u64, align_in_bits: u64, offset_in_bits: u64, ) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.derived_member_type, Metadata.DerivedType{ - .name = name, - .file = file, - .scope = scope, + .name = .wrap(name), + .file = .wrap(file), + .scope = .wrap(scope), .line = line, - .underlying_type = underlying_type, + .underlying_type = .wrap(underlying_type), .size_in_bits_lo = @truncate(size_in_bits), .size_in_bits_hi = @truncate(size_in_bits >> 32), .align_in_bits_lo = @truncate(align_in_bits), @@ -12827,19 +12892,16 @@ fn debugMemberTypeAssumeCapacity( }); } -fn debugSubroutineTypeAssumeCapacity( - self: *Builder, - types_tuple: Metadata, -) Metadata { +fn debugSubroutineTypeAssumeCapacity(self: *Builder, types_tuple: ?Metadata) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.subroutine_type, Metadata.SubroutineType{ - .types_tuple = types_tuple, + .types_tuple = .wrap(types_tuple), }); } fn debugEnumeratorAssumeCapacity( self: *Builder, - name: MetadataString, + name: ?Metadata.String, unsigned: bool, bit_width: u32, value: std.math.big.int.Const, @@ -12847,7 +12909,7 @@ fn debugEnumeratorAssumeCapacity( assert(!self.strip); const Key = struct { tag: Metadata.Tag, - name: MetadataString, + name: Metadata.String.Optional, bit_width: u32, value: std.math.big.int.Const, }; @@ -12886,15 +12948,12 @@ fn debugEnumeratorAssumeCapacity( assert(!(tag == .enumerator_unsigned and !value.positive)); - const gop = self.metadata_map.getOrPutAssumeCapacityAdapted( - Key{ - .tag = tag, - .name = name, - .bit_width = bit_width, - .value = value, - }, - Adapter{ .builder = self }, - ); + const gop = self.metadata_map.getOrPutAssumeCapacityAdapted(Key{ + .tag = tag, + .name = .wrap(name), + .bit_width = bit_width, + .value = value, + }, Adapter{ .builder = self }); if (!gop.found_existing) { gop.key_ptr.* = {}; @@ -12902,7 +12961,7 @@ fn debugEnumeratorAssumeCapacity( self.metadata_items.appendAssumeCapacity(.{ .tag = tag, .data = self.addMetadataExtraAssumeCapacity(Metadata.Enumerator{ - .name = name, + .name = .wrap(name), .bit_width = bit_width, .limbs_index = @intCast(self.metadata_limbs.items.len), .limbs_len = @intCast(value.limbs.len), @@ -12910,25 +12969,18 @@ fn debugEnumeratorAssumeCapacity( }); self.metadata_limbs.appendSliceAssumeCapacity(value.limbs); } - return @enumFromInt(gop.index); + return .{ .index = @intCast(gop.index), .kind = .node }; } -fn debugSubrangeAssumeCapacity( - self: *Builder, - lower_bound: Metadata, - count: Metadata, -) Metadata { +fn debugSubrangeAssumeCapacity(self: *Builder, lower_bound: ?Metadata, count: ?Metadata) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.subrange, Metadata.Subrange{ - .lower_bound = lower_bound, - .count = count, + .lower_bound = .wrap(lower_bound), + .count = .wrap(count), }); } -fn debugExpressionAssumeCapacity( - self: *Builder, - elements: []const u32, -) Metadata { +fn debugExpressionAssumeCapacity(self: *Builder, elements: []const u32) Metadata { assert(!self.strip); const Key = struct { elements: []const u32, @@ -12936,13 +12988,15 @@ fn debugExpressionAssumeCapacity( const Adapter = struct { builder: *const Builder, pub fn hash(_: @This(), key: Key) u32 { - var hasher = comptime std.hash.Wyhash.init(std.hash.int(@intFromEnum(Metadata.Tag.expression))); + var hasher = + comptime std.hash.Wyhash.init(std.hash.int(@intFromEnum(Metadata.Tag.expression))); hasher.update(std.mem.sliceAsBytes(key.elements)); return @truncate(hasher.final()); } pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { - if (Metadata.Tag.expression != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false; + if (Metadata.Tag.expression != ctx.builder.metadata_items.items(.tag)[rhs_index]) + return false; const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index]; var rhs_extra = ctx.builder.metadataExtraDataTrail(Metadata.Expression, rhs_data); return std.mem.eql( @@ -12969,15 +13023,12 @@ fn debugExpressionAssumeCapacity( }); self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(elements)); } - return @enumFromInt(gop.index); + return .{ .index = @intCast(gop.index), .kind = .node }; } -fn metadataTupleAssumeCapacity( - self: *Builder, - elements: []const Metadata, -) Metadata { +fn metadataTupleOptionalsAssumeCapacity(self: *Builder, elements: []const Metadata.Optional) Metadata { const Key = struct { - elements: []const Metadata, + elements: []const Metadata.Optional, }; const Adapter = struct { builder: *const Builder, @@ -12992,9 +13043,9 @@ fn metadataTupleAssumeCapacity( const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index]; var rhs_extra = ctx.builder.metadataExtraDataTrail(Metadata.Tuple, rhs_data); return std.mem.eql( - Metadata, + Metadata.Optional, lhs_key.elements, - rhs_extra.trail.next(rhs_extra.data.elements_len, Metadata, ctx.builder), + rhs_extra.trail.next(rhs_extra.data.elements_len, Metadata.Optional, ctx.builder), ); } }; @@ -13015,117 +13066,55 @@ fn metadataTupleAssumeCapacity( }); self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(elements)); } - return @enumFromInt(gop.index); -} - -fn strTupleAssumeCapacity( - self: *Builder, - str: MetadataString, - elements: []const Metadata, -) Metadata { - const Key = struct { - str: MetadataString, - elements: []const Metadata, - }; - const Adapter = struct { - builder: *const Builder, - pub fn hash(_: @This(), key: Key) u32 { - var hasher = comptime std.hash.Wyhash.init(std.hash.int(@intFromEnum(Metadata.Tag.tuple))); - hasher.update(std.mem.sliceAsBytes(key.elements)); - return @truncate(hasher.final()); - } - - pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { - if (.str_tuple != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false; - const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index]; - var rhs_extra = ctx.builder.metadataExtraDataTrail(Metadata.StrTuple, rhs_data); - return rhs_extra.data.str == lhs_key.str and std.mem.eql( - Metadata, - lhs_key.elements, - rhs_extra.trail.next(rhs_extra.data.elements_len, Metadata, ctx.builder), - ); - } - }; - - const gop = self.metadata_map.getOrPutAssumeCapacityAdapted( - Key{ .str = str, .elements = elements }, - Adapter{ .builder = self }, - ); - - if (!gop.found_existing) { - gop.key_ptr.* = {}; - gop.value_ptr.* = {}; - self.metadata_items.appendAssumeCapacity(.{ - .tag = .str_tuple, - .data = self.addMetadataExtraAssumeCapacity(Metadata.StrTuple{ - .str = str, - .elements_len = @intCast(elements.len), - }), - }); - self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(elements)); - } - return @enumFromInt(gop.index); -} - -fn metadataModuleFlagAssumeCapacity( - self: *Builder, - behavior: Metadata, - name: MetadataString, - constant: Metadata, -) Metadata { - return self.metadataSimpleAssumeCapacity(.module_flag, Metadata.ModuleFlag{ - .behavior = behavior, - .name = name, - .constant = constant, - }); + return .{ .index = @intCast(gop.index), .kind = .node }; } fn debugLocalVarAssumeCapacity( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - ty: Metadata, + ty: ?Metadata, ) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.local_var, Metadata.LocalVar{ - .name = name, - .file = file, - .scope = scope, + .name = .wrap(name), + .file = .wrap(file), + .scope = .wrap(scope), .line = line, - .ty = ty, + .ty = .wrap(ty), }); } fn debugParameterAssumeCapacity( self: *Builder, - name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - ty: Metadata, + ty: ?Metadata, arg_no: u32, ) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.parameter, Metadata.Parameter{ - .name = name, - .file = file, - .scope = scope, + .name = .wrap(name), + .file = .wrap(file), + .scope = .wrap(scope), .line = line, - .ty = ty, + .ty = .wrap(ty), .arg_no = arg_no, }); } fn debugGlobalVarAssumeCapacity( self: *Builder, - name: MetadataString, - linkage_name: MetadataString, - file: Metadata, - scope: Metadata, + name: ?Metadata.String, + linkage_name: ?Metadata.String, + file: ?Metadata, + scope: ?Metadata, line: u32, - ty: Metadata, + ty: ?Metadata, variable: Variable.Index, options: Metadata.GlobalVar.Options, ) Metadata { @@ -13133,12 +13122,12 @@ fn debugGlobalVarAssumeCapacity( return self.metadataDistinctAssumeCapacity( if (options.local) .@"global_var local" else .global_var, Metadata.GlobalVar{ - .name = name, - .linkage_name = linkage_name, - .file = file, - .scope = scope, + .name = .wrap(name), + .linkage_name = .wrap(linkage_name), + .file = .wrap(file), + .scope = .wrap(scope), .line = line, - .ty = ty, + .ty = .wrap(ty), .variable = variable, }, ); @@ -13146,13 +13135,13 @@ fn debugGlobalVarAssumeCapacity( fn debugGlobalVarExpressionAssumeCapacity( self: *Builder, - variable: Metadata, - expression: Metadata, + variable: ?Metadata, + expression: ?Metadata, ) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(.global_var_expression, Metadata.GlobalVarExpression{ - .variable = variable, - .expression = expression, + .variable = .wrap(variable), + .expression = .wrap(expression), }); } @@ -13185,7 +13174,7 @@ fn metadataConstantAssumeCapacity(self: *Builder, constant: Constant) Metadata { .data = @intFromEnum(constant), }); } - return @enumFromInt(gop.index); + return .{ .index = @intCast(gop.index), .kind = .node }; } pub const Producer = struct { @@ -13209,8 +13198,8 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // IDENTIFICATION_BLOCK { - const Identification = ir.Identification; - var identification_block = try bitcode.enterTopBlock(Identification); + const IdentificationBlock = ir.IdentificationBlock; + var identification_block = try bitcode.enterTopBlock(IdentificationBlock); const producer_str = try std.fmt.allocPrint(self.gpa, "{s} {d}.{d}.{d}", .{ producer.name, @@ -13220,42 +13209,42 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco }); defer self.gpa.free(producer_str); - try identification_block.writeAbbrev(Identification.Version{ .string = producer_str }); - try identification_block.writeAbbrev(Identification.Epoch{ .epoch = 0 }); + try identification_block.writeAbbrev(IdentificationBlock.Version{ .string = producer_str }); + try identification_block.writeAbbrev(IdentificationBlock.Epoch{ .epoch = 0 }); try identification_block.end(); } // MODULE_BLOCK { - const Module = ir.Module; - var module_block = try bitcode.enterTopBlock(Module); + const ModuleBlock = ir.ModuleBlock; + var module_block = try bitcode.enterTopBlock(ModuleBlock); - try module_block.writeAbbrev(Module.Version{}); + try module_block.writeAbbrev(ModuleBlock.Version{}); if (self.target_triple.slice(self)) |triple| { - try module_block.writeAbbrev(Module.String{ + try module_block.writeAbbrev(ModuleBlock.String{ .code = 2, .string = triple, }); } if (self.data_layout.slice(self)) |data_layout| { - try module_block.writeAbbrev(Module.String{ + try module_block.writeAbbrev(ModuleBlock.String{ .code = 3, .string = data_layout, }); } if (self.source_filename.slice(self)) |source_filename| { - try module_block.writeAbbrev(Module.String{ + try module_block.writeAbbrev(ModuleBlock.String{ .code = 16, .string = source_filename, }); } if (self.module_asm.items.len != 0) { - try module_block.writeAbbrev(Module.String{ + try module_block.writeAbbrev(ModuleBlock.String{ .code = 4, .string = self.module_asm.items, }); @@ -13263,16 +13252,17 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // TYPE_BLOCK { - var type_block = try module_block.enterSubBlock(ir.Type, true); + const TypeBlock = ir.ModuleBlock.TypeBlock; + var type_block = try module_block.enterSubBlock(TypeBlock, true); - try type_block.writeAbbrev(ir.Type.NumEntry{ .num = @intCast(self.type_items.items.len) }); + try type_block.writeAbbrev(TypeBlock.NumEntry{ .num = @intCast(self.type_items.items.len) }); for (self.type_items.items, 0..) |item, i| { const ty: Type = @enumFromInt(i); switch (item.tag) { - .simple => try type_block.writeAbbrev(ir.Type.Simple{ .code = @truncate(item.data) }), - .integer => try type_block.writeAbbrev(ir.Type.Integer{ .width = item.data }), + .simple => try type_block.writeAbbrev(TypeBlock.Simple{ .code = @enumFromInt(item.data) }), + .integer => try type_block.writeAbbrev(TypeBlock.Integer{ .width = item.data }), .structure, .packed_structure, => |kind| { @@ -13282,19 +13272,19 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco else => unreachable, }; var extra = self.typeExtraDataTrail(Type.Structure, item.data); - try type_block.writeAbbrev(ir.Type.StructAnon{ + try type_block.writeAbbrev(TypeBlock.StructAnon{ .is_packed = is_packed, .types = extra.trail.next(extra.data.fields_len, Type, self), }); }, .named_structure => { const extra = self.typeExtraData(Type.NamedStructure, item.data); - try type_block.writeAbbrev(ir.Type.StructName{ + try type_block.writeAbbrev(TypeBlock.StructName{ .string = extra.id.slice(self).?, }); switch (extra.body) { - .none => try type_block.writeAbbrev(ir.Type.Opaque{}), + .none => try type_block.writeAbbrev(TypeBlock.Opaque{}), else => { const real_struct = self.type_items.items[@intFromEnum(extra.body)]; const is_packed: bool = switch (real_struct.tag) { @@ -13304,7 +13294,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco }; var real_extra = self.typeExtraDataTrail(Type.Structure, real_struct.data); - try type_block.writeAbbrev(ir.Type.StructNamed{ + try type_block.writeAbbrev(TypeBlock.StructNamed{ .is_packed = is_packed, .types = real_extra.trail.next(real_extra.data.fields_len, Type, self), }); @@ -13313,29 +13303,29 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco }, .array, .small_array, - => try type_block.writeAbbrev(ir.Type.Array{ + => try type_block.writeAbbrev(TypeBlock.Array{ .len = ty.aggregateLen(self), .child = ty.childType(self), }), .vector, .scalable_vector, - => try type_block.writeAbbrev(ir.Type.Vector{ + => try type_block.writeAbbrev(TypeBlock.Vector{ .len = ty.aggregateLen(self), .child = ty.childType(self), }), - .pointer => try type_block.writeAbbrev(ir.Type.Pointer{ + .pointer => try type_block.writeAbbrev(TypeBlock.Pointer{ .addr_space = ty.pointerAddrSpace(self), }), .target => { var extra = self.typeExtraDataTrail(Type.Target, item.data); - try type_block.writeAbbrev(ir.Type.StructName{ + try type_block.writeAbbrev(TypeBlock.StructName{ .string = extra.data.name.slice(self).?, }); const types = extra.trail.next(extra.data.types_len, Type, self); const ints = extra.trail.next(extra.data.ints_len, u32, self); - try type_block.writeAbbrev(ir.Type.Target{ + try type_block.writeAbbrev(TypeBlock.Target{ .num_types = extra.data.types_len, .types = types, .ints = ints, @@ -13348,7 +13338,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco else => unreachable, }; var extra = self.typeExtraDataTrail(Type.Function, item.data); - try type_block.writeAbbrev(ir.Type.Function{ + try type_block.writeAbbrev(TypeBlock.Function{ .is_vararg = is_vararg, .return_type = extra.data.ret, .param_types = extra.trail.next(extra.data.params_len, Type, self), @@ -13368,9 +13358,9 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // PARAMATTR_GROUP_BLOCK { - const ParamattrGroup = ir.ParamattrGroup; + const ParamattrGroupBlock = ir.ModuleBlock.ParamattrGroupBlock; - var paramattr_group_block = try module_block.enterSubBlock(ParamattrGroup, true); + var paramattr_group_block = try module_block.enterSubBlock(ParamattrGroupBlock, true); for (self.function_attributes_set.keys()) |func_attributes| { for (func_attributes.slice(self), 0..) |attributes, i| { @@ -13572,8 +13562,8 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // PARAMATTR_BLOCK { - const Paramattr = ir.Paramattr; - var paramattr_block = try module_block.enterSubBlock(Paramattr, true); + const ParamattrBlock = ir.ModuleBlock.ParamattrBlock; + var paramattr_block = try module_block.enterSubBlock(ParamattrBlock, true); for (self.function_attributes_set.keys()) |func_attributes| { const func_attributes_slice = func_attributes.slice(self); @@ -13590,7 +13580,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco record.appendAssumeCapacity(@intCast(group_index)); } - try paramattr_block.writeAbbrev(Paramattr.Entry{ .group_indices = record.items }); + try paramattr_block.writeAbbrev(ParamattrBlock.Entry{ .group_indices = record.items }); } try paramattr_block.end(); @@ -13624,38 +13614,35 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco } const ConstantAdapter = struct { - const ConstantAdapter = @This(); builder: *const Builder, globals: *const std.AutoArrayHashMapUnmanaged(Global.Index, void), - pub fn get(adapter: @This(), param: anytype, comptime field_name: []const u8) @TypeOf(param) { - _ = field_name; + pub fn get(adapter: @This(), param: anytype) switch (@TypeOf(param)) { + Constant => u32, + else => |Param| Param, + } { return switch (@TypeOf(param)) { - Constant => @enumFromInt(adapter.getConstantIndex(param)), + Constant => adapter.getConstantIndex(param), else => param, }; } - pub fn getConstantIndex(adapter: ConstantAdapter, constant: Constant) u32 { + pub fn getConstantIndex(adapter: @This(), constant: Constant) u32 { return switch (constant.unwrap()) { .constant => |c| c + adapter.numGlobals(), .global => |global| @intCast(adapter.globals.getIndex(global.unwrap(adapter.builder)).?), }; } - pub fn numConstants(adapter: ConstantAdapter) u32 { + pub fn numConstants(adapter: @This()) u32 { return @intCast(adapter.globals.count() + adapter.builder.constant_items.len); } - pub fn numGlobals(adapter: ConstantAdapter) u32 { + pub fn numGlobals(adapter: @This()) u32 { return @intCast(adapter.globals.count()); } }; - - const constant_adapter = ConstantAdapter{ - .builder = self, - .globals = &globals, - }; + const constant_adapter: ConstantAdapter = .{ .builder = self, .globals = &globals }; // Globals { @@ -13670,7 +13657,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco if (variable.section == .none) break :blk 0; const gop = section_map.getOrPutAssumeCapacity(variable.section); if (!gop.found_existing) { - try module_block.writeAbbrev(Module.String{ + try module_block.writeAbbrev(ModuleBlock.String{ .code = 5, .string = variable.section.slice(self).?, }); @@ -13686,7 +13673,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco const strtab = variable.global.strtab(self); const global = variable.global.ptrConst(self); - try module_block.writeAbbrev(Module.Variable{ + try module_block.writeAbbrev(ModuleBlock.Variable{ .strtab_offset = strtab.offset, .strtab_size = strtab.size, .type_index = global.type, @@ -13717,7 +13704,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco if (func.section == .none) break :blk 0; const gop = section_map.getOrPutAssumeCapacity(func.section); if (!gop.found_existing) { - try module_block.writeAbbrev(Module.String{ + try module_block.writeAbbrev(ModuleBlock.String{ .code = 5, .string = func.section.slice(self).?, }); @@ -13733,7 +13720,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco const strtab = func.global.strtab(self); const global = func.global.ptrConst(self); - try module_block.writeAbbrev(Module.Function{ + try module_block.writeAbbrev(ModuleBlock.Function{ .strtab_offset = strtab.offset, .strtab_size = strtab.size, .type_index = global.type, @@ -13757,7 +13744,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco const strtab = alias.global.strtab(self); const global = alias.global.ptrConst(self); - try module_block.writeAbbrev(Module.Alias{ + try module_block.writeAbbrev(ModuleBlock.Alias{ .strtab_offset = strtab.offset, .strtab_size = strtab.size, .type_index = global.type, @@ -13775,8 +13762,8 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // CONSTANTS_BLOCK { - const Constants = ir.Constants; - var constants_block = try module_block.enterSubBlock(Constants, true); + const ConstantsBlock = ir.ModuleBlock.ConstantsBlock; + var constants_block = try module_block.enterSubBlock(ConstantsBlock, true); var current_type: Type = .none; const tags = self.constant_items.items(.tag); @@ -13786,7 +13773,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco const constant: Constant = @enumFromInt(index); const constant_type = constant.typeOf(self); if (constant_type != current_type) { - try constants_block.writeAbbrev(Constants.SetType{ .type_id = constant_type }); + try constants_block.writeAbbrev(ConstantsBlock.SetType{ .type_id = constant_type }); current_type = constant_type; } const data = datas[index]; @@ -13794,9 +13781,9 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco .null, .zeroinitializer, .none, - => try constants_block.writeAbbrev(Constants.Null{}), - .undef => try constants_block.writeAbbrev(Constants.Undef{}), - .poison => try constants_block.writeAbbrev(Constants.Poison{}), + => try constants_block.writeAbbrev(ConstantsBlock.Null{}), + .undef => try constants_block.writeAbbrev(ConstantsBlock.Undef{}), + .poison => try constants_block.writeAbbrev(ConstantsBlock.Poison{}), .positive_integer, .negative_integer, => |tag| { @@ -13832,7 +13819,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco try constants_block.writeUnabbrev(5, record.items); continue; }; - try constants_block.writeAbbrev(Constants.Integer{ + try constants_block.writeAbbrev(ConstantsBlock.Integer{ .value = @bitCast(if (val >= 0) val << 1 | 0 else @@ -13841,17 +13828,17 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco }, .half, .bfloat, - => try constants_block.writeAbbrev(Constants.Half{ .value = @truncate(data) }), - .float => try constants_block.writeAbbrev(Constants.Float{ .value = data }), + => try constants_block.writeAbbrev(ConstantsBlock.Half{ .value = @truncate(data) }), + .float => try constants_block.writeAbbrev(ConstantsBlock.Float{ .value = data }), .double => { const extra = self.constantExtraData(Constant.Double, data); - try constants_block.writeAbbrev(Constants.Double{ + try constants_block.writeAbbrev(ConstantsBlock.Double{ .value = (@as(u64, extra.hi) << 32) | extra.lo, }); }, .x86_fp80 => { const extra = self.constantExtraData(Constant.Fp80, data); - try constants_block.writeAbbrev(Constants.Fp80{ + try constants_block.writeAbbrev(ConstantsBlock.Fp80{ .hi = @as(u64, extra.hi) << 48 | @as(u64, extra.lo_hi) << 16 | extra.lo_lo >> 16, .lo = @truncate(extra.lo_lo), @@ -13861,7 +13848,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco .ppc_fp128, => { const extra = self.constantExtraData(Constant.Fp128, data); - try constants_block.writeAbbrev(Constants.Fp128{ + try constants_block.writeAbbrev(ConstantsBlock.Fp128{ .lo = @as(u64, extra.lo_hi) << 32 | @as(u64, extra.lo_lo), .hi = @as(u64, extra.hi_hi) << 32 | @as(u64, extra.hi_lo), }); @@ -13876,35 +13863,35 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco const values = extra.trail.next(len, Constant, self); try constants_block.writeAbbrevAdapted( - Constants.Aggregate{ .values = values }, + ConstantsBlock.Aggregate{ .values = values }, constant_adapter, ); }, .splat => { - const ConstantsWriter = @TypeOf(constants_block); + const ConstantsBlockWriter = @TypeOf(constants_block); const extra = self.constantExtraData(Constant.Splat, data); const vector_len = extra.type.vectorLen(self); const c = constant_adapter.getConstantIndex(extra.value); try bitcode.writeBits( - ConstantsWriter.abbrevId(Constants.Aggregate), - ConstantsWriter.abbrev_len, + ConstantsBlockWriter.abbrevId(ConstantsBlock.Aggregate), + ConstantsBlockWriter.abbrev_len, ); - try bitcode.writeVBR(vector_len, 6); + try bitcode.writeVbr(vector_len, 6); for (0..vector_len) |_| { - try bitcode.writeBits(c, Constants.Aggregate.ops[1].array_fixed); + try bitcode.writeBits(c, ConstantsBlock.Aggregate.ops[1].array_fixed); } }, .string => { const str: String = @enumFromInt(data); if (str == .none) { - try constants_block.writeAbbrev(Constants.Null{}); + try constants_block.writeAbbrev(ConstantsBlock.Null{}); } else { const slice = str.slice(self).?; if (slice.len > 0 and slice[slice.len - 1] == 0) - try constants_block.writeAbbrev(Constants.CString{ .string = slice[0 .. slice.len - 1] }) + try constants_block.writeAbbrev(ConstantsBlock.CString{ .string = slice[0 .. slice.len - 1] }) else - try constants_block.writeAbbrev(Constants.String{ .string = slice }); + try constants_block.writeAbbrev(ConstantsBlock.String{ .string = slice }); } }, .bitcast, @@ -13914,7 +13901,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco .trunc, => |tag| { const extra = self.constantExtraData(Constant.Cast, data); - try constants_block.writeAbbrevAdapted(Constants.Cast{ + try constants_block.writeAbbrevAdapted(ConstantsBlock.Cast{ .type_index = extra.type, .val = extra.val, .opcode = tag.toCastOpcode(), @@ -13930,7 +13917,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco .xor, => |tag| { const extra = self.constantExtraData(Constant.Binary, data); - try constants_block.writeAbbrevAdapted(Constants.Binary{ + try constants_block.writeAbbrevAdapted(ConstantsBlock.Binary{ .opcode = tag.toBinaryOpcode(), .lhs = extra.lhs, .rhs = extra.rhs, @@ -14014,7 +14001,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco }, .blockaddress => { const extra = self.constantExtraData(Constant.BlockAddress, data); - try constants_block.writeAbbrev(Constants.BlockAddress{ + try constants_block.writeAbbrev(ConstantsBlock.BlockAddress{ .type_id = extra.function.typeOf(self), .function = constant_adapter.getConstantIndex(extra.function.toConst(self)), .block = @intFromEnum(extra.block), @@ -14024,10 +14011,10 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco .no_cfi, => |tag| { const function: Function.Index = @enumFromInt(data); - try constants_block.writeAbbrev(Constants.DsoLocalEquivalentOrNoCfi{ + try constants_block.writeAbbrev(ConstantsBlock.DsoLocalEquivalentOrNoCfi{ .code = switch (tag) { - .dso_local_equivalent => 27, - .no_cfi => 29, + .dso_local_equivalent => .DSO_LOCAL_EQUIVALENT, + .no_cfi => .NO_CFI_VALUE, else => unreachable, }, .type_id = function.typeOf(self), @@ -14042,7 +14029,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // METADATA_KIND_BLOCK { - const MetadataKindBlock = ir.MetadataKindBlock; + const MetadataKindBlock = ir.ModuleBlock.MetadataKindBlock; var metadata_kind_block = try module_block.enterSubBlock(MetadataKindBlock, true); inline for (@typeInfo(ir.FixedMetadataKind).@"enum".fields) |field| { @@ -14059,95 +14046,85 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco } const MetadataAdapter = struct { - builder: *const Builder, constant_adapter: ConstantAdapter, - pub fn init( - builder: *const Builder, - const_adapter: ConstantAdapter, - ) @This() { - return .{ - .builder = builder, - .constant_adapter = const_adapter, - }; - } - - pub fn get(adapter: @This(), value: anytype, comptime field_name: []const u8) @TypeOf(value) { - _ = field_name; - const Ty = @TypeOf(value); - return switch (Ty) { - Metadata => @enumFromInt(adapter.getMetadataIndex(value)), - MetadataString => @enumFromInt(adapter.getMetadataStringIndex(value)), - Constant => @enumFromInt(adapter.constant_adapter.getConstantIndex(value)), - else => value, + pub fn get(adapter: @This(), param: anytype) switch (@TypeOf(param)) { + Metadata, Metadata.Optional, Metadata.String, Metadata.String.Optional, Constant => u32, + else => |Result| Result, + } { + return switch (@TypeOf(param)) { + Metadata => adapter.getMetadataIndex(param), + Metadata.Optional => adapter.getOptionalMetadataIndex(param), + Metadata.String => adapter.getMetadataIndex(param.toMetadata()), + Metadata.String.Optional => adapter.getOptionalMetadataIndex(param.toMetadata()), + Constant => adapter.constant_adapter.getConstantIndex(param), + else => param, }; } pub fn getMetadataIndex(adapter: @This(), metadata: Metadata) u32 { - if (metadata == .none) return 0; - return @intCast(adapter.builder.metadata_string_map.count() + - @intFromEnum(metadata.unwrap(adapter.builder)) - 1); + const builder = adapter.constant_adapter.builder; + const unwrapped_metadata = metadata.unwrap(builder); + return switch (unwrapped_metadata.kind) { + .string => unwrapped_metadata.index, + .node => @intCast(builder.metadata_string_map.count() + unwrapped_metadata.index), + .forward, .local => unreachable, + }; } - pub fn getMetadataStringIndex(_: @This(), metadata_string: MetadataString) u32 { - return @intFromEnum(metadata_string); + pub fn getOptionalMetadataIndex(adapter: @This(), metadata: Metadata.Optional) u32 { + return if (metadata.unwrap()) |m| 1 + adapter.getMetadataIndex(m) else 0; } }; - - const metadata_adapter = MetadataAdapter.init(self, constant_adapter); + const metadata_adapter: MetadataAdapter = .{ .constant_adapter = constant_adapter }; // METADATA_BLOCK { - const MetadataBlock = ir.MetadataBlock; + const MetadataBlock = ir.ModuleBlock.MetadataBlock; var metadata_block = try module_block.enterSubBlock(MetadataBlock, true); const MetadataBlockWriter = @TypeOf(metadata_block); - // Emit all MetadataStrings - if (self.metadata_string_map.count() > 1) { - const strings_offset, const strings_size = blk: { - var strings_offset: u32 = 0; - var strings_size: u32 = 0; - for (1..self.metadata_string_map.count()) |metadata_string_index| { - const metadata_string: MetadataString = @enumFromInt(metadata_string_index); - const slice = metadata_string.slice(self); - strings_offset += bitcode.bitsVBR(@as(u32, @intCast(slice.len)), 6); - strings_size += @intCast(slice.len * 8); - } - break :blk .{ - std.mem.alignForward(u32, strings_offset, 32) / 8, - std.mem.alignForward(u32, strings_size, 32) / 8, - }; + // Emit all Metadata.Strings + const strings_len: u32 = @intCast(self.metadata_string_map.count()); + if (strings_len > 0) { + const string_bytes_offset = string_bytes_offset: { + var string_bytes_bit_offset: u32 = 0; + for ( + self.metadata_string_indices.items[0..strings_len], + self.metadata_string_indices.items[1..], + ) |start, end| string_bytes_bit_offset += BitcodeWriter.bitsVbr(end - start, 6); + break :string_bytes_offset @divExact( + std.mem.alignForward(u32, string_bytes_bit_offset, 32), + 8, + ); }; + const string_bytes_len = + std.mem.alignForward(u32, @intCast(self.metadata_string_bytes.items.len), 4); try bitcode.writeBits( comptime MetadataBlockWriter.abbrevId(MetadataBlock.Strings), MetadataBlockWriter.abbrev_len, ); - try bitcode.writeVBR(@as(u32, @intCast(self.metadata_string_map.count() - 1)), 6); - try bitcode.writeVBR(strings_offset, 6); + try bitcode.writeVbr(strings_len, 6); + try bitcode.writeVbr(string_bytes_offset, 6); - try bitcode.writeVBR(strings_size + strings_offset, 6); + try bitcode.writeVbr(string_bytes_offset + string_bytes_len, 6); try bitcode.alignTo32(); - for (1..self.metadata_string_map.count()) |metadata_string_index| { - const metadata_string: MetadataString = @enumFromInt(metadata_string_index); - const slice = metadata_string.slice(self); - try bitcode.writeVBR(@as(u32, @intCast(slice.len)), 6); - } + for ( + self.metadata_string_indices.items[0..strings_len], + self.metadata_string_indices.items[1..], + ) |start, end| try bitcode.writeVbr(end - start, 6); try bitcode.writeBlob(self.metadata_string_bytes.items); } - for ( - self.metadata_items.items(.tag)[1..], - self.metadata_items.items(.data)[1..], - ) |tag, data| { + for (self.metadata_items.items(.tag), self.metadata_items.items(.data)) |tag, data| { record.clearRetainingCapacity(); switch (tag) { - .none => unreachable, .file => { const extra = self.metadataExtraData(Metadata.File, data); @@ -14209,13 +14186,12 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco }, .location => { const extra = self.metadataExtraData(Metadata.Location, data); - assert(extra.scope != .none); - try metadata_block.writeAbbrev(MetadataBlock.Location{ + try metadata_block.writeAbbrevAdapted(MetadataBlock.Location{ .line = extra.line, .column = extra.column, - .scope = metadata_adapter.getMetadataIndex(extra.scope) - 1, - .inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(extra.inlined_at)), - }); + .scope = extra.scope, + .inlined_at = extra.inlined_at, + }, metadata_adapter); }, .basic_bool_type, .basic_unsigned_type, @@ -14325,7 +14301,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco @bitCast(flags), )); record.appendAssumeCapacity(extra.bit_width); - record.appendAssumeCapacity(metadata_adapter.getMetadataStringIndex(extra.name)); + record.appendAssumeCapacity(metadata_adapter.getOptionalMetadataIndex(extra.name.toMetadata())); const limbs = record.addManyAsSliceAssumeCapacity(limbs_len); bigint.writeTwosComplement(std.mem.sliceAsBytes(limbs), .little); for (limbs) |*limb| { @@ -14335,7 +14311,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco else -%val << 1 | 1); } - try metadata_block.writeUnabbrev(@intFromEnum(MetadataBlock.Enumerator.id), record.items); + try metadata_block.writeUnabbrev(@intFromEnum(MetadataBlock.Code.ENUMERATOR), record.items); continue; }; try metadata_block.writeAbbrevAdapted(MetadataBlock.Enumerator{ @@ -14350,7 +14326,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco }, .subrange => { const extra = self.metadataExtraData(Metadata.Subrange, data); - try metadata_block.writeAbbrevAdapted(MetadataBlock.Subrange{ .count = extra.count, .lower_bound = extra.lower_bound, @@ -14358,48 +14333,19 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco }, .expression => { var extra = self.metadataExtraDataTrail(Metadata.Expression, data); - const elements = extra.trail.next(extra.data.elements_len, u32, self); - try metadata_block.writeAbbrevAdapted(MetadataBlock.Expression{ .elements = elements, }, metadata_adapter); }, .tuple => { var extra = self.metadataExtraDataTrail(Metadata.Tuple, data); - - const elements = extra.trail.next(extra.data.elements_len, Metadata, self); - + const elements = + extra.trail.next(extra.data.elements_len, Metadata.Optional, self); try metadata_block.writeAbbrevAdapted(MetadataBlock.Node{ .elements = elements, }, metadata_adapter); }, - .str_tuple => { - var extra = self.metadataExtraDataTrail(Metadata.StrTuple, data); - - const elements = extra.trail.next(extra.data.elements_len, Metadata, self); - - const all_elems = try self.gpa.alloc(Metadata, elements.len + 1); - defer self.gpa.free(all_elems); - all_elems[0] = @enumFromInt(metadata_adapter.getMetadataStringIndex(extra.data.str)); - for (elements, all_elems[1..]) |elem, *out_elem| { - out_elem.* = @enumFromInt(metadata_adapter.getMetadataIndex(elem)); - } - - try metadata_block.writeAbbrev(MetadataBlock.Node{ - .elements = all_elems, - }); - }, - .module_flag => { - const extra = self.metadataExtraData(Metadata.ModuleFlag, data); - try metadata_block.writeAbbrev(MetadataBlock.Node{ - .elements = &.{ - @enumFromInt(metadata_adapter.getMetadataIndex(extra.behavior)), - @enumFromInt(metadata_adapter.getMetadataStringIndex(extra.name)), - @enumFromInt(metadata_adapter.getMetadataIndex(extra.constant)), - }, - }); - }, .local_var => { const extra = self.metadataExtraData(Metadata.LocalVar, data); try metadata_block.writeAbbrevAdapted(MetadataBlock.LocalVar{ @@ -14454,37 +14400,28 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // Write named metadata for (self.metadata_named.keys(), self.metadata_named.values()) |name, operands| { - const slice = name.slice(self); - try metadata_block.writeAbbrev(MetadataBlock.Name{ - .name = slice, - }); - - const elements = self.metadata_extra.items[operands.index..][0..operands.len]; - for (elements) |*e| { - e.* = metadata_adapter.getMetadataIndex(@enumFromInt(e.*)) - 1; - } - - try metadata_block.writeAbbrev(MetadataBlock.NamedNode{ - .elements = @ptrCast(elements), - }); + try metadata_block.writeAbbrev(MetadataBlock.Name{ .name = name.slice(self).? }); + try metadata_block.writeAbbrevAdapted(MetadataBlock.NamedNode{ + .elements = @ptrCast(self.metadata_extra.items[operands.index..][0..operands.len]), + }, metadata_adapter); } // Write global attached metadata { - for (globals.keys()) |global| { - const global_ptr = global.ptrConst(self); - if (global_ptr.dbg == .none) continue; + for (globals.keys()) |global_index| { + const global = global_index.ptrConst(self); + if (global.dbg.unwrap()) |dbg| { + switch (global.kind) { + .function => |f| if (f.ptrConst(self).instructions.len != 0) continue, + else => {}, + } - switch (global_ptr.kind) { - .function => |f| if (f.ptrConst(self).instructions.len != 0) continue, - else => {}, + try metadata_block.writeAbbrevAdapted(MetadataBlock.GlobalDeclAttachment{ + .value = global_index.toConst(), + .kind = .dbg, + .metadata = dbg, + }, metadata_adapter); } - - try metadata_block.writeAbbrev(MetadataBlock.GlobalDeclAttachment{ - .value = @enumFromInt(constant_adapter.getConstantIndex(global.toConst())), - .kind = .dbg, - .metadata = @enumFromInt(metadata_adapter.getMetadataIndex(global_ptr.dbg) - 1), - }); } } @@ -14493,10 +14430,10 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // OPERAND_BUNDLE_TAGS_BLOCK { - const OperandBundleTags = ir.OperandBundleTags; - var operand_bundle_tags_block = try module_block.enterSubBlock(OperandBundleTags, true); + const OperandBundleTagsBlock = ir.ModuleBlock.OperandBundleTagsBlock; + var operand_bundle_tags_block = try module_block.enterSubBlock(OperandBundleTagsBlock, true); - try operand_bundle_tags_block.writeAbbrev(OperandBundleTags.OperandBundleTag{ + try operand_bundle_tags_block.writeAbbrev(OperandBundleTagsBlock.OperandBundleTag{ .tag = "cold", }); @@ -14505,26 +14442,34 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // Block info { - const BlockInfo = ir.BlockInfo; - var block_info_block = try module_block.enterSubBlock(BlockInfo, true); + const BlockInfoBlock = ir.BlockInfoBlock; + var block_info_block = try module_block.enterSubBlock(BlockInfoBlock, true); - try block_info_block.writeUnabbrev(BlockInfo.set_block_id, &.{ir.FunctionBlock.id}); - inline for (ir.FunctionBlock.abbrevs) |abbrev| { + try block_info_block.writeUnabbrev(BlockInfoBlock.set_block_id, &.{ + @intFromEnum(ir.ModuleBlock.FunctionBlock.id), + }); + inline for (ir.ModuleBlock.FunctionBlock.abbrevs) |abbrev| { try block_info_block.defineAbbrev(&abbrev.ops); } - try block_info_block.writeUnabbrev(BlockInfo.set_block_id, &.{ir.FunctionValueSymbolTable.id}); - inline for (ir.FunctionValueSymbolTable.abbrevs) |abbrev| { + try block_info_block.writeUnabbrev(BlockInfoBlock.set_block_id, &.{ + @intFromEnum(ir.ModuleBlock.FunctionBlock.ValueSymtabBlock.id), + }); + inline for (ir.ModuleBlock.FunctionBlock.ValueSymtabBlock.abbrevs) |abbrev| { try block_info_block.defineAbbrev(&abbrev.ops); } - try block_info_block.writeUnabbrev(BlockInfo.set_block_id, &.{ir.FunctionMetadataBlock.id}); - inline for (ir.FunctionMetadataBlock.abbrevs) |abbrev| { + try block_info_block.writeUnabbrev(BlockInfoBlock.set_block_id, &.{ + @intFromEnum(ir.ModuleBlock.FunctionBlock.MetadataBlock.id), + }); + inline for (ir.ModuleBlock.FunctionBlock.MetadataBlock.abbrevs) |abbrev| { try block_info_block.defineAbbrev(&abbrev.ops); } - try block_info_block.writeUnabbrev(BlockInfo.set_block_id, &.{ir.MetadataAttachmentBlock.id}); - inline for (ir.MetadataAttachmentBlock.abbrevs) |abbrev| { + try block_info_block.writeUnabbrev(BlockInfoBlock.set_block_id, &.{ + @intFromEnum(ir.ModuleBlock.FunctionBlock.MetadataAttachmentBlock.id), + }); + inline for (ir.ModuleBlock.FunctionBlock.MetadataAttachmentBlock.abbrevs) |abbrev| { try block_info_block.defineAbbrev(&abbrev.ops); } @@ -14534,38 +14479,40 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // FUNCTION_BLOCKS { const FunctionAdapter = struct { - constant_adapter: ConstantAdapter, metadata_adapter: MetadataAdapter, func: *const Function, instruction_index: Function.Instruction.Index, - pub fn get(adapter: @This(), value: anytype, comptime field_name: []const u8) @TypeOf(value) { - _ = field_name; - const Ty = @TypeOf(value); - return switch (Ty) { - Value => @enumFromInt(adapter.getOffsetValueIndex(value)), - Constant => @enumFromInt(adapter.getOffsetConstantIndex(value)), - FunctionAttributes => @enumFromInt(switch (value) { + pub fn get(adapter: @This(), param: anytype) switch (@TypeOf(param)) { + Value, Constant, FunctionAttributes => u32, + else => |Result| Result, + } { + return switch (@TypeOf(param)) { + Value => adapter.getOffsetValueIndex(param), + Constant => adapter.getOffsetConstantIndex(param), + FunctionAttributes => switch (param) { .none => 0, - else => 1 + adapter.constant_adapter.builder.function_attributes_set.getIndex(value).?, - }), - else => value, + else => @intCast(1 + adapter.metadata_adapter.constant_adapter.builder + .function_attributes_set.getIndex(param).?), + }, + else => param, }; } pub fn getValueIndex(adapter: @This(), value: Value) u32 { return @intCast(switch (value.unwrap()) { .instruction => |instruction| instruction.valueIndex(adapter.func) + adapter.firstInstr(), - .constant => |constant| adapter.constant_adapter.getConstantIndex(constant), + .constant => |constant| adapter.metadata_adapter.constant_adapter.getConstantIndex(constant), .metadata => |metadata| { - const real_metadata = metadata.unwrap(adapter.metadata_adapter.builder); - if (@intFromEnum(real_metadata) < Metadata.first_local_metadata) - return adapter.metadata_adapter.getMetadataIndex(real_metadata) - 1; - - return @intCast(@intFromEnum(metadata) - - Metadata.first_local_metadata + - adapter.metadata_adapter.builder.metadata_string_map.count() - 1 + - adapter.metadata_adapter.builder.metadata_map.count() - 1); + const builder = adapter.metadata_adapter.constant_adapter.builder; + const unwrapped_metadata = metadata.unwrap(builder); + return switch (unwrapped_metadata.kind) { + .string, .node => adapter.metadata_adapter.getMetadataIndex(unwrapped_metadata), + .forward => unreachable, + .local => @intCast(builder.metadata_string_map.count() + + builder.metadata_map.count() + + unwrapped_metadata.index), + }; }, }); } @@ -14589,12 +14536,12 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco } fn firstInstr(adapter: @This()) u32 { - return adapter.constant_adapter.numConstants(); + return adapter.metadata_adapter.constant_adapter.numConstants(); } }; for (self.functions.items, 0..) |func, func_index| { - const FunctionBlock = ir.FunctionBlock; + const FunctionBlock = ir.ModuleBlock.FunctionBlock; if (func.global.getReplacement(self) != .none) continue; if (func.instructions.len == 0) continue; @@ -14604,7 +14551,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco try function_block.writeAbbrev(FunctionBlock.DeclareBlocks{ .num_blocks = func.blocks.len }); var adapter: FunctionAdapter = .{ - .constant_adapter = constant_adapter, .metadata_adapter = metadata_adapter, .func = &func, .instruction_index = @enumFromInt(0), @@ -14612,7 +14558,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // Emit function level metadata block if (!func.strip and func.debug_values.len > 0) { - const MetadataBlock = ir.FunctionMetadataBlock; + const MetadataBlock = ir.ModuleBlock.FunctionBlock.MetadataBlock; var metadata_block = try function_block.enterSubBlock(MetadataBlock, false); for (func.debug_values) |value| { @@ -15048,7 +14994,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco const vals = extra.trail.next(extra.data.cases_len, Constant, &func); const blocks = extra.trail.next(extra.data.cases_len, Function.Block.Index, &func); for (vals, blocks) |val, block| { - record.appendAssumeCapacity(adapter.constant_adapter.getConstantIndex(val)); + record.appendAssumeCapacity(adapter.metadata_adapter.constant_adapter.getConstantIndex(val)); record.appendAssumeCapacity(@intFromEnum(block)); } @@ -15135,12 +15081,12 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco switch (debug_location) { .no_location => has_location = false, .location => |location| { - try function_block.writeAbbrev(FunctionBlock.DebugLoc{ + try function_block.writeAbbrevAdapted(FunctionBlock.DebugLoc{ .line = location.line, .column = location.column, - .scope = @enumFromInt(metadata_adapter.getMetadataIndex(location.scope)), - .inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(location.inlined_at)), - }); + .scope = location.scope, + .inlined_at = location.inlined_at, + }, metadata_adapter); has_location = true; }, } @@ -15152,16 +15098,16 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // VALUE_SYMTAB if (!func.strip) { - const ValueSymbolTable = ir.FunctionValueSymbolTable; + const ValueSymtabBlock = ir.ModuleBlock.FunctionBlock.ValueSymtabBlock; - var value_symtab_block = try function_block.enterSubBlock(ValueSymbolTable, false); + var value_symtab_block = try function_block.enterSubBlock(ValueSymtabBlock, false); for (func.blocks, 0..) |block, block_index| { const name = block.instruction.name(&func); if (name == .none or name == .empty) continue; - try value_symtab_block.writeAbbrev(ValueSymbolTable.BlockEntry{ + try value_symtab_block.writeAbbrev(ValueSymtabBlock.BlockEntry{ .value_id = @intCast(block_index), .string = name.slice(self).?, }); @@ -15174,17 +15120,14 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // METADATA_ATTACHMENT_BLOCK { - const MetadataAttachmentBlock = ir.MetadataAttachmentBlock; + const MetadataAttachmentBlock = ir.ModuleBlock.FunctionBlock.MetadataAttachmentBlock; var metadata_attach_block = try function_block.enterSubBlock(MetadataAttachmentBlock, false); - dbg: { - if (func.strip) break :dbg; - const dbg = func.global.ptrConst(self).dbg; - if (dbg == .none) break :dbg; - try metadata_attach_block.writeAbbrev(MetadataAttachmentBlock.AttachmentGlobalSingle{ + if (func.global.ptrConst(self).dbg.unwrap()) |dbg| { + try metadata_attach_block.writeAbbrevAdapted(MetadataAttachmentBlock.AttachmentGlobalSingle{ .kind = .dbg, - .metadata = @enumFromInt(metadata_adapter.getMetadataIndex(dbg) - 1), - }); + .metadata = dbg, + }, metadata_adapter); } var instr_index: u32 = 0; @@ -15201,16 +15144,16 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco }; switch (weights) { .none => {}, - .unpredictable => try metadata_attach_block.writeAbbrev(MetadataAttachmentBlock.AttachmentInstructionSingle{ + .unpredictable => try metadata_attach_block.writeAbbrevAdapted(MetadataAttachmentBlock.AttachmentInstructionSingle{ .inst = instr_index, .kind = .unpredictable, - .metadata = @enumFromInt(metadata_adapter.getMetadataIndex(.empty_tuple) - 1), - }), - _ => try metadata_attach_block.writeAbbrev(MetadataAttachmentBlock.AttachmentInstructionSingle{ + .metadata = .empty_tuple, + }, metadata_adapter), + _ => try metadata_attach_block.writeAbbrevAdapted(MetadataAttachmentBlock.AttachmentInstructionSingle{ .inst = instr_index, .kind = .prof, - .metadata = @enumFromInt(metadata_adapter.getMetadataIndex(@enumFromInt(@intFromEnum(weights))) - 1), - }), + .metadata = weights.toMetadata(), + }, metadata_adapter), } instr_index += 1; }, @@ -15228,7 +15171,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco // STRTAB_BLOCK { - const Strtab = ir.Strtab; + const Strtab = ir.StrtabBlock; var strtab_block = try bitcode.enterTopBlock(Strtab); try strtab_block.writeAbbrev(Strtab.Blob{ .blob = self.strtab_string_bytes.items }); diff --git a/lib/std/zig/llvm/bitcode_writer.zig b/lib/std/zig/llvm/bitcode_writer.zig index 35bd880085..77102a8a7c 100644 --- a/lib/std/zig/llvm/bitcode_writer.zig +++ b/lib/std/zig/llvm/bitcode_writer.zig @@ -88,7 +88,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { } } - pub fn writeVBR(self: *BcWriter, value: anytype, comptime vbr_bits: usize) Error!void { + pub fn writeVbr(self: *BcWriter, value: anytype, comptime vbr_bits: usize) Error!void { comptime { std.debug.assert(vbr_bits > 1); if (@bitSizeOf(@TypeOf(value)) > 64) @compileError("Unsupported VBR block type: " ++ @typeName(@TypeOf(value))); @@ -110,7 +110,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { try self.writeBits(in_buffer, vbr_bits); } - pub fn bitsVBR(_: *const BcWriter, value: anytype, comptime vbr_bits: usize) u16 { + pub fn bitsVbr(value: anytype, comptime vbr_bits: usize) u16 { comptime { std.debug.assert(vbr_bits > 1); if (@bitSizeOf(@TypeOf(value)) > 64) @compileError("Unsupported VBR block type: " ++ @typeName(@TypeOf(value))); @@ -177,8 +177,8 @@ pub fn BitcodeWriter(comptime types: []const type) type { pub fn init(bitcode: *BcWriter, comptime parent_abbrev_len: u6, comptime define_abbrevs: bool) Error!Self { try bitcode.writeBits(1, parent_abbrev_len); - try bitcode.writeVBR(Block.id, 8); - try bitcode.writeVBR(abbrev_len, 4); + try bitcode.writeVbr(Block.id, 8); + try bitcode.writeVbr(abbrev_len, 4); try bitcode.alignTo32(); // We store the index of the block size and store a dummy value as the number of words in the block @@ -214,16 +214,16 @@ pub fn BitcodeWriter(comptime types: []const type) type { pub fn writeUnabbrev(self: *Self, code: u32, values: []const u64) Error!void { try self.bitcode.writeBits(3, abbrev_len); - try self.bitcode.writeVBR(code, 6); - try self.bitcode.writeVBR(values.len, 6); + try self.bitcode.writeVbr(code, 6); + try self.bitcode.writeVbr(values.len, 6); for (values) |val| { - try self.bitcode.writeVBR(val, 6); + try self.bitcode.writeVbr(val, 6); } } pub fn writeAbbrev(self: *Self, params: anytype) Error!void { return self.writeAbbrevAdapted(params, struct { - pub fn get(_: @This(), param: anytype, comptime _: []const u8) @TypeOf(param) { + pub fn get(_: @This(), param: anytype) @TypeOf(param) { return param; } }{}); @@ -253,47 +253,45 @@ pub fn BitcodeWriter(comptime types: []const type) type { comptime var field_index: usize = 0; inline for (Abbrev.ops) |ty| { - const field_name = fields[field_index].name; - const param = @field(params, field_name); - + const param = @field(params, fields[field_index].name); switch (ty) { .literal => continue, - .fixed => |len| try self.bitcode.writeBits(adapter.get(param, field_name), len), + .fixed => |len| try self.bitcode.writeBits(adapter.get(param), len), .fixed_runtime => |width_ty| try self.bitcode.writeBits( - adapter.get(param, field_name), + adapter.get(param), self.bitcode.getTypeWidth(width_ty), ), - .vbr => |len| try self.bitcode.writeVBR(adapter.get(param, field_name), len), - .char6 => try self.bitcode.write6BitChar(adapter.get(param, field_name)), + .vbr => |len| try self.bitcode.writeVbr(adapter.get(param), len), + .char6 => try self.bitcode.write6BitChar(adapter.get(param)), .blob => { - try self.bitcode.writeVBR(param.len, 6); + try self.bitcode.writeVbr(param.len, 6); try self.bitcode.writeBlob(param); }, .array_fixed => |len| { - try self.bitcode.writeVBR(param.len, 6); + try self.bitcode.writeVbr(param.len, 6); for (param) |x| { - try self.bitcode.writeBits(adapter.get(x, field_name), len); + try self.bitcode.writeBits(adapter.get(x), len); } }, .array_fixed_runtime => |width_ty| { - try self.bitcode.writeVBR(param.len, 6); + try self.bitcode.writeVbr(param.len, 6); for (param) |x| { try self.bitcode.writeBits( - adapter.get(x, field_name), + adapter.get(x), self.bitcode.getTypeWidth(width_ty), ); } }, .array_vbr => |len| { - try self.bitcode.writeVBR(param.len, 6); + try self.bitcode.writeVbr(param.len, 6); for (param) |x| { - try self.bitcode.writeVBR(adapter.get(x, field_name), len); + try self.bitcode.writeVbr(adapter.get(x), len); } }, .array_char6 => { - try self.bitcode.writeVBR(param.len, 6); + try self.bitcode.writeVbr(param.len, 6); for (param) |x| { - try self.bitcode.write6BitChar(adapter.get(x, field_name)); + try self.bitcode.write6BitChar(adapter.get(x)); } }, } @@ -307,7 +305,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { try bitcode.writeBits(2, abbrev_len); // ops.len is not accurate because arrays are actually two ops - try bitcode.writeVBR(blk: { + try bitcode.writeVbr(blk: { var count: usize = 0; inline for (ops) |op| { count += switch (op) { @@ -322,22 +320,22 @@ pub fn BitcodeWriter(comptime types: []const type) type { switch (op) { .literal => |value| { try bitcode.writeBits(1, 1); - try bitcode.writeVBR(value, 8); + try bitcode.writeVbr(value, 8); }, .fixed => |width| { try bitcode.writeBits(0, 1); try bitcode.writeBits(1, 3); - try bitcode.writeVBR(width, 5); + try bitcode.writeVbr(width, 5); }, .fixed_runtime => |width_ty| { try bitcode.writeBits(0, 1); try bitcode.writeBits(1, 3); - try bitcode.writeVBR(bitcode.getTypeWidth(width_ty), 5); + try bitcode.writeVbr(bitcode.getTypeWidth(width_ty), 5); }, .vbr => |width| { try bitcode.writeBits(0, 1); try bitcode.writeBits(2, 3); - try bitcode.writeVBR(width, 5); + try bitcode.writeVbr(width, 5); }, .char6 => { try bitcode.writeBits(0, 1); @@ -355,7 +353,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { // Fixed or VBR op try bitcode.writeBits(0, 1); try bitcode.writeBits(1, 3); - try bitcode.writeVBR(width, 5); + try bitcode.writeVbr(width, 5); }, .array_fixed_runtime => |width_ty| { // Array op @@ -365,7 +363,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { // Fixed or VBR op try bitcode.writeBits(0, 1); try bitcode.writeBits(1, 3); - try bitcode.writeVBR(bitcode.getTypeWidth(width_ty), 5); + try bitcode.writeVbr(bitcode.getTypeWidth(width_ty), 5); }, .array_vbr => |width| { // Array op @@ -375,7 +373,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { // Fixed or VBR op try bitcode.writeBits(0, 1); try bitcode.writeBits(2, 3); - try bitcode.writeVBR(width, 5); + try bitcode.writeVbr(width, 5); }, .array_char6 => { // Array op diff --git a/lib/std/zig/llvm/ir.zig b/lib/std/zig/llvm/ir.zig index 824186efb8..13cc180d4d 100644 --- a/lib/std/zig/llvm/ir.zig +++ b/lib/std/zig/llvm/ir.zig @@ -21,9 +21,60 @@ const ColumnAbbrev = AbbrevOp{ .vbr = 8 }; const BlockAbbrev = AbbrevOp{ .vbr = 6 }; const BlockArrayAbbrev = AbbrevOp{ .array_vbr = 6 }; +/// All bitcode files can optionally include a BLOCKINFO block, which contains +/// metadata about other blocks in the file. +/// The only top-level block types are MODULE, IDENTIFICATION, STRTAB and SYMTAB. +pub const BlockId = enum(u5) { + /// BLOCKINFO_BLOCK is used to define metadata about blocks, for example, + /// standard abbrevs that should be available to all blocks of a specified + /// ID. + BLOCKINFO = 0, + + /// Blocks + MODULE = FIRST_APPLICATION, + + /// Module sub-block id's. + PARAMATTR, + PARAMATTR_GROUP, + + CONSTANTS, + FUNCTION, + + /// Block intended to contains information on the bitcode versioning. + /// Can be used to provide better error messages when we fail to parse a + /// bitcode file. + IDENTIFICATION, + + VALUE_SYMTAB, + METADATA, + METADATA_ATTACHMENT, + + TYPE, + + USELIST, + + MODULE_STRTAB, + GLOBALVAL_SUMMARY, + + OPERAND_BUNDLE_TAGS, + + METADATA_KIND, + + STRTAB, + + FULL_LTO_GLOBALVAL_SUMMARY, + + SYMTAB, + + SYNC_SCOPE_NAMES, + + /// Block IDs 1-7 are reserved for future expansion. + pub const FIRST_APPLICATION = 8; +}; + /// Unused tags are commented out so that they are omitted in the generated /// bitcode, which scans over this enum using reflection. -pub const FixedMetadataKind = enum(u8) { +pub const FixedMetadataKind = enum(u6) { dbg = 0, //tbaa = 1, prof = 2, @@ -66,138 +117,79 @@ pub const FixedMetadataKind = enum(u8) { //@"coro.outside.frame" = 39, }; -pub const MetadataCode = enum(u8) { - /// MDSTRING: [values] - STRING_OLD = 1, - /// VALUE: [type num, value num] - VALUE = 2, - /// NODE: [n x md num] - NODE = 3, - /// STRING: [values] - NAME = 4, - /// DISTINCT_NODE: [n x md num] - DISTINCT_NODE = 5, - /// [n x [id, name]] - KIND = 6, - /// [distinct, line, col, scope, inlined-at?] - LOCATION = 7, - /// OLD_NODE: [n x (type num, value num)] - OLD_NODE = 8, - /// OLD_FN_NODE: [n x (type num, value num)] - OLD_FN_NODE = 9, - /// NAMED_NODE: [n x mdnodes] - NAMED_NODE = 10, - /// [m x [value, [n x [id, mdnode]]] - ATTACHMENT = 11, - /// [distinct, tag, vers, header, n x md num] - GENERIC_DEBUG = 12, - /// [distinct, count, lo] - SUBRANGE = 13, - /// [isUnsigned|distinct, value, name] - ENUMERATOR = 14, - /// [distinct, tag, name, size, align, enc] - BASIC_TYPE = 15, - /// [distinct, filename, directory, checksumkind, checksum] - FILE = 16, - /// [distinct, ...] - DERIVED_TYPE = 17, - /// [distinct, ...] - COMPOSITE_TYPE = 18, - /// [distinct, flags, types, cc] - SUBROUTINE_TYPE = 19, - /// [distinct, ...] - COMPILE_UNIT = 20, - /// [distinct, ...] - SUBPROGRAM = 21, - /// [distinct, scope, file, line, column] - LEXICAL_BLOCK = 22, - ///[distinct, scope, file, discriminator] - LEXICAL_BLOCK_FILE = 23, - /// [distinct, scope, file, name, line, exportSymbols] - NAMESPACE = 24, - /// [distinct, scope, name, type, ...] - TEMPLATE_TYPE = 25, - /// [distinct, scope, name, type, value, ...] - TEMPLATE_VALUE = 26, - /// [distinct, ...] - GLOBAL_VAR = 27, - /// [distinct, ...] - LOCAL_VAR = 28, - /// [distinct, n x element] - EXPRESSION = 29, - /// [distinct, name, file, line, ...] - OBJC_PROPERTY = 30, - /// [distinct, tag, scope, entity, line, name] - IMPORTED_ENTITY = 31, - /// [distinct, scope, name, ...] - MODULE = 32, - /// [distinct, macinfo, line, name, value] - MACRO = 33, - /// [distinct, macinfo, line, file, ...] - MACRO_FILE = 34, - /// [count, offset] blob([lengths][chars]) - STRINGS = 35, - /// [valueid, n x [id, mdnode]] - GLOBAL_DECL_ATTACHMENT = 36, - /// [distinct, var, expr] - GLOBAL_VAR_EXPR = 37, - /// [offset] - INDEX_OFFSET = 38, - /// [bitpos] - INDEX = 39, - /// [distinct, scope, name, file, line] - LABEL = 40, - /// [distinct, name, size, align,...] - STRING_TYPE = 41, - /// [distinct, scope, name, variable,...] - COMMON_BLOCK = 44, - /// [distinct, count, lo, up, stride] - GENERIC_SUBRANGE = 45, - /// [n x [type num, value num]] - ARG_LIST = 46, - /// [distinct, ...] - ASSIGN_ID = 47, +pub const BlockInfoBlock = struct { + pub const id: BlockId = .BLOCKINFO; + + pub const set_block_id = 1; + + pub const abbrevs = [_]type{}; }; -pub const Identification = struct { - pub const id = 13; +/// MODULE blocks have a number of optional fields and subblocks. +pub const ModuleBlock = struct { + pub const id: BlockId = .MODULE; pub const abbrevs = [_]type{ - Version, - Epoch, + ModuleBlock.Version, + ModuleBlock.String, + ModuleBlock.Variable, + ModuleBlock.Function, + ModuleBlock.Alias, + }; + + pub const Code = enum(u5) { + /// VERSION: [version#] + VERSION = 1, + /// TRIPLE: [strchr x N] + TRIPLE = 2, + /// DATALAYOUT: [strchr x N] + DATALAYOUT = 3, + /// ASM: [strchr x N] + ASM = 4, + /// SECTIONNAME: [strchr x N] + SECTIONNAME = 5, + + /// Deprecated, but still needed to read old bitcode files. + /// DEPLIB: [strchr x N] + DEPLIB = 6, + + /// GLOBALVAR: [pointer type, isconst, initid, + /// linkage, alignment, section, visibility, threadlocal] + GLOBALVAR = 7, + + /// FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment, + /// section, visibility, gc, unnamed_addr] + FUNCTION = 8, + + /// ALIAS: [alias type, aliasee val#, linkage, visibility] + ALIAS_OLD = 9, + + /// GCNAME: [strchr x N] + GCNAME = 11, + /// COMDAT: [selection_kind, name] + COMDAT = 12, + + /// VSTOFFSET: [offset] + VSTOFFSET = 13, + + /// ALIAS: [alias value type, addrspace, aliasee val#, linkage, visibility] + ALIAS = 14, + + METADATA_VALUES_UNUSED = 15, + + /// SOURCE_FILENAME: [namechar x N] + SOURCE_FILENAME = 16, + + /// HASH: [5*i32] + HASH = 17, + + /// IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility] + IFUNC = 18, }; pub const Version = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 1 }, - .{ .array_fixed = 8 }, - }; - string: []const u8, - }; - - pub const Epoch = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 2 }, - .{ .vbr = 6 }, - }; - epoch: u32, - }; -}; - -pub const Module = struct { - pub const id = 8; - - pub const abbrevs = [_]type{ - Version, - String, - Variable, - Function, - Alias, - }; - - pub const Version = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 1 }, + .{ .literal = @intFromEnum(ModuleBlock.Code.VERSION) }, .{ .literal = 2 }, }; }; @@ -219,7 +211,7 @@ pub const Module = struct { }; pub const ops = [_]AbbrevOp{ - .{ .literal = 7 }, // Code + .{ .literal = @intFromEnum(ModuleBlock.Code.GLOBALVAR) }, // Code .{ .vbr = 16 }, // strtab_offset .{ .vbr = 16 }, // strtab_size .{ .fixed_runtime = Builder.Type }, @@ -255,7 +247,7 @@ pub const Module = struct { pub const Function = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 8 }, // Code + .{ .literal = @intFromEnum(ModuleBlock.Code.FUNCTION) }, // Code .{ .vbr = 16 }, // strtab_offset .{ .vbr = 16 }, // strtab_size .{ .fixed_runtime = Builder.Type }, @@ -294,7 +286,7 @@ pub const Module = struct { pub const Alias = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 14 }, // Code + .{ .literal = @intFromEnum(ModuleBlock.Code.ALIAS) }, // Code .{ .vbr = 16 }, // strtab_offset .{ .vbr = 16 }, // strtab_size .{ .fixed_runtime = Builder.Type }, @@ -319,1542 +311,1986 @@ pub const Module = struct { unnamed_addr: Builder.UnnamedAddr, preemption: Builder.Preemption, }; + + /// PARAMATTR blocks have code for defining a parameter attribute set. + pub const ParamattrBlock = struct { + pub const id: BlockId = .PARAMATTR; + + pub const abbrevs = [_]type{ + ModuleBlock.ParamattrBlock.Entry, + }; + + pub const Code = enum(u2) { + /// Deprecated, but still needed to read old bitcode files. + /// ENTRY: [paramidx0, attr0, paramidx1, attr1...] + ENTRY_OLD = 1, + /// ENTRY: [attrgrp0, attrgrp1, ...] + ENTRY = 2, + }; + + pub const Entry = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ParamattrBlock.Code.ENTRY) }, + .{ .array_vbr = 8 }, + }; + group_indices: []const u64, + }; + }; + + pub const ParamattrGroupBlock = struct { + pub const id: BlockId = .PARAMATTR_GROUP; + + pub const abbrevs = [_]type{}; + + pub const Code = enum(u2) { + /// ENTRY: [grpid, idx, attr0, attr1, ...] + CODE_ENTRY = 3, + }; + }; + + /// The constants block (CONSTANTS_BLOCK_ID) describes emission for each + /// constant and maintains an implicit current type value. + pub const ConstantsBlock = struct { + pub const id: BlockId = .CONSTANTS; + + pub const abbrevs = [_]type{ + ModuleBlock.ConstantsBlock.SetType, + ModuleBlock.ConstantsBlock.Null, + ModuleBlock.ConstantsBlock.Undef, + ModuleBlock.ConstantsBlock.Poison, + ModuleBlock.ConstantsBlock.Integer, + ModuleBlock.ConstantsBlock.Half, + ModuleBlock.ConstantsBlock.Float, + ModuleBlock.ConstantsBlock.Double, + ModuleBlock.ConstantsBlock.Fp80, + ModuleBlock.ConstantsBlock.Fp128, + ModuleBlock.ConstantsBlock.Aggregate, + ModuleBlock.ConstantsBlock.String, + ModuleBlock.ConstantsBlock.CString, + ModuleBlock.ConstantsBlock.Cast, + ModuleBlock.ConstantsBlock.Binary, + ModuleBlock.ConstantsBlock.Cmp, + ModuleBlock.ConstantsBlock.ExtractElement, + ModuleBlock.ConstantsBlock.InsertElement, + ModuleBlock.ConstantsBlock.ShuffleVector, + ModuleBlock.ConstantsBlock.ShuffleVectorEx, + ModuleBlock.ConstantsBlock.BlockAddress, + ModuleBlock.ConstantsBlock.DsoLocalEquivalentOrNoCfi, + }; + + pub const Code = enum(u6) { + /// SETTYPE: [typeid] + SETTYPE = 1, + /// NULL + NULL = 2, + /// UNDEF + UNDEF = 3, + /// INTEGER: [intval] + INTEGER = 4, + /// WIDE_INTEGER: [n x intval] + WIDE_INTEGER = 5, + /// FLOAT: [fpval] + FLOAT = 6, + /// AGGREGATE: [n x value number] + AGGREGATE = 7, + /// STRING: [values] + STRING = 8, + /// CSTRING: [values] + CSTRING = 9, + /// CE_BINOP: [opcode, opval, opval] + CE_BINOP = 10, + /// CE_CAST: [opcode, opty, opval] + CE_CAST = 11, + /// CE_GEP: [n x operands] + CE_GEP_OLD = 12, + /// CE_SELECT: [opval, opval, opval] + CE_SELECT = 13, + /// CE_EXTRACTELT: [opty, opval, opval] + CE_EXTRACTELT = 14, + /// CE_INSERTELT: [opval, opval, opval] + CE_INSERTELT = 15, + /// CE_SHUFFLEVEC: [opval, opval, opval] + CE_SHUFFLEVEC = 16, + /// CE_CMP: [opty, opval, opval, pred] + CE_CMP = 17, + /// INLINEASM: [sideeffect|alignstack,asmstr,conststr] + INLINEASM_OLD = 18, + /// SHUFVEC_EX: [opty, opval, opval, opval] + CE_SHUFVEC_EX = 19, + /// INBOUNDS_GEP: [n x operands] + CE_INBOUNDS_GEP = 20, + /// BLOCKADDRESS: [fnty, fnval, bb#] + BLOCKADDRESS = 21, + /// DATA: [n x elements] + DATA = 22, + /// INLINEASM: [sideeffect|alignstack|asmdialect,asmstr,conststr] + INLINEASM_OLD2 = 23, + /// [opty, flags, n x operands] + CE_GEP_WITH_INRANGE_INDEX_OLD = 24, + /// CE_UNOP: [opcode, opval] + CE_UNOP = 25, + /// POISON + POISON = 26, + /// DSO_LOCAL_EQUIVALENT [gvty, gv] + DSO_LOCAL_EQUIVALENT = 27, + /// INLINEASM: [sideeffect|alignstack|asmdialect|unwind,asmstr, + /// conststr] + INLINEASM_OLD3 = 28, + /// NO_CFI [ fty, f ] + NO_CFI_VALUE = 29, + /// INLINEASM: [fnty,sideeffect|alignstack|asmdialect|unwind, + /// asmstr,conststr] + INLINEASM = 30, + /// [opty, flags, range, n x operands] + CE_GEP_WITH_INRANGE = 31, + /// [opty, flags, n x operands] + CE_GEP = 32, + /// [ptr, key, disc, addrdisc] + PTRAUTH = 33, + }; + + pub const SetType = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.SETTYPE) }, + .{ .fixed_runtime = Builder.Type }, + }; + type_id: Builder.Type, + }; + + pub const Null = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.NULL) }, + }; + }; + + pub const Undef = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.UNDEF) }, + }; + }; + + pub const Poison = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.POISON) }, + }; + }; + + pub const Integer = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.INTEGER) }, + .{ .vbr = 16 }, + }; + value: u64, + }; + + pub const Half = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.FLOAT) }, + .{ .fixed = 16 }, + }; + value: u16, + }; + + pub const Float = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.FLOAT) }, + .{ .fixed = 32 }, + }; + value: u32, + }; + + pub const Double = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.FLOAT) }, + .{ .vbr = 6 }, + }; + value: u64, + }; + + pub const Fp80 = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.FLOAT) }, + .{ .vbr = 6 }, + .{ .vbr = 6 }, + }; + hi: u64, + lo: u16, + }; + + pub const Fp128 = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.FLOAT) }, + .{ .vbr = 6 }, + .{ .vbr = 6 }, + }; + lo: u64, + hi: u64, + }; + + pub const Aggregate = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.AGGREGATE) }, + .{ .array_fixed = 32 }, + }; + values: []const Builder.Constant, + }; + + pub const String = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.STRING) }, + .{ .array_fixed = 8 }, + }; + string: []const u8, + }; + + pub const CString = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.CSTRING) }, + .{ .array_fixed = 8 }, + }; + string: []const u8, + }; + + pub const Cast = struct { + const CastOpcode = Builder.CastOpcode; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.CE_CAST) }, + .{ .fixed = @bitSizeOf(CastOpcode) }, + .{ .fixed_runtime = Builder.Type }, + ConstantAbbrev, + }; + + opcode: CastOpcode, + type_index: Builder.Type, + val: Builder.Constant, + }; + + pub const Binary = struct { + const BinaryOpcode = Builder.BinaryOpcode; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.CE_BINOP) }, + .{ .fixed = @bitSizeOf(BinaryOpcode) }, + ConstantAbbrev, + ConstantAbbrev, + }; + + opcode: BinaryOpcode, + lhs: Builder.Constant, + rhs: Builder.Constant, + }; + + pub const Cmp = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.CE_CMP) }, + .{ .fixed_runtime = Builder.Type }, + ConstantAbbrev, + ConstantAbbrev, + .{ .vbr = 6 }, + }; + + ty: Builder.Type, + lhs: Builder.Constant, + rhs: Builder.Constant, + pred: u32, + }; + + pub const ExtractElement = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.CE_EXTRACTELT) }, + .{ .fixed_runtime = Builder.Type }, + ConstantAbbrev, + .{ .fixed_runtime = Builder.Type }, + ConstantAbbrev, + }; + + val_type: Builder.Type, + val: Builder.Constant, + index_type: Builder.Type, + index: Builder.Constant, + }; + + pub const InsertElement = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.CE_INSERTELT) }, + ConstantAbbrev, + ConstantAbbrev, + .{ .fixed_runtime = Builder.Type }, + ConstantAbbrev, + }; + + val: Builder.Constant, + elem: Builder.Constant, + index_type: Builder.Type, + index: Builder.Constant, + }; + + pub const ShuffleVector = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.CE_SHUFFLEVEC) }, + ValueAbbrev, + ValueAbbrev, + ValueAbbrev, + }; + + lhs: Builder.Constant, + rhs: Builder.Constant, + mask: Builder.Constant, + }; + + pub const ShuffleVectorEx = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.CE_SHUFVEC_EX) }, + .{ .fixed_runtime = Builder.Type }, + ValueAbbrev, + ValueAbbrev, + ValueAbbrev, + }; + + ty: Builder.Type, + lhs: Builder.Constant, + rhs: Builder.Constant, + mask: Builder.Constant, + }; + + pub const BlockAddress = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.ConstantsBlock.Code.BLOCKADDRESS) }, + .{ .fixed_runtime = Builder.Type }, + ConstantAbbrev, + BlockAbbrev, + }; + type_id: Builder.Type, + function: u32, + block: u32, + }; + + pub const DsoLocalEquivalentOrNoCfi = struct { + pub const ops = [_]AbbrevOp{ + .{ .fixed = 5 }, + .{ .fixed_runtime = Builder.Type }, + ConstantAbbrev, + }; + code: ModuleBlock.ConstantsBlock.Code, + type_id: Builder.Type, + function: u32, + }; + }; + + /// The function body block (FUNCTION_BLOCK_ID) describes function bodies. It + /// can contain a constant block (CONSTANTS_BLOCK_ID). + pub const FunctionBlock = struct { + pub const id: BlockId = .FUNCTION; + + pub const abbrevs = [_]type{ + ModuleBlock.FunctionBlock.DeclareBlocks, + ModuleBlock.FunctionBlock.Call, + ModuleBlock.FunctionBlock.CallFast, + ModuleBlock.FunctionBlock.FNeg, + ModuleBlock.FunctionBlock.FNegFast, + ModuleBlock.FunctionBlock.Binary, + ModuleBlock.FunctionBlock.BinaryNoWrap, + ModuleBlock.FunctionBlock.BinaryExact, + ModuleBlock.FunctionBlock.BinaryFast, + ModuleBlock.FunctionBlock.Cmp, + ModuleBlock.FunctionBlock.CmpFast, + ModuleBlock.FunctionBlock.Select, + ModuleBlock.FunctionBlock.SelectFast, + ModuleBlock.FunctionBlock.Cast, + ModuleBlock.FunctionBlock.Alloca, + ModuleBlock.FunctionBlock.GetElementPtr, + ModuleBlock.FunctionBlock.ExtractValue, + ModuleBlock.FunctionBlock.InsertValue, + ModuleBlock.FunctionBlock.ExtractElement, + ModuleBlock.FunctionBlock.InsertElement, + ModuleBlock.FunctionBlock.ShuffleVector, + ModuleBlock.FunctionBlock.RetVoid, + ModuleBlock.FunctionBlock.Ret, + ModuleBlock.FunctionBlock.Unreachable, + ModuleBlock.FunctionBlock.Load, + ModuleBlock.FunctionBlock.LoadAtomic, + ModuleBlock.FunctionBlock.Store, + ModuleBlock.FunctionBlock.StoreAtomic, + ModuleBlock.FunctionBlock.BrUnconditional, + ModuleBlock.FunctionBlock.BrConditional, + ModuleBlock.FunctionBlock.VaArg, + ModuleBlock.FunctionBlock.AtomicRmw, + ModuleBlock.FunctionBlock.CmpXchg, + ModuleBlock.FunctionBlock.Fence, + ModuleBlock.FunctionBlock.DebugLoc, + ModuleBlock.FunctionBlock.DebugLocAgain, + ModuleBlock.FunctionBlock.ColdOperandBundle, + ModuleBlock.FunctionBlock.IndirectBr, + }; + + pub const Code = enum(u7) { + /// DECLAREBLOCKS: [n] + DECLAREBLOCKS = 1, + + /// BINOP: [opcode, ty, opval, opval] + INST_BINOP = 2, + /// CAST: [opcode, ty, opty, opval] + INST_CAST = 3, + /// GEP: [n x operands] + INST_GEP_OLD = 4, + /// SELECT: [ty, opval, opval, opval] + INST_SELECT = 5, + /// EXTRACTELT: [opty, opval, opval] + INST_EXTRACTELT = 6, + /// INSERTELT: [ty, opval, opval, opval] + INST_INSERTELT = 7, + /// SHUFFLEVEC: [ty, opval, opval, opval] + INST_SHUFFLEVEC = 8, + /// CMP: [opty, opval, opval, pred] + INST_CMP = 9, + + /// RET: [opty,opval] + INST_RET = 10, + /// BR: [bb#, bb#, cond] or [bb#] + INST_BR = 11, + /// SWITCH: [opty, op0, op1, ...] + INST_SWITCH = 12, + /// INVOKE: [attr, fnty, op0,op1, ...] + INST_INVOKE = 13, + /// UNREACHABLE + INST_UNREACHABLE = 15, + + /// PHI: [ty, val0,bb0, ...] + INST_PHI = 16, + /// ALLOCA: [instty, opty, op, align] + INST_ALLOCA = 19, + /// LOAD: [opty, op, align, vol] + INST_LOAD = 20, + /// VAARG: [valistty, valist, instty] + /// This store code encodes the pointer type, rather than the value type + /// this is so information only available in the pointer type (e.g. address + /// spaces) is retained. + INST_VAARG = 23, + /// STORE: [ptrty,ptr,val, align, vol] + INST_STORE_OLD = 24, + + /// EXTRACTVAL: [n x operands] + INST_EXTRACTVAL = 26, + /// INSERTVAL: [n x operands] + INST_INSERTVAL = 27, + /// fcmp/icmp returning Int1TY or vector of Int1Ty. Same as CMP, exists to + /// support legacy vicmp/vfcmp instructions. + /// CMP2: [opty, opval, opval, pred] + INST_CMP2 = 28, + /// new select on i1 or [N x i1] + /// VSELECT: [ty,opval,opval,predty,pred] + INST_VSELECT = 29, + /// INBOUNDS_GEP: [n x operands] + INST_INBOUNDS_GEP_OLD = 30, + /// INDIRECTBR: [opty, op0, op1, ...] + INST_INDIRECTBR = 31, + + /// DEBUG_LOC_AGAIN + DEBUG_LOC_AGAIN = 33, + + /// CALL: [attr, cc, fnty, fnid, args...] + INST_CALL = 34, + + /// DEBUG_LOC: [Line,Col,ScopeVal, IAVal] + DEBUG_LOC = 35, + /// FENCE: [ordering, synchscope] + INST_FENCE = 36, + /// CMPXCHG: [ptrty, ptr, cmp, val, vol, + /// ordering, synchscope, + /// failure_ordering?, weak?] + INST_CMPXCHG_OLD = 37, + /// ATOMICRMW: [ptrty,ptr,val, operation, + /// align, vol, + /// ordering, synchscope] + INST_ATOMICRMW_OLD = 38, + /// RESUME: [opval] + INST_RESUME = 39, + /// LANDINGPAD: [ty,val,val,num,id0,val0...] + INST_LANDINGPAD_OLD = 40, + /// LOAD: [opty, op, align, vol, + /// ordering, synchscope] + INST_LOADATOMIC = 41, + /// STORE: [ptrty,ptr,val, align, vol + /// ordering, synchscope] + INST_STOREATOMIC_OLD = 42, + + /// GEP: [inbounds, n x operands] + INST_GEP = 43, + /// STORE: [ptrty,ptr,valty,val, align, vol] + INST_STORE = 44, + /// STORE: [ptrty,ptr,val, align, vol + INST_STOREATOMIC = 45, + /// CMPXCHG: [ptrty, ptr, cmp, val, vol, + /// success_ordering, synchscope, + /// failure_ordering, weak] + INST_CMPXCHG = 46, + /// LANDINGPAD: [ty,val,num,id0,val0...] + INST_LANDINGPAD = 47, + /// CLEANUPRET: [val] or [val,bb#] + INST_CLEANUPRET = 48, + /// CATCHRET: [val,bb#] + INST_CATCHRET = 49, + /// CATCHPAD: [bb#,bb#,num,args...] + INST_CATCHPAD = 50, + /// CLEANUPPAD: [num,args...] + INST_CLEANUPPAD = 51, + /// CATCHSWITCH: [num,args...] or [num,args...,bb] + INST_CATCHSWITCH = 52, + /// OPERAND_BUNDLE: [tag#, value...] + OPERAND_BUNDLE = 55, + /// UNOP: [opcode, ty, opval] + INST_UNOP = 56, + /// CALLBR: [attr, cc, norm, transfs, + /// fnty, fnid, args...] + INST_CALLBR = 57, + /// FREEZE: [opty, opval] + INST_FREEZE = 58, + /// ATOMICRMW: [ptrty, ptr, valty, val, + /// operation, align, vol, + /// ordering, synchscope] + INST_ATOMICRMW = 59, + /// BLOCKADDR_USERS: [value...] + BLOCKADDR_USERS = 60, + + /// [DILocation, DILocalVariable, DIExpression, ValueAsMetadata] + DEBUG_RECORD_VALUE = 61, + /// [DILocation, DILocalVariable, DIExpression, ValueAsMetadata] + DEBUG_RECORD_DECLARE = 62, + /// [DILocation, DILocalVariable, DIExpression, ValueAsMetadata, + /// DIAssignID, DIExpression (addr), ValueAsMetadata (addr)] + DEBUG_RECORD_ASSIGN = 63, + /// [DILocation, DILocalVariable, DIExpression, Value] + DEBUG_RECORD_VALUE_SIMPLE = 64, + /// [DILocation, DILabel] + DEBUG_RECORD_LABEL = 65, + }; + + pub const DeclareBlocks = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.DECLAREBLOCKS) }, + .{ .vbr = 8 }, + }; + num_blocks: usize, + }; + + pub const Call = struct { + pub const CallType = packed struct(u17) { + tail: bool = false, + call_conv: Builder.CallConv, + reserved: u3 = 0, + must_tail: bool = false, + // We always use the explicit type version as that is what LLVM does + explicit_type: bool = true, + no_tail: bool = false, + }; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_CALL) }, + .{ .fixed_runtime = Builder.FunctionAttributes }, + .{ .fixed = @bitSizeOf(CallType) }, + .{ .fixed_runtime = Builder.Type }, + ValueAbbrev, // Callee + ValueArrayAbbrev, // Args + }; + + attributes: Builder.FunctionAttributes, + call_type: CallType, + type_id: Builder.Type, + callee: Builder.Value, + args: []const Builder.Value, + }; + + pub const CallFast = struct { + const CallType = packed struct(u18) { + tail: bool = false, + call_conv: Builder.CallConv, + reserved: u3 = 0, + must_tail: bool = false, + // We always use the explicit type version as that is what LLVM does + explicit_type: bool = true, + no_tail: bool = false, + fast: bool = true, + }; + + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_CALL) }, + .{ .fixed_runtime = Builder.FunctionAttributes }, + .{ .fixed = @bitSizeOf(CallType) }, + .{ .fixed = @bitSizeOf(Builder.FastMath) }, + .{ .fixed_runtime = Builder.Type }, + ValueAbbrev, // Callee + ValueArrayAbbrev, // Args + }; + + attributes: Builder.FunctionAttributes, + call_type: CallType, + fast_math: Builder.FastMath, + type_id: Builder.Type, + callee: Builder.Value, + args: []const Builder.Value, + }; + + pub const FNeg = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_UNOP) }, + ValueAbbrev, + .{ .literal = 0 }, + }; + + val: u32, + }; + + pub const FNegFast = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_UNOP) }, + ValueAbbrev, + .{ .literal = 0 }, + .{ .fixed = @bitSizeOf(Builder.FastMath) }, + }; + + val: u32, + fast_math: Builder.FastMath, + }; + + pub const Binary = struct { + const BinaryOpcode = Builder.BinaryOpcode; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_BINOP) }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(BinaryOpcode) }, + }; + + lhs: u32, + rhs: u32, + opcode: BinaryOpcode, + }; + + pub const BinaryNoWrap = struct { + const BinaryOpcode = Builder.BinaryOpcode; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_BINOP) }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(BinaryOpcode) }, + .{ .fixed = 2 }, + }; + + lhs: u32, + rhs: u32, + opcode: BinaryOpcode, + flags: packed struct(u2) { + no_unsigned_wrap: bool, + no_signed_wrap: bool, + }, + }; + + pub const BinaryExact = struct { + const BinaryOpcode = Builder.BinaryOpcode; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_BINOP) }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(BinaryOpcode) }, + .{ .literal = 1 }, + }; + + lhs: u32, + rhs: u32, + opcode: BinaryOpcode, + }; + + pub const BinaryFast = struct { + const BinaryOpcode = Builder.BinaryOpcode; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_BINOP) }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(BinaryOpcode) }, + .{ .fixed = @bitSizeOf(Builder.FastMath) }, + }; + + lhs: u32, + rhs: u32, + opcode: BinaryOpcode, + fast_math: Builder.FastMath, + }; + + pub const Cmp = struct { + const CmpPredicate = Builder.CmpPredicate; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_CMP2) }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(CmpPredicate) }, + }; + + lhs: u32, + rhs: u32, + pred: CmpPredicate, + }; + + pub const CmpFast = struct { + const CmpPredicate = Builder.CmpPredicate; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_CMP2) }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(CmpPredicate) }, + .{ .fixed = @bitSizeOf(Builder.FastMath) }, + }; + + lhs: u32, + rhs: u32, + pred: CmpPredicate, + fast_math: Builder.FastMath, + }; + + pub const Select = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_VSELECT) }, + ValueAbbrev, + ValueAbbrev, + ValueAbbrev, + }; + + lhs: u32, + rhs: u32, + cond: u32, + }; + + pub const SelectFast = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_VSELECT) }, + ValueAbbrev, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(Builder.FastMath) }, + }; + + lhs: u32, + rhs: u32, + cond: u32, + fast_math: Builder.FastMath, + }; + + pub const Cast = struct { + const CastOpcode = Builder.CastOpcode; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_CAST) }, + ValueAbbrev, + .{ .fixed_runtime = Builder.Type }, + .{ .fixed = @bitSizeOf(CastOpcode) }, + }; + + val: u32, + type_index: Builder.Type, + opcode: CastOpcode, + }; + + pub const Alloca = struct { + pub const Flags = packed struct(u11) { + align_lower: u5, + inalloca: bool, + explicit_type: bool, + swift_error: bool, + align_upper: u3, + }; + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_ALLOCA) }, + .{ .fixed_runtime = Builder.Type }, + .{ .fixed_runtime = Builder.Type }, + ValueAbbrev, + .{ .fixed = @bitSizeOf(Flags) }, + }; + + inst_type: Builder.Type, + len_type: Builder.Type, + len_value: u32, + flags: Flags, + }; + + pub const RetVoid = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_RET) }, + }; + }; + + pub const Ret = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_RET) }, + ValueAbbrev, + }; + val: u32, + }; + + pub const GetElementPtr = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_GEP) }, + .{ .fixed = 1 }, + .{ .fixed_runtime = Builder.Type }, + ValueAbbrev, + ValueArrayAbbrev, + }; + + is_inbounds: bool, + type_index: Builder.Type, + base: Builder.Value, + indices: []const Builder.Value, + }; + + pub const ExtractValue = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_EXTRACTVAL) }, + ValueAbbrev, + ValueArrayAbbrev, + }; + + val: u32, + indices: []const u32, + }; + + pub const InsertValue = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_INSERTVAL) }, + ValueAbbrev, + ValueAbbrev, + ValueArrayAbbrev, + }; + + val: u32, + elem: u32, + indices: []const u32, + }; + + pub const ExtractElement = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_EXTRACTELT) }, + ValueAbbrev, + ValueAbbrev, + }; + + val: u32, + index: u32, + }; + + pub const InsertElement = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_INSERTELT) }, + ValueAbbrev, + ValueAbbrev, + ValueAbbrev, + }; + + val: u32, + elem: u32, + index: u32, + }; + + pub const ShuffleVector = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_SHUFFLEVEC) }, + ValueAbbrev, + ValueAbbrev, + ValueAbbrev, + }; + + lhs: u32, + rhs: u32, + mask: u32, + }; + + pub const Unreachable = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_UNREACHABLE) }, + }; + }; + + pub const Load = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_LOAD) }, + ValueAbbrev, + .{ .fixed_runtime = Builder.Type }, + .{ .fixed = @bitSizeOf(Builder.Alignment) }, + .{ .fixed = 1 }, + }; + ptr: u32, + ty: Builder.Type, + alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), + is_volatile: bool, + }; + + pub const LoadAtomic = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_LOADATOMIC) }, + ValueAbbrev, + .{ .fixed_runtime = Builder.Type }, + .{ .fixed = @bitSizeOf(Builder.Alignment) }, + .{ .fixed = 1 }, + .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, + .{ .fixed = @bitSizeOf(Builder.SyncScope) }, + }; + ptr: u32, + ty: Builder.Type, + alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), + is_volatile: bool, + success_ordering: Builder.AtomicOrdering, + sync_scope: Builder.SyncScope, + }; + + pub const Store = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_STORE) }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(Builder.Alignment) }, + .{ .fixed = 1 }, + }; + ptr: u32, + val: u32, + alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), + is_volatile: bool, + }; + + pub const StoreAtomic = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_STOREATOMIC) }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(Builder.Alignment) }, + .{ .fixed = 1 }, + .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, + .{ .fixed = @bitSizeOf(Builder.SyncScope) }, + }; + ptr: u32, + val: u32, + alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), + is_volatile: bool, + success_ordering: Builder.AtomicOrdering, + sync_scope: Builder.SyncScope, + }; + + pub const BrUnconditional = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_BR) }, + BlockAbbrev, + }; + block: u32, + }; + + pub const BrConditional = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_BR) }, + BlockAbbrev, + BlockAbbrev, + BlockAbbrev, + }; + then_block: u32, + else_block: u32, + condition: u32, + }; + + pub const VaArg = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_VAARG) }, + .{ .fixed_runtime = Builder.Type }, + ValueAbbrev, + .{ .fixed_runtime = Builder.Type }, + }; + list_type: Builder.Type, + list: u32, + type: Builder.Type, + }; + + pub const AtomicRmw = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_ATOMICRMW) }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(Builder.Function.Instruction.AtomicRmw.Operation) }, + .{ .fixed = 1 }, + .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, + .{ .fixed = @bitSizeOf(Builder.SyncScope) }, + .{ .fixed = @bitSizeOf(Builder.Alignment) }, + }; + ptr: u32, + val: u32, + operation: Builder.Function.Instruction.AtomicRmw.Operation, + is_volatile: bool, + success_ordering: Builder.AtomicOrdering, + sync_scope: Builder.SyncScope, + alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), + }; + + pub const CmpXchg = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_CMPXCHG) }, + ValueAbbrev, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = 1 }, + .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, + .{ .fixed = @bitSizeOf(Builder.SyncScope) }, + .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, + .{ .fixed = 1 }, + .{ .fixed = @bitSizeOf(Builder.Alignment) }, + }; + ptr: u32, + cmp: u32, + new: u32, + is_volatile: bool, + success_ordering: Builder.AtomicOrdering, + sync_scope: Builder.SyncScope, + failure_ordering: Builder.AtomicOrdering, + is_weak: bool, + alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), + }; + + pub const Fence = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_FENCE) }, + .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, + .{ .fixed = @bitSizeOf(Builder.SyncScope) }, + }; + ordering: Builder.AtomicOrdering, + sync_scope: Builder.SyncScope, + }; + + pub const DebugLoc = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.DEBUG_LOC) }, + LineAbbrev, + ColumnAbbrev, + MetadataAbbrev, + MetadataAbbrev, + .{ .literal = 0 }, + }; + line: u32, + column: u32, + scope: Builder.Metadata.Optional, + inlined_at: Builder.Metadata.Optional, + }; + + pub const DebugLocAgain = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.DEBUG_LOC_AGAIN) }, + }; + }; + + pub const ColdOperandBundle = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.OPERAND_BUNDLE) }, + .{ .literal = 0 }, + }; + }; + + pub const IndirectBr = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.Code.INST_INDIRECTBR) }, + .{ .fixed_runtime = Builder.Type }, + ValueAbbrev, + BlockArrayAbbrev, + }; + ty: Builder.Type, + addr: Builder.Value, + targets: []const Builder.Function.Block.Index, + }; + + pub const ValueSymtabBlock = struct { + pub const id: BlockId = .VALUE_SYMTAB; + + pub const abbrevs = [_]type{ + ModuleBlock.FunctionBlock.ValueSymtabBlock.BlockEntry, + }; + + /// Value symbol table codes. + pub const Code = enum(u3) { + /// VST_ENTRY: [valueid, namechar x N] + ENTRY = 1, + /// VST_BBENTRY: [bbid, namechar x N] + BBENTRY = 2, + /// VST_FNENTRY: [valueid, offset, namechar x N] + FNENTRY = 3, + /// VST_COMBINED_ENTRY: [valueid, refguid] + COMBINED_ENTRY = 5, + }; + + pub const BlockEntry = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.FunctionBlock.ValueSymtabBlock.Code.BBENTRY) }, + ValueAbbrev, + .{ .array_fixed = 8 }, + }; + value_id: u32, + string: []const u8, + }; + }; + + pub const MetadataBlock = struct { + pub const id: BlockId = .METADATA; + + pub const abbrevs = [_]type{ + ModuleBlock.FunctionBlock.MetadataBlock.Value, + }; + + pub const Value = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.VALUE) }, + .{ .fixed = 32 }, // variable + .{ .fixed = 32 }, // expression + }; + + ty: Builder.Type, + value: Builder.Value, + }; + }; + + pub const MetadataAttachmentBlock = struct { + pub const id: BlockId = .METADATA_ATTACHMENT; + + pub const abbrevs = [_]type{ + ModuleBlock.FunctionBlock.MetadataAttachmentBlock.AttachmentGlobalSingle, + ModuleBlock.FunctionBlock.MetadataAttachmentBlock.AttachmentInstructionSingle, + }; + + pub const AttachmentGlobalSingle = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.ATTACHMENT) }, + .{ .fixed = 1 }, + MetadataAbbrev, + }; + kind: FixedMetadataKind, + metadata: Builder.Metadata, + }; + + pub const AttachmentInstructionSingle = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.ATTACHMENT) }, + ValueAbbrev, + .{ .fixed = 5 }, + MetadataAbbrev, + }; + inst: u32, + kind: FixedMetadataKind, + metadata: Builder.Metadata, + }; + }; + }; + + pub const MetadataBlock = struct { + pub const id: BlockId = .METADATA; + + pub const abbrevs = [_]type{ + ModuleBlock.MetadataBlock.Strings, + ModuleBlock.MetadataBlock.File, + ModuleBlock.MetadataBlock.CompileUnit, + ModuleBlock.MetadataBlock.Subprogram, + ModuleBlock.MetadataBlock.LexicalBlock, + ModuleBlock.MetadataBlock.Location, + ModuleBlock.MetadataBlock.BasicType, + ModuleBlock.MetadataBlock.CompositeType, + ModuleBlock.MetadataBlock.DerivedType, + ModuleBlock.MetadataBlock.SubroutineType, + ModuleBlock.MetadataBlock.Enumerator, + ModuleBlock.MetadataBlock.Subrange, + ModuleBlock.MetadataBlock.Expression, + ModuleBlock.MetadataBlock.Node, + ModuleBlock.MetadataBlock.LocalVar, + ModuleBlock.MetadataBlock.Parameter, + ModuleBlock.MetadataBlock.GlobalVar, + ModuleBlock.MetadataBlock.GlobalVarExpression, + ModuleBlock.MetadataBlock.Constant, + ModuleBlock.MetadataBlock.Name, + ModuleBlock.MetadataBlock.NamedNode, + ModuleBlock.MetadataBlock.GlobalDeclAttachment, + }; + + pub const Code = enum(u6) { + /// MDSTRING: [values] + STRING_OLD = 1, + /// VALUE: [type num, value num] + VALUE = 2, + /// NODE: [n x md num] + NODE = 3, + /// STRING: [values] + NAME = 4, + /// DISTINCT_NODE: [n x md num] + DISTINCT_NODE = 5, + /// [n x [id, name]] + KIND = 6, + /// [distinct, line, col, scope, inlined-at?] + LOCATION = 7, + /// OLD_NODE: [n x (type num, value num)] + OLD_NODE = 8, + /// OLD_FN_NODE: [n x (type num, value num)] + OLD_FN_NODE = 9, + /// NAMED_NODE: [n x mdnodes] + NAMED_NODE = 10, + /// [m x [value, [n x [id, mdnode]]] + ATTACHMENT = 11, + /// [distinct, tag, vers, header, n x md num] + GENERIC_DEBUG = 12, + /// [distinct, count, lo] + SUBRANGE = 13, + /// [isUnsigned|distinct, value, name] + ENUMERATOR = 14, + /// [distinct, tag, name, size, align, enc] + BASIC_TYPE = 15, + /// [distinct, filename, directory, checksumkind, checksum] + FILE = 16, + /// [distinct, ...] + DERIVED_TYPE = 17, + /// [distinct, ...] + COMPOSITE_TYPE = 18, + /// [distinct, flags, types, cc] + SUBROUTINE_TYPE = 19, + /// [distinct, ...] + COMPILE_UNIT = 20, + /// [distinct, ...] + SUBPROGRAM = 21, + /// [distinct, scope, file, line, column] + LEXICAL_BLOCK = 22, + ///[distinct, scope, file, discriminator] + LEXICAL_BLOCK_FILE = 23, + /// [distinct, scope, file, name, line, exportSymbols] + NAMESPACE = 24, + /// [distinct, scope, name, type, ...] + TEMPLATE_TYPE = 25, + /// [distinct, scope, name, type, value, ...] + TEMPLATE_VALUE = 26, + /// [distinct, ...] + GLOBAL_VAR = 27, + /// [distinct, ...] + LOCAL_VAR = 28, + /// [distinct, n x element] + EXPRESSION = 29, + /// [distinct, name, file, line, ...] + OBJC_PROPERTY = 30, + /// [distinct, tag, scope, entity, line, name] + IMPORTED_ENTITY = 31, + /// [distinct, scope, name, ...] + MODULE = 32, + /// [distinct, macinfo, line, name, value] + MACRO = 33, + /// [distinct, macinfo, line, file, ...] + MACRO_FILE = 34, + /// [count, offset] blob([lengths][chars]) + STRINGS = 35, + /// [valueid, n x [id, mdnode]] + GLOBAL_DECL_ATTACHMENT = 36, + /// [distinct, var, expr] + GLOBAL_VAR_EXPR = 37, + /// [offset] + INDEX_OFFSET = 38, + /// [bitpos] + INDEX = 39, + /// [distinct, scope, name, file, line] + LABEL = 40, + /// [distinct, name, size, align,...] + STRING_TYPE = 41, + /// [distinct, scope, name, variable,...] + COMMON_BLOCK = 44, + /// [distinct, count, lo, up, stride] + GENERIC_SUBRANGE = 45, + /// [n x [type num, value num]] + ARG_LIST = 46, + /// [distinct, ...] + ASSIGN_ID = 47, + }; + + pub const Strings = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.STRINGS) }, + .{ .vbr = 6 }, + .{ .vbr = 6 }, + .blob, + }; + num_strings: u32, + strings_offset: u32, + blob: []const u8, + }; + + pub const File = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.FILE) }, + .{ .literal = 0 }, // is distinct + MetadataAbbrev, // filename + MetadataAbbrev, // directory + .{ .literal = 0 }, // checksum + .{ .literal = 0 }, // checksum + }; + + filename: Builder.Metadata.String.Optional, + directory: Builder.Metadata.String.Optional, + }; + + pub const CompileUnit = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.COMPILE_UNIT) }, + .{ .literal = 1 }, // is distinct + .{ .literal = std.dwarf.LANG.C99 }, // source language + MetadataAbbrev, // file + MetadataAbbrev, // producer + .{ .fixed = 1 }, // isOptimized + .{ .literal = 0 }, // raw flags + .{ .literal = 0 }, // runtime version + .{ .literal = 0 }, // split debug file name + .{ .literal = 1 }, // emission kind + MetadataAbbrev, // enums + .{ .literal = 0 }, // retained types + .{ .literal = 0 }, // subprograms + MetadataAbbrev, // globals + .{ .literal = 0 }, // imported entities + .{ .literal = 0 }, // DWO ID + .{ .literal = 0 }, // macros + .{ .literal = 0 }, // split debug inlining + .{ .literal = 0 }, // debug info profiling + .{ .literal = 0 }, // name table kind + .{ .literal = 0 }, // ranges base address + .{ .literal = 0 }, // raw sysroot + .{ .literal = 0 }, // raw SDK + }; + + file: Builder.Metadata.Optional, + producer: Builder.Metadata.String.Optional, + is_optimized: bool, + enums: Builder.Metadata.Optional, + globals: Builder.Metadata.Optional, + }; + + pub const Subprogram = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.SUBPROGRAM) }, + .{ .literal = 0b111 }, // is distinct | has sp flags | has flags + MetadataAbbrev, // scope + MetadataAbbrev, // name + MetadataAbbrev, // linkage name + MetadataAbbrev, // file + LineAbbrev, // line + MetadataAbbrev, // type + LineAbbrev, // scope line + .{ .literal = 0 }, // containing type + .{ .fixed = 32 }, // sp flags + .{ .literal = 0 }, // virtual index + .{ .fixed = 32 }, // flags + MetadataAbbrev, // compile unit + .{ .literal = 0 }, // template params + .{ .literal = 0 }, // declaration + .{ .literal = 0 }, // retained nodes + .{ .literal = 0 }, // this adjustment + .{ .literal = 0 }, // thrown types + .{ .literal = 0 }, // annotations + .{ .literal = 0 }, // target function name + }; + + scope: Builder.Metadata.Optional, + name: Builder.Metadata.String.Optional, + linkage_name: Builder.Metadata.String.Optional, + file: Builder.Metadata.Optional, + line: u32, + ty: Builder.Metadata.Optional, + scope_line: u32, + sp_flags: Builder.Metadata.Subprogram.DISPFlags, + flags: Builder.Metadata.DIFlags, + compile_unit: Builder.Metadata.Optional, + }; + + pub const LexicalBlock = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.LEXICAL_BLOCK) }, + .{ .literal = 0 }, // is distinct + MetadataAbbrev, // scope + MetadataAbbrev, // file + LineAbbrev, // line + ColumnAbbrev, // column + }; + + scope: Builder.Metadata.Optional, + file: Builder.Metadata.Optional, + line: u32, + column: u32, + }; + + pub const Location = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.LOCATION) }, + .{ .literal = 0 }, // is distinct + LineAbbrev, // line + ColumnAbbrev, // column + MetadataAbbrev, // scope + MetadataAbbrev, // inlined at + .{ .literal = 0 }, // is implicit code + }; + + line: u32, + column: u32, + scope: Builder.Metadata, + inlined_at: Builder.Metadata.Optional, + }; + + pub const BasicType = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.BASIC_TYPE) }, + .{ .literal = 0 }, // is distinct + .{ .literal = std.dwarf.TAG.base_type }, // tag + MetadataAbbrev, // name + .{ .vbr = 6 }, // size in bits + .{ .literal = 0 }, // align in bits + .{ .vbr = 8 }, // encoding + .{ .literal = 0 }, // flags + }; + + name: Builder.Metadata.String.Optional, + size_in_bits: u64, + encoding: u32, + }; + + pub const CompositeType = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.COMPOSITE_TYPE) }, + .{ .literal = 0 | 0x2 }, // is distinct | is not used in old type ref + .{ .fixed = 32 }, // tag + MetadataAbbrev, // name + MetadataAbbrev, // file + LineAbbrev, // line + MetadataAbbrev, // scope + MetadataAbbrev, // underlying type + .{ .vbr = 6 }, // size in bits + .{ .vbr = 6 }, // align in bits + .{ .literal = 0 }, // offset in bits + .{ .fixed = 32 }, // flags + MetadataAbbrev, // elements + .{ .literal = 0 }, // runtime lang + .{ .literal = 0 }, // vtable holder + .{ .literal = 0 }, // template params + .{ .literal = 0 }, // raw id + .{ .literal = 0 }, // discriminator + .{ .literal = 0 }, // data location + .{ .literal = 0 }, // associated + .{ .literal = 0 }, // allocated + .{ .literal = 0 }, // rank + .{ .literal = 0 }, // annotations + }; + + tag: u32, + name: Builder.Metadata.String.Optional, + file: Builder.Metadata.Optional, + line: u32, + scope: Builder.Metadata.Optional, + underlying_type: Builder.Metadata.Optional, + size_in_bits: u64, + align_in_bits: u64, + flags: Builder.Metadata.DIFlags, + elements: Builder.Metadata.Optional, + }; + + pub const DerivedType = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.DERIVED_TYPE) }, + .{ .literal = 0 }, // is distinct + .{ .fixed = 32 }, // tag + MetadataAbbrev, // name + MetadataAbbrev, // file + LineAbbrev, // line + MetadataAbbrev, // scope + MetadataAbbrev, // underlying type + .{ .vbr = 6 }, // size in bits + .{ .vbr = 6 }, // align in bits + .{ .vbr = 6 }, // offset in bits + .{ .literal = 0 }, // flags + .{ .literal = 0 }, // extra data + }; + + tag: u32, + name: Builder.Metadata.String.Optional, + file: Builder.Metadata.Optional, + line: u32, + scope: Builder.Metadata.Optional, + underlying_type: Builder.Metadata.Optional, + size_in_bits: u64, + align_in_bits: u64, + offset_in_bits: u64, + }; + + pub const SubroutineType = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.SUBROUTINE_TYPE) }, + .{ .literal = 0 | 0x2 }, // is distinct | has no old type refs + .{ .literal = 0 }, // flags + MetadataAbbrev, // types + .{ .literal = 0 }, // cc + }; + + types: Builder.Metadata.Optional, + }; + + pub const Enumerator = struct { + pub const Flags = packed struct(u3) { + distinct: bool = false, + unsigned: bool, + bigint: bool = true, + }; + + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.ENUMERATOR) }, + .{ .fixed = @bitSizeOf(Flags) }, // flags + .{ .vbr = 6 }, // bit width + MetadataAbbrev, // name + .{ .vbr = 16 }, // integer value + }; + + flags: Flags, + bit_width: u32, + name: Builder.Metadata.String.Optional, + value: u64, + }; + + pub const Subrange = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.SUBRANGE) }, + .{ .literal = 0 | (2 << 1) }, // is distinct | version + MetadataAbbrev, // count + MetadataAbbrev, // lower bound + .{ .literal = 0 }, // upper bound + .{ .literal = 0 }, // stride + }; + + count: Builder.Metadata.Optional, + lower_bound: Builder.Metadata.Optional, + }; + + pub const Expression = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.EXPRESSION) }, + .{ .literal = 0 | (3 << 1) }, // is distinct | version + MetadataArrayAbbrev, // elements + }; + + elements: []const u32, + }; + + pub const Node = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.NODE) }, + MetadataArrayAbbrev, // elements + }; + + elements: []const Builder.Metadata.Optional, + }; + + pub const LocalVar = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.LOCAL_VAR) }, + .{ .literal = 0b10 }, // is distinct | has alignment + MetadataAbbrev, // scope + MetadataAbbrev, // name + MetadataAbbrev, // file + LineAbbrev, // line + MetadataAbbrev, // type + .{ .literal = 0 }, // arg + .{ .literal = 0 }, // flags + .{ .literal = 0 }, // align bits + .{ .literal = 0 }, // annotations + }; + + scope: Builder.Metadata.Optional, + name: Builder.Metadata.String.Optional, + file: Builder.Metadata.Optional, + line: u32, + ty: Builder.Metadata.Optional, + }; + + pub const Parameter = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.LOCAL_VAR) }, + .{ .literal = 0b10 }, // is distinct | has alignment + MetadataAbbrev, // scope + MetadataAbbrev, // name + MetadataAbbrev, // file + LineAbbrev, // line + MetadataAbbrev, // type + .{ .vbr = 4 }, // arg + .{ .literal = 0 }, // flags + .{ .literal = 0 }, // align bits + .{ .literal = 0 }, // annotations + }; + + scope: Builder.Metadata.Optional, + name: Builder.Metadata.String.Optional, + file: Builder.Metadata.Optional, + line: u32, + ty: Builder.Metadata.Optional, + arg: u32, + }; + + pub const GlobalVar = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.GLOBAL_VAR) }, + .{ .literal = 0b101 }, // is distinct | version + MetadataAbbrev, // scope + MetadataAbbrev, // name + MetadataAbbrev, // linkage name + MetadataAbbrev, // file + LineAbbrev, // line + MetadataAbbrev, // type + .{ .fixed = 1 }, // local + .{ .literal = 1 }, // defined + .{ .literal = 0 }, // static data members declaration + .{ .literal = 0 }, // template params + .{ .literal = 0 }, // align in bits + .{ .literal = 0 }, // annotations + }; + + scope: Builder.Metadata.Optional, + name: Builder.Metadata.String.Optional, + linkage_name: Builder.Metadata.String.Optional, + file: Builder.Metadata.Optional, + line: u32, + ty: Builder.Metadata.Optional, + local: bool, + }; + + pub const GlobalVarExpression = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.GLOBAL_VAR_EXPR) }, + .{ .literal = 0 }, // is distinct + MetadataAbbrev, // variable + MetadataAbbrev, // expression + }; + + variable: Builder.Metadata.Optional, + expression: Builder.Metadata.Optional, + }; + + pub const Constant = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.VALUE) }, + MetadataAbbrev, // type + MetadataAbbrev, // value + }; + + ty: Builder.Type, + constant: Builder.Constant, + }; + + pub const Name = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.NAME) }, + .{ .array_fixed = 8 }, // name + }; + + name: []const u8, + }; + + pub const NamedNode = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.NAMED_NODE) }, + MetadataArrayAbbrev, // elements + }; + + elements: []const Builder.Metadata, + }; + + pub const GlobalDeclAttachment = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.GLOBAL_DECL_ATTACHMENT) }, + ValueAbbrev, // value id + .{ .fixed = 1 }, // kind + MetadataAbbrev, // elements + }; + + value: Builder.Constant, + kind: FixedMetadataKind, + metadata: Builder.Metadata, + }; + }; + + /// TYPE blocks have codes for each type primitive they use. + pub const TypeBlock = struct { + pub const id: BlockId = .TYPE; + + pub const abbrevs = [_]type{ + ModuleBlock.TypeBlock.NumEntry, + ModuleBlock.TypeBlock.Simple, + ModuleBlock.TypeBlock.Opaque, + ModuleBlock.TypeBlock.Integer, + ModuleBlock.TypeBlock.StructAnon, + ModuleBlock.TypeBlock.StructNamed, + ModuleBlock.TypeBlock.StructName, + ModuleBlock.TypeBlock.Array, + ModuleBlock.TypeBlock.Vector, + ModuleBlock.TypeBlock.Pointer, + ModuleBlock.TypeBlock.Target, + ModuleBlock.TypeBlock.Function, + }; + + pub const Code = enum(u5) { + /// NUMENTRY: [numentries] + NUMENTRY = 1, + + // Type Codes + /// VOID + VOID = 2, + /// FLOAT + FLOAT = 3, + /// DOUBLE + DOUBLE = 4, + /// LABEL + LABEL = 5, + /// OPAQUE + OPAQUE = 6, + /// INTEGER: [width] + INTEGER = 7, + /// POINTER: [pointee type] + POINTER = 8, + + /// FUNCTION: [vararg, attrid, retty, paramty x N] + FUNCTION_OLD = 9, + + /// HALF + HALF = 10, + + /// ARRAY: [numelts, eltty] + ARRAY = 11, + /// VECTOR: [numelts, eltty] + VECTOR = 12, + + // These are not with the other floating point types because they're + // a late addition, and putting them in the right place breaks + // binary compatibility. + /// X86 LONG DOUBLE + X86_FP80 = 13, + /// LONG DOUBLE (112 bit mantissa) + FP128 = 14, + /// PPC LONG DOUBLE (2 doubles) + PPC_FP128 = 15, + + /// METADATA + METADATA = 16, + + /// X86 MMX + X86_MMX = 17, + + /// STRUCT_ANON: [ispacked, eltty x N] + STRUCT_ANON = 18, + /// STRUCT_NAME: [strchr x N] + STRUCT_NAME = 19, + /// STRUCT_NAMED: [ispacked, eltty x N] + STRUCT_NAMED = 20, + + /// FUNCTION: [vararg, retty, paramty x N] + FUNCTION = 21, + + /// TOKEN + TOKEN = 22, + + /// BRAIN FLOATING POINT + BFLOAT = 23, + /// X86 AMX + X86_AMX = 24, + + /// OPAQUE_POINTER: [addrspace] + OPAQUE_POINTER = 25, + + /// TARGET_TYPE + TARGET_TYPE = 26, + }; + + pub const NumEntry = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.NUMENTRY) }, + .{ .fixed = 32 }, + }; + num: u32, + }; + + pub const Simple = struct { + pub const ops = [_]AbbrevOp{ + .{ .vbr = 4 }, + }; + code: ModuleBlock.TypeBlock.Code, + }; + + pub const Opaque = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.OPAQUE) }, + .{ .literal = 0 }, + }; + }; + + pub const Integer = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.INTEGER) }, + .{ .fixed = 28 }, + }; + width: u28, + }; + + pub const StructAnon = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.STRUCT_ANON) }, + .{ .fixed = 1 }, + .{ .array_fixed_runtime = Builder.Type }, + }; + is_packed: bool, + types: []const Builder.Type, + }; + + pub const StructNamed = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.STRUCT_NAMED) }, + .{ .fixed = 1 }, + .{ .array_fixed_runtime = Builder.Type }, + }; + is_packed: bool, + types: []const Builder.Type, + }; + + pub const StructName = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.STRUCT_NAME) }, + .{ .array_fixed = 8 }, + }; + string: []const u8, + }; + + pub const Array = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.ARRAY) }, + .{ .vbr = 16 }, + .{ .fixed_runtime = Builder.Type }, + }; + len: u64, + child: Builder.Type, + }; + + pub const Vector = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.VECTOR) }, + .{ .vbr = 16 }, + .{ .fixed_runtime = Builder.Type }, + }; + len: u64, + child: Builder.Type, + }; + + pub const Pointer = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.OPAQUE_POINTER) }, + .{ .vbr = 4 }, + }; + addr_space: Builder.AddrSpace, + }; + + pub const Target = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.TARGET_TYPE) }, + .{ .vbr = 4 }, + .{ .array_fixed_runtime = Builder.Type }, + .{ .array_fixed = 32 }, + }; + num_types: u32, + types: []const Builder.Type, + ints: []const u32, + }; + + pub const Function = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.TypeBlock.Code.FUNCTION) }, + .{ .fixed = 1 }, + .{ .fixed_runtime = Builder.Type }, + .{ .array_fixed_runtime = Builder.Type }, + }; + is_vararg: bool, + return_type: Builder.Type, + param_types: []const Builder.Type, + }; + }; + + pub const OperandBundleTagsBlock = struct { + pub const id: BlockId = .OPERAND_BUNDLE_TAGS; + + pub const abbrevs = [_]type{ + ModuleBlock.OperandBundleTagsBlock.OperandBundleTag, + }; + + pub const Code = enum(u1) { + /// TAG: [strchr x N] + OPERAND_BUNDLE_TAG = 1, + }; + + pub const OperandBundleTag = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.OperandBundleTagsBlock.Code.OPERAND_BUNDLE_TAG) }, + .array_char6, + }; + tag: []const u8, + }; + }; + + pub const MetadataKindBlock = struct { + pub const id: BlockId = .METADATA_KIND; + + pub const abbrevs = [_]type{ + ModuleBlock.MetadataKindBlock.Kind, + }; + + pub const Kind = struct { + pub const ops = [_]AbbrevOp{ + .{ .literal = @intFromEnum(ModuleBlock.MetadataBlock.Code.KIND) }, + .{ .vbr = 4 }, + .{ .array_fixed = 8 }, + }; + id: u32, + name: []const u8, + }; + }; }; -pub const BlockInfo = struct { - pub const id = 0; - - pub const set_block_id = 1; - - pub const abbrevs = [_]type{}; -}; - -pub const Type = struct { - pub const id = 17; +/// Identification block contains a string that describes the producer details, +/// and an epoch that defines the auto-upgrade capability. +pub const IdentificationBlock = struct { + pub const id: BlockId = .IDENTIFICATION; pub const abbrevs = [_]type{ - NumEntry, - Simple, - Opaque, - Integer, - StructAnon, - StructNamed, - StructName, - Array, - Vector, - Pointer, - Target, - Function, + IdentificationBlock.Version, + IdentificationBlock.Epoch, }; - pub const NumEntry = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 1 }, - .{ .fixed = 32 }, - }; - num: u32, + pub const Code = enum(u2) { + /// IDENTIFICATION: [strchr x N] + STRING = 1, + /// EPOCH: [epoch#] + EPOCH = 2, }; - pub const Simple = struct { + pub const Version = struct { pub const ops = [_]AbbrevOp{ - .{ .vbr = 4 }, - }; - code: u5, - }; - - pub const Opaque = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 6 }, - .{ .literal = 0 }, - }; - }; - - pub const Integer = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 7 }, - .{ .fixed = 28 }, - }; - width: u28, - }; - - pub const StructAnon = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 18 }, - .{ .fixed = 1 }, - .{ .array_fixed_runtime = Builder.Type }, - }; - is_packed: bool, - types: []const Builder.Type, - }; - - pub const StructNamed = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 20 }, - .{ .fixed = 1 }, - .{ .array_fixed_runtime = Builder.Type }, - }; - is_packed: bool, - types: []const Builder.Type, - }; - - pub const StructName = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 19 }, + .{ .literal = @intFromEnum(IdentificationBlock.Code.STRING) }, .{ .array_fixed = 8 }, }; string: []const u8, }; - pub const Array = struct { + pub const Epoch = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 11 }, - .{ .vbr = 16 }, - .{ .fixed_runtime = Builder.Type }, - }; - len: u64, - child: Builder.Type, - }; - - pub const Vector = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 12 }, - .{ .vbr = 16 }, - .{ .fixed_runtime = Builder.Type }, - }; - len: u64, - child: Builder.Type, - }; - - pub const Pointer = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 25 }, - .{ .vbr = 4 }, - }; - addr_space: Builder.AddrSpace, - }; - - pub const Target = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 26 }, - .{ .vbr = 4 }, - .{ .array_fixed_runtime = Builder.Type }, - .{ .array_fixed = 32 }, - }; - num_types: u32, - types: []const Builder.Type, - ints: []const u32, - }; - - pub const Function = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 21 }, - .{ .fixed = 1 }, - .{ .fixed_runtime = Builder.Type }, - .{ .array_fixed_runtime = Builder.Type }, - }; - is_vararg: bool, - return_type: Builder.Type, - param_types: []const Builder.Type, - }; -}; - -pub const Paramattr = struct { - pub const id = 9; - - pub const abbrevs = [_]type{ - Entry, - }; - - pub const Entry = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 2 }, - .{ .array_vbr = 8 }, - }; - group_indices: []const u64, - }; -}; - -pub const ParamattrGroup = struct { - pub const id = 10; - - pub const abbrevs = [_]type{}; -}; - -pub const Constants = struct { - pub const id = 11; - - pub const abbrevs = [_]type{ - SetType, - Null, - Undef, - Poison, - Integer, - Half, - Float, - Double, - Fp80, - Fp128, - Aggregate, - String, - CString, - Cast, - Binary, - Cmp, - ExtractElement, - InsertElement, - ShuffleVector, - ShuffleVectorEx, - BlockAddress, - DsoLocalEquivalentOrNoCfi, - }; - - pub const SetType = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 1 }, - .{ .fixed_runtime = Builder.Type }, - }; - type_id: Builder.Type, - }; - - pub const Null = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 2 }, - }; - }; - - pub const Undef = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 3 }, - }; - }; - - pub const Poison = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 26 }, - }; - }; - - pub const Integer = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 4 }, - .{ .vbr = 16 }, - }; - value: u64, - }; - - pub const Half = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 6 }, - .{ .fixed = 16 }, - }; - value: u16, - }; - - pub const Float = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 6 }, - .{ .fixed = 32 }, - }; - value: u32, - }; - - pub const Double = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 6 }, + .{ .literal = @intFromEnum(IdentificationBlock.Code.EPOCH) }, .{ .vbr = 6 }, }; - value: u64, - }; - - pub const Fp80 = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 6 }, - .{ .vbr = 6 }, - .{ .vbr = 6 }, - }; - hi: u64, - lo: u16, - }; - - pub const Fp128 = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 6 }, - .{ .vbr = 6 }, - .{ .vbr = 6 }, - }; - lo: u64, - hi: u64, - }; - - pub const Aggregate = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 7 }, - .{ .array_fixed = 32 }, - }; - values: []const Builder.Constant, - }; - - pub const String = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 8 }, - .{ .array_fixed = 8 }, - }; - string: []const u8, - }; - - pub const CString = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 9 }, - .{ .array_fixed = 8 }, - }; - string: []const u8, - }; - - pub const Cast = struct { - const CastOpcode = Builder.CastOpcode; - pub const ops = [_]AbbrevOp{ - .{ .literal = 11 }, - .{ .fixed = @bitSizeOf(CastOpcode) }, - .{ .fixed_runtime = Builder.Type }, - ConstantAbbrev, - }; - - opcode: CastOpcode, - type_index: Builder.Type, - val: Builder.Constant, - }; - - pub const Binary = struct { - const BinaryOpcode = Builder.BinaryOpcode; - pub const ops = [_]AbbrevOp{ - .{ .literal = 10 }, - .{ .fixed = @bitSizeOf(BinaryOpcode) }, - ConstantAbbrev, - ConstantAbbrev, - }; - - opcode: BinaryOpcode, - lhs: Builder.Constant, - rhs: Builder.Constant, - }; - - pub const Cmp = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 17 }, - .{ .fixed_runtime = Builder.Type }, - ConstantAbbrev, - ConstantAbbrev, - .{ .vbr = 6 }, - }; - - ty: Builder.Type, - lhs: Builder.Constant, - rhs: Builder.Constant, - pred: u32, - }; - - pub const ExtractElement = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 14 }, - .{ .fixed_runtime = Builder.Type }, - ConstantAbbrev, - .{ .fixed_runtime = Builder.Type }, - ConstantAbbrev, - }; - - val_type: Builder.Type, - val: Builder.Constant, - index_type: Builder.Type, - index: Builder.Constant, - }; - - pub const InsertElement = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 15 }, - ConstantAbbrev, - ConstantAbbrev, - .{ .fixed_runtime = Builder.Type }, - ConstantAbbrev, - }; - - val: Builder.Constant, - elem: Builder.Constant, - index_type: Builder.Type, - index: Builder.Constant, - }; - - pub const ShuffleVector = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 16 }, - ValueAbbrev, - ValueAbbrev, - ValueAbbrev, - }; - - lhs: Builder.Constant, - rhs: Builder.Constant, - mask: Builder.Constant, - }; - - pub const ShuffleVectorEx = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 19 }, - .{ .fixed_runtime = Builder.Type }, - ValueAbbrev, - ValueAbbrev, - ValueAbbrev, - }; - - ty: Builder.Type, - lhs: Builder.Constant, - rhs: Builder.Constant, - mask: Builder.Constant, - }; - - pub const BlockAddress = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 21 }, - .{ .fixed_runtime = Builder.Type }, - ConstantAbbrev, - BlockAbbrev, - }; - type_id: Builder.Type, - function: u32, - block: u32, - }; - - pub const DsoLocalEquivalentOrNoCfi = struct { - pub const ops = [_]AbbrevOp{ - .{ .fixed = 5 }, - .{ .fixed_runtime = Builder.Type }, - ConstantAbbrev, - }; - code: u5, - type_id: Builder.Type, - function: u32, + epoch: u32, }; }; -pub const MetadataKindBlock = struct { - pub const id = 22; - - pub const abbrevs = [_]type{ - Kind, - }; - - pub const Kind = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 6 }, - .{ .vbr = 4 }, - .{ .array_fixed = 8 }, - }; - id: u32, - name: []const u8, - }; -}; - -pub const MetadataAttachmentBlock = struct { - pub const id = 16; - - pub const abbrevs = [_]type{ - AttachmentGlobalSingle, - AttachmentInstructionSingle, - }; - - pub const AttachmentGlobalSingle = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.ATTACHMENT) }, - .{ .fixed = 1 }, - MetadataAbbrev, - }; - kind: FixedMetadataKind, - metadata: Builder.Metadata, - }; - - pub const AttachmentInstructionSingle = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.ATTACHMENT) }, - ValueAbbrev, - .{ .fixed = 5 }, - MetadataAbbrev, - }; - inst: u32, - kind: FixedMetadataKind, - metadata: Builder.Metadata, - }; -}; - -pub const MetadataBlock = struct { - pub const id = 15; - - pub const abbrevs = [_]type{ - Strings, - File, - CompileUnit, - Subprogram, - LexicalBlock, - Location, - BasicType, - CompositeType, - DerivedType, - SubroutineType, - Enumerator, - Subrange, - Expression, - Node, - LocalVar, - Parameter, - GlobalVar, - GlobalVarExpression, - Constant, - Name, - NamedNode, - GlobalDeclAttachment, - }; - - pub const Strings = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.STRINGS) }, - .{ .vbr = 6 }, - .{ .vbr = 6 }, - .blob, - }; - num_strings: u32, - strings_offset: u32, - blob: []const u8, - }; - - pub const File = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.FILE) }, - .{ .literal = 0 }, // is distinct - MetadataAbbrev, // filename - MetadataAbbrev, // directory - .{ .literal = 0 }, // checksum - .{ .literal = 0 }, // checksum - }; - - filename: Builder.MetadataString, - directory: Builder.MetadataString, - }; - - pub const CompileUnit = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.COMPILE_UNIT) }, - .{ .literal = 1 }, // is distinct - .{ .literal = std.dwarf.LANG.C99 }, // source language - MetadataAbbrev, // file - MetadataAbbrev, // producer - .{ .fixed = 1 }, // isOptimized - .{ .literal = 0 }, // raw flags - .{ .literal = 0 }, // runtime version - .{ .literal = 0 }, // split debug file name - .{ .literal = 1 }, // emission kind - MetadataAbbrev, // enums - .{ .literal = 0 }, // retained types - .{ .literal = 0 }, // subprograms - MetadataAbbrev, // globals - .{ .literal = 0 }, // imported entities - .{ .literal = 0 }, // DWO ID - .{ .literal = 0 }, // macros - .{ .literal = 0 }, // split debug inlining - .{ .literal = 0 }, // debug info profiling - .{ .literal = 0 }, // name table kind - .{ .literal = 0 }, // ranges base address - .{ .literal = 0 }, // raw sysroot - .{ .literal = 0 }, // raw SDK - }; - - file: Builder.Metadata, - producer: Builder.MetadataString, - is_optimized: bool, - enums: Builder.Metadata, - globals: Builder.Metadata, - }; - - pub const Subprogram = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.SUBPROGRAM) }, - .{ .literal = 0b111 }, // is distinct | has sp flags | has flags - MetadataAbbrev, // scope - MetadataAbbrev, // name - MetadataAbbrev, // linkage name - MetadataAbbrev, // file - LineAbbrev, // line - MetadataAbbrev, // type - LineAbbrev, // scope line - .{ .literal = 0 }, // containing type - .{ .fixed = 32 }, // sp flags - .{ .literal = 0 }, // virtual index - .{ .fixed = 32 }, // flags - MetadataAbbrev, // compile unit - .{ .literal = 0 }, // template params - .{ .literal = 0 }, // declaration - .{ .literal = 0 }, // retained nodes - .{ .literal = 0 }, // this adjustment - .{ .literal = 0 }, // thrown types - .{ .literal = 0 }, // annotations - .{ .literal = 0 }, // target function name - }; - - scope: Builder.Metadata, - name: Builder.MetadataString, - linkage_name: Builder.MetadataString, - file: Builder.Metadata, - line: u32, - ty: Builder.Metadata, - scope_line: u32, - sp_flags: Builder.Metadata.Subprogram.DISPFlags, - flags: Builder.Metadata.DIFlags, - compile_unit: Builder.Metadata, - }; - - pub const LexicalBlock = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.LEXICAL_BLOCK) }, - .{ .literal = 0 }, // is distinct - MetadataAbbrev, // scope - MetadataAbbrev, // file - LineAbbrev, // line - ColumnAbbrev, // column - }; - - scope: Builder.Metadata, - file: Builder.Metadata, - line: u32, - column: u32, - }; - - pub const Location = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.LOCATION) }, - .{ .literal = 0 }, // is distinct - LineAbbrev, // line - ColumnAbbrev, // column - MetadataAbbrev, // scope - MetadataAbbrev, // inlined at - .{ .literal = 0 }, // is implicit code - }; - - line: u32, - column: u32, - scope: u32, - inlined_at: Builder.Metadata, - }; - - pub const BasicType = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.BASIC_TYPE) }, - .{ .literal = 0 }, // is distinct - .{ .literal = std.dwarf.TAG.base_type }, // tag - MetadataAbbrev, // name - .{ .vbr = 6 }, // size in bits - .{ .literal = 0 }, // align in bits - .{ .vbr = 8 }, // encoding - .{ .literal = 0 }, // flags - }; - - name: Builder.MetadataString, - size_in_bits: u64, - encoding: u32, - }; - - pub const CompositeType = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.COMPOSITE_TYPE) }, - .{ .literal = 0 | 0x2 }, // is distinct | is not used in old type ref - .{ .fixed = 32 }, // tag - MetadataAbbrev, // name - MetadataAbbrev, // file - LineAbbrev, // line - MetadataAbbrev, // scope - MetadataAbbrev, // underlying type - .{ .vbr = 6 }, // size in bits - .{ .vbr = 6 }, // align in bits - .{ .literal = 0 }, // offset in bits - .{ .fixed = 32 }, // flags - MetadataAbbrev, // elements - .{ .literal = 0 }, // runtime lang - .{ .literal = 0 }, // vtable holder - .{ .literal = 0 }, // template params - .{ .literal = 0 }, // raw id - .{ .literal = 0 }, // discriminator - .{ .literal = 0 }, // data location - .{ .literal = 0 }, // associated - .{ .literal = 0 }, // allocated - .{ .literal = 0 }, // rank - .{ .literal = 0 }, // annotations - }; - - tag: u32, - name: Builder.MetadataString, - file: Builder.Metadata, - line: u32, - scope: Builder.Metadata, - underlying_type: Builder.Metadata, - size_in_bits: u64, - align_in_bits: u64, - flags: Builder.Metadata.DIFlags, - elements: Builder.Metadata, - }; - - pub const DerivedType = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.DERIVED_TYPE) }, - .{ .literal = 0 }, // is distinct - .{ .fixed = 32 }, // tag - MetadataAbbrev, // name - MetadataAbbrev, // file - LineAbbrev, // line - MetadataAbbrev, // scope - MetadataAbbrev, // underlying type - .{ .vbr = 6 }, // size in bits - .{ .vbr = 6 }, // align in bits - .{ .vbr = 6 }, // offset in bits - .{ .literal = 0 }, // flags - .{ .literal = 0 }, // extra data - }; - - tag: u32, - name: Builder.MetadataString, - file: Builder.Metadata, - line: u32, - scope: Builder.Metadata, - underlying_type: Builder.Metadata, - size_in_bits: u64, - align_in_bits: u64, - offset_in_bits: u64, - }; - - pub const SubroutineType = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.SUBROUTINE_TYPE) }, - .{ .literal = 0 | 0x2 }, // is distinct | has no old type refs - .{ .literal = 0 }, // flags - MetadataAbbrev, // types - .{ .literal = 0 }, // cc - }; - - types: Builder.Metadata, - }; - - pub const Enumerator = struct { - pub const id: MetadataCode = .ENUMERATOR; - - pub const Flags = packed struct(u3) { - distinct: bool = false, - unsigned: bool, - bigint: bool = true, - }; - - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(Enumerator.id) }, - .{ .fixed = @bitSizeOf(Flags) }, // flags - .{ .vbr = 6 }, // bit width - MetadataAbbrev, // name - .{ .vbr = 16 }, // integer value - }; - - flags: Flags, - bit_width: u32, - name: Builder.MetadataString, - value: u64, - }; - - pub const Subrange = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.SUBRANGE) }, - .{ .literal = 0 | (2 << 1) }, // is distinct | version - MetadataAbbrev, // count - MetadataAbbrev, // lower bound - .{ .literal = 0 }, // upper bound - .{ .literal = 0 }, // stride - }; - - count: Builder.Metadata, - lower_bound: Builder.Metadata, - }; - - pub const Expression = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.EXPRESSION) }, - .{ .literal = 0 | (3 << 1) }, // is distinct | version - MetadataArrayAbbrev, // elements - }; - - elements: []const u32, - }; - - pub const Node = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.NODE) }, - MetadataArrayAbbrev, // elements - }; - - elements: []const Builder.Metadata, - }; - - pub const LocalVar = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.LOCAL_VAR) }, - .{ .literal = 0b10 }, // is distinct | has alignment - MetadataAbbrev, // scope - MetadataAbbrev, // name - MetadataAbbrev, // file - LineAbbrev, // line - MetadataAbbrev, // type - .{ .literal = 0 }, // arg - .{ .literal = 0 }, // flags - .{ .literal = 0 }, // align bits - .{ .literal = 0 }, // annotations - }; - - scope: Builder.Metadata, - name: Builder.MetadataString, - file: Builder.Metadata, - line: u32, - ty: Builder.Metadata, - }; - - pub const Parameter = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.LOCAL_VAR) }, - .{ .literal = 0b10 }, // is distinct | has alignment - MetadataAbbrev, // scope - MetadataAbbrev, // name - MetadataAbbrev, // file - LineAbbrev, // line - MetadataAbbrev, // type - .{ .vbr = 4 }, // arg - .{ .literal = 0 }, // flags - .{ .literal = 0 }, // align bits - .{ .literal = 0 }, // annotations - }; - - scope: Builder.Metadata, - name: Builder.MetadataString, - file: Builder.Metadata, - line: u32, - ty: Builder.Metadata, - arg: u32, - }; - - pub const GlobalVar = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.GLOBAL_VAR) }, - .{ .literal = 0b101 }, // is distinct | version - MetadataAbbrev, // scope - MetadataAbbrev, // name - MetadataAbbrev, // linkage name - MetadataAbbrev, // file - LineAbbrev, // line - MetadataAbbrev, // type - .{ .fixed = 1 }, // local - .{ .literal = 1 }, // defined - .{ .literal = 0 }, // static data members declaration - .{ .literal = 0 }, // template params - .{ .literal = 0 }, // align in bits - .{ .literal = 0 }, // annotations - }; - - scope: Builder.Metadata, - name: Builder.MetadataString, - linkage_name: Builder.MetadataString, - file: Builder.Metadata, - line: u32, - ty: Builder.Metadata, - local: bool, - }; - - pub const GlobalVarExpression = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.GLOBAL_VAR_EXPR) }, - .{ .literal = 0 }, // is distinct - MetadataAbbrev, // variable - MetadataAbbrev, // expression - }; - - variable: Builder.Metadata, - expression: Builder.Metadata, - }; - - pub const Constant = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.VALUE) }, - MetadataAbbrev, // type - MetadataAbbrev, // value - }; - - ty: Builder.Type, - constant: Builder.Constant, - }; - - pub const Name = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.NAME) }, - .{ .array_fixed = 8 }, // name - }; - - name: []const u8, - }; - - pub const NamedNode = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.NAMED_NODE) }, - MetadataArrayAbbrev, // elements - }; - - elements: []const Builder.Metadata, - }; - - pub const GlobalDeclAttachment = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = @intFromEnum(MetadataCode.GLOBAL_DECL_ATTACHMENT) }, - ValueAbbrev, // value id - .{ .fixed = 1 }, // kind - MetadataAbbrev, // elements - }; - - value: Builder.Constant, - kind: FixedMetadataKind, - metadata: Builder.Metadata, - }; -}; - -pub const OperandBundleTags = struct { - pub const id = 21; - - pub const abbrevs = [_]type{OperandBundleTag}; - - pub const OperandBundleTag = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 1 }, - .array_char6, - }; - tag: []const u8, - }; -}; - -pub const FunctionMetadataBlock = struct { - pub const id = 15; - - pub const abbrevs = [_]type{ - Value, - }; - - pub const Value = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 2 }, - .{ .fixed = 32 }, // variable - .{ .fixed = 32 }, // expression - }; - - ty: Builder.Type, - value: Builder.Value, - }; -}; - -pub const FunctionBlock = struct { - pub const id = 12; - - pub const abbrevs = [_]type{ - DeclareBlocks, - Call, - CallFast, - FNeg, - FNegFast, - Binary, - BinaryNoWrap, - BinaryExact, - BinaryFast, - Cmp, - CmpFast, - Select, - SelectFast, - Cast, - Alloca, - GetElementPtr, - ExtractValue, - InsertValue, - ExtractElement, - InsertElement, - ShuffleVector, - RetVoid, - Ret, - Unreachable, - Load, - LoadAtomic, - Store, - StoreAtomic, - BrUnconditional, - BrConditional, - VaArg, - AtomicRmw, - CmpXchg, - Fence, - DebugLoc, - DebugLocAgain, - ColdOperandBundle, - IndirectBr, - }; - - pub const DeclareBlocks = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 1 }, - .{ .vbr = 8 }, - }; - num_blocks: usize, - }; - - pub const Call = struct { - pub const CallType = packed struct(u17) { - tail: bool = false, - call_conv: Builder.CallConv, - reserved: u3 = 0, - must_tail: bool = false, - // We always use the explicit type version as that is what LLVM does - explicit_type: bool = true, - no_tail: bool = false, - }; - pub const ops = [_]AbbrevOp{ - .{ .literal = 34 }, - .{ .fixed_runtime = Builder.FunctionAttributes }, - .{ .fixed = @bitSizeOf(CallType) }, - .{ .fixed_runtime = Builder.Type }, - ValueAbbrev, // Callee - ValueArrayAbbrev, // Args - }; - - attributes: Builder.FunctionAttributes, - call_type: CallType, - type_id: Builder.Type, - callee: Builder.Value, - args: []const Builder.Value, - }; - - pub const CallFast = struct { - const CallType = packed struct(u18) { - tail: bool = false, - call_conv: Builder.CallConv, - reserved: u3 = 0, - must_tail: bool = false, - // We always use the explicit type version as that is what LLVM does - explicit_type: bool = true, - no_tail: bool = false, - fast: bool = true, - }; - - pub const ops = [_]AbbrevOp{ - .{ .literal = 34 }, - .{ .fixed_runtime = Builder.FunctionAttributes }, - .{ .fixed = @bitSizeOf(CallType) }, - .{ .fixed = @bitSizeOf(Builder.FastMath) }, - .{ .fixed_runtime = Builder.Type }, - ValueAbbrev, // Callee - ValueArrayAbbrev, // Args - }; - - attributes: Builder.FunctionAttributes, - call_type: CallType, - fast_math: Builder.FastMath, - type_id: Builder.Type, - callee: Builder.Value, - args: []const Builder.Value, - }; - - pub const FNeg = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 56 }, - ValueAbbrev, - .{ .literal = 0 }, - }; - - val: u32, - }; - - pub const FNegFast = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 56 }, - ValueAbbrev, - .{ .literal = 0 }, - .{ .fixed = @bitSizeOf(Builder.FastMath) }, - }; - - val: u32, - fast_math: Builder.FastMath, - }; - - pub const Binary = struct { - const BinaryOpcode = Builder.BinaryOpcode; - pub const ops = [_]AbbrevOp{ - .{ .literal = 2 }, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = @bitSizeOf(BinaryOpcode) }, - }; - - lhs: u32, - rhs: u32, - opcode: BinaryOpcode, - }; - - pub const BinaryNoWrap = struct { - const BinaryOpcode = Builder.BinaryOpcode; - pub const ops = [_]AbbrevOp{ - .{ .literal = 2 }, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = @bitSizeOf(BinaryOpcode) }, - .{ .fixed = 2 }, - }; - - lhs: u32, - rhs: u32, - opcode: BinaryOpcode, - flags: packed struct(u2) { - no_unsigned_wrap: bool, - no_signed_wrap: bool, - }, - }; - - pub const BinaryExact = struct { - const BinaryOpcode = Builder.BinaryOpcode; - pub const ops = [_]AbbrevOp{ - .{ .literal = 2 }, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = @bitSizeOf(BinaryOpcode) }, - .{ .literal = 1 }, - }; - - lhs: u32, - rhs: u32, - opcode: BinaryOpcode, - }; - - pub const BinaryFast = struct { - const BinaryOpcode = Builder.BinaryOpcode; - pub const ops = [_]AbbrevOp{ - .{ .literal = 2 }, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = @bitSizeOf(BinaryOpcode) }, - .{ .fixed = @bitSizeOf(Builder.FastMath) }, - }; - - lhs: u32, - rhs: u32, - opcode: BinaryOpcode, - fast_math: Builder.FastMath, - }; - - pub const Cmp = struct { - const CmpPredicate = Builder.CmpPredicate; - pub const ops = [_]AbbrevOp{ - .{ .literal = 28 }, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = @bitSizeOf(CmpPredicate) }, - }; - - lhs: u32, - rhs: u32, - pred: CmpPredicate, - }; - - pub const CmpFast = struct { - const CmpPredicate = Builder.CmpPredicate; - pub const ops = [_]AbbrevOp{ - .{ .literal = 28 }, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = @bitSizeOf(CmpPredicate) }, - .{ .fixed = @bitSizeOf(Builder.FastMath) }, - }; - - lhs: u32, - rhs: u32, - pred: CmpPredicate, - fast_math: Builder.FastMath, - }; - - pub const Select = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 29 }, - ValueAbbrev, - ValueAbbrev, - ValueAbbrev, - }; - - lhs: u32, - rhs: u32, - cond: u32, - }; - - pub const SelectFast = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 29 }, - ValueAbbrev, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = @bitSizeOf(Builder.FastMath) }, - }; - - lhs: u32, - rhs: u32, - cond: u32, - fast_math: Builder.FastMath, - }; - - pub const Cast = struct { - const CastOpcode = Builder.CastOpcode; - pub const ops = [_]AbbrevOp{ - .{ .literal = 3 }, - ValueAbbrev, - .{ .fixed_runtime = Builder.Type }, - .{ .fixed = @bitSizeOf(CastOpcode) }, - }; - - val: u32, - type_index: Builder.Type, - opcode: CastOpcode, - }; - - pub const Alloca = struct { - pub const Flags = packed struct(u11) { - align_lower: u5, - inalloca: bool, - explicit_type: bool, - swift_error: bool, - align_upper: u3, - }; - pub const ops = [_]AbbrevOp{ - .{ .literal = 19 }, - .{ .fixed_runtime = Builder.Type }, - .{ .fixed_runtime = Builder.Type }, - ValueAbbrev, - .{ .fixed = @bitSizeOf(Flags) }, - }; - - inst_type: Builder.Type, - len_type: Builder.Type, - len_value: u32, - flags: Flags, - }; - - pub const RetVoid = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 10 }, - }; - }; - - pub const Ret = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 10 }, - ValueAbbrev, - }; - val: u32, - }; - - pub const GetElementPtr = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 43 }, - .{ .fixed = 1 }, - .{ .fixed_runtime = Builder.Type }, - ValueAbbrev, - ValueArrayAbbrev, - }; - - is_inbounds: bool, - type_index: Builder.Type, - base: Builder.Value, - indices: []const Builder.Value, - }; - - pub const ExtractValue = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 26 }, - ValueAbbrev, - ValueArrayAbbrev, - }; - - val: u32, - indices: []const u32, - }; - - pub const InsertValue = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 27 }, - ValueAbbrev, - ValueAbbrev, - ValueArrayAbbrev, - }; - - val: u32, - elem: u32, - indices: []const u32, - }; - - pub const ExtractElement = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 6 }, - ValueAbbrev, - ValueAbbrev, - }; - - val: u32, - index: u32, - }; - - pub const InsertElement = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 7 }, - ValueAbbrev, - ValueAbbrev, - ValueAbbrev, - }; - - val: u32, - elem: u32, - index: u32, - }; - - pub const ShuffleVector = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 8 }, - ValueAbbrev, - ValueAbbrev, - ValueAbbrev, - }; - - lhs: u32, - rhs: u32, - mask: u32, - }; - - pub const Unreachable = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 15 }, - }; - }; - - pub const Load = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 20 }, - ValueAbbrev, - .{ .fixed_runtime = Builder.Type }, - .{ .fixed = @bitSizeOf(Builder.Alignment) }, - .{ .fixed = 1 }, - }; - ptr: u32, - ty: Builder.Type, - alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), - is_volatile: bool, - }; - - pub const LoadAtomic = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 41 }, - ValueAbbrev, - .{ .fixed_runtime = Builder.Type }, - .{ .fixed = @bitSizeOf(Builder.Alignment) }, - .{ .fixed = 1 }, - .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, - .{ .fixed = @bitSizeOf(Builder.SyncScope) }, - }; - ptr: u32, - ty: Builder.Type, - alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), - is_volatile: bool, - success_ordering: Builder.AtomicOrdering, - sync_scope: Builder.SyncScope, - }; - - pub const Store = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 44 }, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = @bitSizeOf(Builder.Alignment) }, - .{ .fixed = 1 }, - }; - ptr: u32, - val: u32, - alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), - is_volatile: bool, - }; - - pub const StoreAtomic = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 45 }, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = @bitSizeOf(Builder.Alignment) }, - .{ .fixed = 1 }, - .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, - .{ .fixed = @bitSizeOf(Builder.SyncScope) }, - }; - ptr: u32, - val: u32, - alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), - is_volatile: bool, - success_ordering: Builder.AtomicOrdering, - sync_scope: Builder.SyncScope, - }; - - pub const BrUnconditional = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 11 }, - BlockAbbrev, - }; - block: u32, - }; - - pub const BrConditional = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 11 }, - BlockAbbrev, - BlockAbbrev, - BlockAbbrev, - }; - then_block: u32, - else_block: u32, - condition: u32, - }; - - pub const VaArg = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 23 }, - .{ .fixed_runtime = Builder.Type }, - ValueAbbrev, - .{ .fixed_runtime = Builder.Type }, - }; - list_type: Builder.Type, - list: u32, - type: Builder.Type, - }; - - pub const AtomicRmw = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 59 }, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = @bitSizeOf(Builder.Function.Instruction.AtomicRmw.Operation) }, - .{ .fixed = 1 }, - .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, - .{ .fixed = @bitSizeOf(Builder.SyncScope) }, - .{ .fixed = @bitSizeOf(Builder.Alignment) }, - }; - ptr: u32, - val: u32, - operation: Builder.Function.Instruction.AtomicRmw.Operation, - is_volatile: bool, - success_ordering: Builder.AtomicOrdering, - sync_scope: Builder.SyncScope, - alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), - }; - - pub const CmpXchg = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 46 }, - ValueAbbrev, - ValueAbbrev, - ValueAbbrev, - .{ .fixed = 1 }, - .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, - .{ .fixed = @bitSizeOf(Builder.SyncScope) }, - .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, - .{ .fixed = 1 }, - .{ .fixed = @bitSizeOf(Builder.Alignment) }, - }; - ptr: u32, - cmp: u32, - new: u32, - is_volatile: bool, - success_ordering: Builder.AtomicOrdering, - sync_scope: Builder.SyncScope, - failure_ordering: Builder.AtomicOrdering, - is_weak: bool, - alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), - }; - - pub const Fence = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 36 }, - .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) }, - .{ .fixed = @bitSizeOf(Builder.SyncScope) }, - }; - ordering: Builder.AtomicOrdering, - sync_scope: Builder.SyncScope, - }; - - pub const DebugLoc = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 35 }, - LineAbbrev, - ColumnAbbrev, - MetadataAbbrev, - MetadataAbbrev, - .{ .literal = 0 }, - }; - line: u32, - column: u32, - scope: Builder.Metadata, - inlined_at: Builder.Metadata, - }; - - pub const DebugLocAgain = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 33 }, - }; - }; - - pub const ColdOperandBundle = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 55 }, - .{ .literal = 0 }, - }; - }; - - pub const IndirectBr = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 31 }, - .{ .fixed_runtime = Builder.Type }, - ValueAbbrev, - BlockArrayAbbrev, - }; - ty: Builder.Type, - addr: Builder.Value, - targets: []const Builder.Function.Block.Index, - }; -}; - -pub const FunctionValueSymbolTable = struct { - pub const id = 14; - - pub const abbrevs = [_]type{ - BlockEntry, - }; - - pub const BlockEntry = struct { - pub const ops = [_]AbbrevOp{ - .{ .literal = 2 }, - ValueAbbrev, - .{ .array_fixed = 8 }, - }; - value_id: u32, - string: []const u8, - }; -}; - -pub const Strtab = struct { - pub const id = 23; +pub const StrtabBlock = struct { + pub const id: BlockId = .STRTAB; pub const abbrevs = [_]type{Blob}; + pub const Code = enum(u1) { + BLOB = 1, + }; + pub const Blob = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 1 }, + .{ .literal = @intFromEnum(StrtabBlock.Code.BLOB) }, .blob, }; blob: []const u8, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 6a33557e07..20e5696c15 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -508,16 +508,16 @@ pub const Object = struct { gpa: Allocator, builder: Builder, - debug_compile_unit: Builder.Metadata, + debug_compile_unit: Builder.Metadata.Optional, - debug_enums_fwd_ref: Builder.Metadata, - debug_globals_fwd_ref: Builder.Metadata, + debug_enums_fwd_ref: Builder.Metadata.Optional, + debug_globals_fwd_ref: Builder.Metadata.Optional, debug_enums: std.ArrayListUnmanaged(Builder.Metadata), debug_globals: std.ArrayListUnmanaged(Builder.Metadata), debug_file_map: std.AutoHashMapUnmanaged(Zcu.File.Index, Builder.Metadata), - debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata), + debug_type_map: std.AutoHashMapUnmanaged(InternPool.Index, Builder.Metadata), debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata), @@ -630,9 +630,13 @@ pub const Object = struct { .{ .optimized = comp.root_mod.optimize_mode != .Debug }, ); - try builder.metadataNamed(try builder.metadataString("llvm.dbg.cu"), &.{debug_compile_unit}); - break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref }; - } else .{.none} ** 3; + try builder.addNamedMetadata(try builder.string("llvm.dbg.cu"), &.{debug_compile_unit}); + break :debug_info .{ + debug_compile_unit.toOptional(), + debug_enums_fwd_ref.toOptional(), + debug_globals_fwd_ref.toOptional(), + }; + } else .{Builder.Metadata.Optional.none} ** 3; const obj = try arena.create(Object); obj.* = .{ @@ -816,17 +820,17 @@ pub const Object = struct { const namespace = zcu.namespacePtr(namespace_index); const debug_type = try o.lowerDebugType(pt, Type.fromInterned(namespace.owner_type)); - o.builder.debugForwardReferenceSetType(fwd_ref, debug_type); + o.builder.resolveDebugForwardReference(fwd_ref, debug_type); } } - o.builder.debugForwardReferenceSetType( - o.debug_enums_fwd_ref, + o.builder.resolveDebugForwardReference( + o.debug_enums_fwd_ref.unwrap().?, try o.builder.metadataTuple(o.debug_enums.items), ); - o.builder.debugForwardReferenceSetType( - o.debug_globals_fwd_ref, + o.builder.resolveDebugForwardReference( + o.debug_globals_fwd_ref.unwrap().?, try o.builder.metadataTuple(o.debug_globals.items), ); } @@ -842,36 +846,34 @@ pub const Object = struct { const behavior_min = try o.builder.metadataConstant(try o.builder.intConst(.i32, 8)); if (target_util.llvmMachineAbi(&comp.root_mod.resolved_target.result)) |abi| { - module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag( + module_flags.appendAssumeCapacity(try o.builder.metadataTuple(&.{ behavior_error, - try o.builder.metadataString("target-abi"), - try o.builder.metadataConstant( - try o.builder.stringConst(try o.builder.string(abi)), - ), - )); + (try o.builder.metadataString("target-abi")).toMetadata(), + (try o.builder.metadataString(abi)).toMetadata(), + })); } const pic_level = target_util.picLevel(&comp.root_mod.resolved_target.result); if (comp.root_mod.pic) { - module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag( + module_flags.appendAssumeCapacity(try o.builder.metadataTuple(&.{ behavior_min, - try o.builder.metadataString("PIC Level"), + (try o.builder.metadataString("PIC Level")).toMetadata(), try o.builder.metadataConstant(try o.builder.intConst(.i32, pic_level)), - )); + })); } if (comp.config.pie) { - module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag( + module_flags.appendAssumeCapacity(try o.builder.metadataTuple(&.{ behavior_max, - try o.builder.metadataString("PIE Level"), + (try o.builder.metadataString("PIE Level")).toMetadata(), try o.builder.metadataConstant(try o.builder.intConst(.i32, pic_level)), - )); + })); } if (comp.root_mod.code_model != .default) { - module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag( + module_flags.appendAssumeCapacity(try o.builder.metadataTuple(&.{ behavior_error, - try o.builder.metadataString("Code Model"), + (try o.builder.metadataString("Code Model")).toMetadata(), try o.builder.metadataConstant(try o.builder.intConst(.i32, @as( i32, switch (codeModel(comp.root_mod.code_model, &comp.root_mod.resolved_target.result)) { @@ -883,39 +885,39 @@ pub const Object = struct { .large => 4, }, ))), - )); + })); } if (!o.builder.strip) { - module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag( + module_flags.appendAssumeCapacity(try o.builder.metadataTuple(&.{ behavior_warning, - try o.builder.metadataString("Debug Info Version"), + (try o.builder.metadataString("Debug Info Version")).toMetadata(), try o.builder.metadataConstant(try o.builder.intConst(.i32, 3)), - )); + })); switch (comp.config.debug_format) { .strip => unreachable, .dwarf => |f| { - module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag( + module_flags.appendAssumeCapacity(try o.builder.metadataTuple(&.{ behavior_max, - try o.builder.metadataString("Dwarf Version"), + (try o.builder.metadataString("Dwarf Version")).toMetadata(), try o.builder.metadataConstant(try o.builder.intConst(.i32, 4)), - )); + })); if (f == .@"64") { - module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag( + module_flags.appendAssumeCapacity(try o.builder.metadataTuple(&.{ behavior_max, - try o.builder.metadataString("DWARF64"), + (try o.builder.metadataString("DWARF64")).toMetadata(), try o.builder.metadataConstant(.@"1"), - )); + })); } }, .code_view => { - module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag( + module_flags.appendAssumeCapacity(try o.builder.metadataTuple(&.{ behavior_warning, - try o.builder.metadataString("CodeView"), + (try o.builder.metadataString("CodeView")).toMetadata(), try o.builder.metadataConstant(.@"1"), - )); + })); }, } } @@ -925,14 +927,14 @@ pub const Object = struct { // Add the "RegCallv4" flag so that any functions using `x86_regcallcc` use regcall // v4, which is essentially a requirement on Windows. See corresponding logic in // `toLlvmCallConvTag`. - module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag( + module_flags.appendAssumeCapacity(try o.builder.metadataTuple(&.{ behavior_max, - try o.builder.metadataString("RegCallv4"), + (try o.builder.metadataString("RegCallv4")).toMetadata(), try o.builder.metadataConstant(.@"1"), - )); + })); } - try o.builder.metadataNamed(try o.builder.metadataString("llvm.module.flags"), module_flags.items); + try o.builder.addNamedMetadata(try o.builder.string("llvm.module.flags"), module_flags.items); } const target_triple_sentinel = @@ -1477,11 +1479,11 @@ pub const Object = struct { .LocalToUnit = is_internal_linkage, }, }, - o.debug_compile_unit, + o.debug_compile_unit.unwrap().?, ); function_index.setSubprogram(subprogram, &o.builder); break :debug_info .{ file, subprogram }; - } else .{.none} ** 2; + } else .{undefined} ** 2; const fuzz: ?FuncGen.Fuzz = f: { if (!owner_mod.fuzz) break :f null; @@ -1807,7 +1809,7 @@ pub const Object = struct { const zcu = pt.zcu; const ip = &zcu.intern_pool; - if (o.debug_type_map.get(ty)) |debug_type| return debug_type; + if (o.debug_type_map.get(ty.toIntern())) |debug_type| return debug_type; switch (ty.zigTypeTag(zcu)) { .void, @@ -1817,7 +1819,7 @@ pub const Object = struct { try o.builder.metadataString("void"), 0, ); - try o.debug_type_map.put(gpa, ty, debug_void_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_void_type); return debug_void_type; }, .int => { @@ -1831,13 +1833,13 @@ pub const Object = struct { .signed => try o.builder.debugSignedType(builder_name, debug_bits), .unsigned => try o.builder.debugUnsignedType(builder_name, debug_bits), }; - try o.debug_type_map.put(gpa, ty, debug_int_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_int_type); return debug_int_type; }, .@"enum" => { if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { const debug_enum_type = try o.makeEmptyNamespaceDebugType(pt, ty); - try o.debug_type_map.put(gpa, ty, debug_enum_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_enum_type); return debug_enum_type; } @@ -1884,7 +1886,7 @@ pub const Object = struct { try o.builder.metadataTuple(enumerators), ); - try o.debug_type_map.put(gpa, ty, debug_enum_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_enum_type); try o.debug_enums.append(gpa, debug_enum_type); return debug_enum_type; }, @@ -1896,7 +1898,7 @@ pub const Object = struct { try o.builder.metadataString(name), bits, ); - try o.debug_type_map.put(gpa, ty, debug_float_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_float_type); return debug_float_type; }, .bool => { @@ -1904,7 +1906,7 @@ pub const Object = struct { try o.builder.metadataString("bool"), 8, // lldb cannot handle non-byte sized types ); - try o.debug_type_map.put(gpa, ty, debug_bool_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_bool_type); return debug_bool_type; }, .pointer => { @@ -1936,14 +1938,14 @@ pub const Object = struct { }, }); const debug_ptr_type = try o.lowerDebugType(pt, bland_ptr_ty); - try o.debug_type_map.put(gpa, ty, debug_ptr_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_ptr_type); return debug_ptr_type; } const debug_fwd_ref = try o.builder.debugForwardReference(); // Set as forward reference while the type is lowered in case it references itself - try o.debug_type_map.put(gpa, ty, debug_fwd_ref); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_fwd_ref); if (ty.isSlice(zcu)) { const ptr_ty = ty.slicePtrFieldType(zcu); @@ -1962,7 +1964,7 @@ pub const Object = struct { const debug_ptr_type = try o.builder.debugMemberType( try o.builder.metadataString("ptr"), - .none, // File + null, // File debug_fwd_ref, 0, // Line try o.lowerDebugType(pt, ptr_ty), @@ -1973,7 +1975,7 @@ pub const Object = struct { const debug_len_type = try o.builder.debugMemberType( try o.builder.metadataString("len"), - .none, // File + null, // File debug_fwd_ref, 0, // Line try o.lowerDebugType(pt, len_ty), @@ -1984,10 +1986,10 @@ pub const Object = struct { const debug_slice_type = try o.builder.debugStructType( try o.builder.metadataString(name), - .none, // File - o.debug_compile_unit, // Scope + null, // File + o.debug_compile_unit.unwrap().?, // Scope line, - .none, // Underlying type + null, // Underlying type ty.abiSize(zcu) * 8, (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.metadataTuple(&.{ @@ -1996,10 +1998,10 @@ pub const Object = struct { }), ); - o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_slice_type); + o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_slice_type); // Set to real type now that it has been lowered fully - const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable; map_ptr.* = debug_slice_type; return debug_slice_type; @@ -2012,8 +2014,8 @@ pub const Object = struct { const debug_ptr_type = try o.builder.debugPointerType( try o.builder.metadataString(name), - .none, // File - .none, // Scope + null, // File + null, // Scope 0, // Line debug_elem_ty, target.ptrBitWidth(), @@ -2021,10 +2023,10 @@ pub const Object = struct { 0, // Offset ); - o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_ptr_type); + o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_ptr_type); // Set to real type now that it has been lowered fully - const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable; map_ptr.* = debug_ptr_type; return debug_ptr_type; @@ -2035,7 +2037,7 @@ pub const Object = struct { try o.builder.metadataString("anyopaque"), 0, ); - try o.debug_type_map.put(gpa, ty, debug_opaque_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_opaque_type); return debug_opaque_type; } @@ -2053,19 +2055,19 @@ pub const Object = struct { file, scope, ty.typeDeclSrcLine(zcu).? + 1, // Line - .none, // Underlying type + null, // Underlying type 0, // Size 0, // Align - .none, // Fields + null, // Fields ); - try o.debug_type_map.put(gpa, ty, debug_opaque_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_opaque_type); return debug_opaque_type; }, .array => { const debug_array_type = try o.builder.debugArrayType( - .none, // Name - .none, // File - .none, // Scope + null, // Name + null, // File + null, // Scope 0, // Line try o.lowerDebugType(pt, ty.childType(zcu)), ty.abiSize(zcu) * 8, @@ -2077,7 +2079,7 @@ pub const Object = struct { ), }), ); - try o.debug_type_map.put(gpa, ty, debug_array_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_array_type); return debug_array_type; }, .vector => { @@ -2106,9 +2108,9 @@ pub const Object = struct { }; const debug_vector_type = try o.builder.debugVectorType( - .none, // Name - .none, // File - .none, // Scope + null, // Name + null, // File + null, // Scope 0, // Line debug_elem_type, ty.abiSize(zcu) * 8, @@ -2121,7 +2123,7 @@ pub const Object = struct { }), ); - try o.debug_type_map.put(gpa, ty, debug_vector_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_vector_type); return debug_vector_type; }, .optional => { @@ -2133,22 +2135,22 @@ pub const Object = struct { try o.builder.metadataString(name), 8, ); - try o.debug_type_map.put(gpa, ty, debug_bool_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_bool_type); return debug_bool_type; } const debug_fwd_ref = try o.builder.debugForwardReference(); // Set as forward reference while the type is lowered in case it references itself - try o.debug_type_map.put(gpa, ty, debug_fwd_ref); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_fwd_ref); if (ty.optionalReprIsPayload(zcu)) { const debug_optional_type = try o.lowerDebugType(pt, child_ty); - o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type); + o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_optional_type); // Set to real type now that it has been lowered fully - const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable; map_ptr.* = debug_optional_type; return debug_optional_type; @@ -2163,7 +2165,7 @@ pub const Object = struct { const debug_data_type = try o.builder.debugMemberType( try o.builder.metadataString("data"), - .none, // File + null, // File debug_fwd_ref, 0, // Line try o.lowerDebugType(pt, child_ty), @@ -2174,7 +2176,7 @@ pub const Object = struct { const debug_some_type = try o.builder.debugMemberType( try o.builder.metadataString("some"), - .none, + null, debug_fwd_ref, 0, try o.lowerDebugType(pt, non_null_ty), @@ -2185,10 +2187,10 @@ pub const Object = struct { const debug_optional_type = try o.builder.debugStructType( try o.builder.metadataString(name), - .none, // File - o.debug_compile_unit, // Scope + null, // File + o.debug_compile_unit.unwrap().?, // Scope 0, // Line - .none, // Underlying type + null, // Underlying type ty.abiSize(zcu) * 8, (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.metadataTuple(&.{ @@ -2197,10 +2199,10 @@ pub const Object = struct { }), ); - o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type); + o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_optional_type); // Set to real type now that it has been lowered fully - const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable; map_ptr.* = debug_optional_type; return debug_optional_type; @@ -2210,7 +2212,7 @@ pub const Object = struct { if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { // TODO: Maybe remove? const debug_error_union_type = try o.lowerDebugType(pt, Type.anyerror); - try o.debug_type_map.put(gpa, ty, debug_error_union_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_error_union_type); return debug_error_union_type; } @@ -2243,7 +2245,7 @@ pub const Object = struct { var fields: [2]Builder.Metadata = undefined; fields[error_index] = try o.builder.debugMemberType( try o.builder.metadataString("tag"), - .none, // File + null, // File debug_fwd_ref, 0, // Line try o.lowerDebugType(pt, Type.anyerror), @@ -2253,7 +2255,7 @@ pub const Object = struct { ); fields[payload_index] = try o.builder.debugMemberType( try o.builder.metadataString("value"), - .none, // File + null, // File debug_fwd_ref, 0, // Line try o.lowerDebugType(pt, payload_ty), @@ -2264,18 +2266,18 @@ pub const Object = struct { const debug_error_union_type = try o.builder.debugStructType( try o.builder.metadataString(name), - .none, // File - o.debug_compile_unit, // Sope + null, // File + o.debug_compile_unit.unwrap().?, // Sope 0, // Line - .none, // Underlying type + null, // Underlying type ty.abiSize(zcu) * 8, (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.metadataTuple(&fields), ); - o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_error_union_type); + o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_error_union_type); - try o.debug_type_map.put(gpa, ty, debug_error_union_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_error_union_type); return debug_error_union_type; }, .error_set => { @@ -2283,7 +2285,7 @@ pub const Object = struct { try o.builder.metadataString("anyerror"), 16, ); - try o.debug_type_map.put(gpa, ty, debug_error_set); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_error_set); return debug_error_set; }, .@"struct" => { @@ -2299,7 +2301,7 @@ pub const Object = struct { .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(zcu) * 8), .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(zcu) * 8), }; - try o.debug_type_map.put(gpa, ty, debug_int_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_int_type); return debug_int_type; } } @@ -2329,7 +2331,7 @@ pub const Object = struct { fields.appendAssumeCapacity(try o.builder.debugMemberType( try o.builder.metadataString(field_name), - .none, // File + null, // File debug_fwd_ref, 0, try o.lowerDebugType(pt, Type.fromInterned(field_ty)), @@ -2341,18 +2343,18 @@ pub const Object = struct { const debug_struct_type = try o.builder.debugStructType( try o.builder.metadataString(name), - .none, // File - o.debug_compile_unit, // Scope + null, // File + o.debug_compile_unit.unwrap().?, // Scope 0, // Line - .none, // Underlying type + null, // Underlying type ty.abiSize(zcu) * 8, (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.metadataTuple(fields.items), ); - o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type); + o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_struct_type); - try o.debug_type_map.put(gpa, ty, debug_struct_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_struct_type); return debug_struct_type; }, .struct_type => { @@ -2365,7 +2367,7 @@ pub const Object = struct { // rather than changing the frontend to unnecessarily resolve the // struct field types. const debug_struct_type = try o.makeEmptyNamespaceDebugType(pt, ty); - try o.debug_type_map.put(gpa, ty, debug_struct_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_struct_type); return debug_struct_type; } }, @@ -2374,7 +2376,7 @@ pub const Object = struct { if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { const debug_struct_type = try o.makeEmptyNamespaceDebugType(pt, ty); - try o.debug_type_map.put(gpa, ty, debug_struct_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_struct_type); return debug_struct_type; } @@ -2388,7 +2390,7 @@ pub const Object = struct { const debug_fwd_ref = try o.builder.debugForwardReference(); // Set as forward reference while the type is lowered in case it references itself - try o.debug_type_map.put(gpa, ty, debug_fwd_ref); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_fwd_ref); comptime assert(struct_layout_version == 2); var it = struct_type.iterateRuntimeOrder(ip); @@ -2402,7 +2404,7 @@ pub const Object = struct { try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); fields.appendAssumeCapacity(try o.builder.debugMemberType( try o.builder.metadataString(field_name.toSlice(ip)), - .none, // File + null, // File debug_fwd_ref, 0, // Line try o.lowerDebugType(pt, field_ty), @@ -2414,19 +2416,19 @@ pub const Object = struct { const debug_struct_type = try o.builder.debugStructType( try o.builder.metadataString(name), - .none, // File - o.debug_compile_unit, // Scope + null, // File + o.debug_compile_unit.unwrap().?, // Scope 0, // Line - .none, // Underlying type + null, // Underlying type ty.abiSize(zcu) * 8, (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.metadataTuple(fields.items), ); - o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type); + o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_struct_type); // Set to real type now that it has been lowered fully - const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable; map_ptr.* = debug_struct_type; return debug_struct_type; @@ -2441,7 +2443,7 @@ pub const Object = struct { !union_type.haveLayout(ip)) { const debug_union_type = try o.makeEmptyNamespaceDebugType(pt, ty); - try o.debug_type_map.put(gpa, ty, debug_union_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_union_type); return debug_union_type; } @@ -2450,15 +2452,15 @@ pub const Object = struct { const debug_fwd_ref = try o.builder.debugForwardReference(); // Set as forward reference while the type is lowered in case it references itself - try o.debug_type_map.put(gpa, ty, debug_fwd_ref); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_fwd_ref); if (layout.payload_size == 0) { const debug_union_type = try o.builder.debugStructType( try o.builder.metadataString(name), - .none, // File - o.debug_compile_unit, // Scope + null, // File + o.debug_compile_unit.unwrap().?, // Scope 0, // Line - .none, // Underlying type + null, // Underlying type ty.abiSize(zcu) * 8, (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.metadataTuple( @@ -2467,7 +2469,7 @@ pub const Object = struct { ); // Set to real type now that it has been lowered fully - const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable; map_ptr.* = debug_union_type; return debug_union_type; @@ -2498,7 +2500,7 @@ pub const Object = struct { const field_name = tag_type.names.get(ip)[field_index]; fields.appendAssumeCapacity(try o.builder.debugMemberType( try o.builder.metadataString(field_name.toSlice(ip)), - .none, // File + null, // File debug_union_fwd_ref, 0, // Line try o.lowerDebugType(pt, Type.fromInterned(field_ty)), @@ -2517,20 +2519,20 @@ pub const Object = struct { const debug_union_type = try o.builder.debugUnionType( try o.builder.metadataString(union_name), - .none, // File - o.debug_compile_unit, // Scope + null, // File + o.debug_compile_unit.unwrap().?, // Scope 0, // Line - .none, // Underlying type + null, // Underlying type layout.payload_size * 8, (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.metadataTuple(fields.items), ); - o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type); + o.builder.resolveDebugForwardReference(debug_union_fwd_ref, debug_union_type); if (layout.tag_size == 0) { // Set to real type now that it has been lowered fully - const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable; map_ptr.* = debug_union_type; return debug_union_type; @@ -2548,7 +2550,7 @@ pub const Object = struct { const debug_tag_type = try o.builder.debugMemberType( try o.builder.metadataString("tag"), - .none, // File + null, // File debug_fwd_ref, 0, // Line try o.lowerDebugType(pt, Type.fromInterned(union_type.enum_tag_ty)), @@ -2559,7 +2561,7 @@ pub const Object = struct { const debug_payload_type = try o.builder.debugMemberType( try o.builder.metadataString("payload"), - .none, // File + null, // File debug_fwd_ref, 0, // Line debug_union_type, @@ -2576,19 +2578,19 @@ pub const Object = struct { const debug_tagged_union_type = try o.builder.debugStructType( try o.builder.metadataString(name), - .none, // File - o.debug_compile_unit, // Scope + null, // File + o.debug_compile_unit.unwrap().?, // Scope 0, // Line - .none, // Underlying type + null, // Underlying type ty.abiSize(zcu) * 8, (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.metadataTuple(&full_fields), ); - o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_tagged_union_type); + o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_tagged_union_type); // Set to real type now that it has been lowered fully - const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable; + const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable; map_ptr.* = debug_tagged_union_type; return debug_tagged_union_type; @@ -2636,7 +2638,7 @@ pub const Object = struct { try o.builder.metadataTuple(debug_param_types.items), ); - try o.debug_type_map.put(gpa, ty, debug_function_type); + try o.debug_type_map.put(gpa, ty.toIntern(), debug_function_type); return debug_function_type; }, .comptime_int => unreachable, @@ -2676,10 +2678,10 @@ pub const Object = struct { file, scope, ty.typeDeclSrcLine(zcu).? + 1, - .none, + null, 0, 0, - .none, + null, ); } @@ -4687,7 +4689,7 @@ pub const FuncGen = struct { file: Builder.Metadata, scope: Builder.Metadata, - inlined: Builder.DebugLocation = .no_location, + inlined_at: Builder.Metadata.Optional = .none, base_line: u32, prev_dbg_line: c_uint, @@ -5156,16 +5158,18 @@ pub const FuncGen = struct { ) Error!void { if (self.wip.strip) return self.genBody(body, coverage_point); + const old_debug_location = self.wip.debug_location; const old_file = self.file; - const old_inlined = self.inlined; + const old_inlined_at = self.inlined_at; const old_base_line = self.base_line; - const old_scope = self.scope; defer if (maybe_inline_func) |_| { - self.wip.debug_location = self.inlined; + self.wip.debug_location = old_debug_location; self.file = old_file; - self.inlined = old_inlined; + self.inlined_at = old_inlined_at; self.base_line = old_base_line; }; + + const old_scope = self.scope; defer self.scope = old_scope; if (maybe_inline_func) |inline_func| { @@ -5181,8 +5185,9 @@ pub const FuncGen = struct { self.file = try o.getDebugFile(pt, file_scope); - const line_number = zcu.navSrcLine(func.owner_nav) + 1; - self.inlined = self.wip.debug_location; + self.base_line = zcu.navSrcLine(func.owner_nav); + const line_number = self.base_line + 1; + self.inlined_at = try self.wip.debug_location.toMetadata(&o.builder); const fn_ty = try pt.funcType(.{ .param_types = &.{}, @@ -5201,23 +5206,11 @@ pub const FuncGen = struct { .sp_flags = .{ .Optimized = mod.optimize_mode != .Debug, .Definition = true, - // TODO: we can't know this at this point, since the function could be exported later! - .LocalToUnit = true, + .LocalToUnit = true, // inline functions cannot be exported }, }, - o.debug_compile_unit, + o.debug_compile_unit.unwrap().?, ); - - self.base_line = zcu.navSrcLine(func.owner_nav); - const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder); - self.wip.debug_location = .{ - .location = .{ - .line = line_number, - .column = 0, - .scope = self.scope, - .inlined_at = inlined_at_location, - }, - }; } self.scope = try self.ng.object.builder.debugLexicalBlock( @@ -5226,15 +5219,12 @@ pub const FuncGen = struct { self.prev_dbg_line, self.prev_dbg_column, ); - - switch (self.wip.debug_location) { - .location => |*l| l.scope = self.scope, - .no_location => {}, - } - defer switch (self.wip.debug_location) { - .location => |*l| l.scope = old_scope, - .no_location => {}, - }; + self.wip.debug_location = .{ .location = .{ + .line = self.prev_dbg_line, + .column = self.prev_dbg_column, + .scope = self.scope.toOptional(), + .inlined_at = self.inlined_at, + } }; try self.genBody(body, coverage_point); } @@ -6516,8 +6506,13 @@ pub const FuncGen = struct { break :llvm_cases_len len; }; - var weights = try self.gpa.alloc(Builder.Metadata, llvm_cases_len + 1); + var weights = try self.gpa.alloc(Builder.Metadata, 1 + llvm_cases_len + 1); defer self.gpa.free(weights); + var weight_idx: usize = 0; + + const branch_weights_str = try o.builder.metadataString("branch_weights"); + weights[weight_idx] = branch_weights_str.toMetadata(); + weight_idx += 1; const else_weight: u32 = switch (switch_br.getElseHint()) { .unpredictable => unreachable, @@ -6525,9 +6520,9 @@ pub const FuncGen = struct { .likely => 2000, .unlikely => 1, }; - weights[0] = try o.builder.metadataConstant(try o.builder.intConst(.i32, else_weight)); + weights[weight_idx] = try o.builder.metadataConstant(try o.builder.intConst(.i32, else_weight)); + weight_idx += 1; - var weight_idx: usize = 1; var it = switch_br.iterateCases(); while (it.next()) |case| { const weight_val: u32 = switch (switch_br.getHint(case.idx)) { @@ -6542,10 +6537,7 @@ pub const FuncGen = struct { } assert(weight_idx == weights.len); - - const branch_weights_str = try o.builder.metadataString("branch_weights"); - const tuple = try o.builder.strTuple(branch_weights_str, weights); - break :weights @enumFromInt(@intFromEnum(tuple)); + break :weights .fromMetadata(try o.builder.metadataTuple(weights)); }; const dispatch_info: SwitchDispatchInfo = .{ @@ -7102,14 +7094,12 @@ pub const FuncGen = struct { self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1); self.prev_dbg_column = @intCast(dbg_stmt.column + 1); - self.wip.debug_location = .{ - .location = .{ - .line = self.prev_dbg_line, - .column = self.prev_dbg_column, - .scope = self.scope, - .inlined_at = try self.inlined.toMetadata(self.wip.builder), - }, - }; + self.wip.debug_location = .{ .location = .{ + .line = self.prev_dbg_line, + .column = self.prev_dbg_column, + .scope = self.scope.toOptional(), + .inlined_at = self.inlined_at, + } }; return .none; } @@ -7167,9 +7157,10 @@ pub const FuncGen = struct { const operand = try self.resolveInst(pl_op.operand); const operand_ty = self.typeOf(pl_op.operand); const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); - + const name_slice = name.toSlice(self.air); + const metadata_name = if (name_slice.len > 0) try o.builder.metadataString(name_slice) else null; const debug_local_var = if (is_arg) try o.builder.debugParameter( - try o.builder.metadataString(name.toSlice(self.air)), + metadata_name, self.file, self.scope, self.prev_dbg_line, @@ -7179,7 +7170,7 @@ pub const FuncGen = struct { break :arg_no self.arg_inline_index; }, ) else try o.builder.debugLocalVar( - try o.builder.metadataString(name.toSlice(self.air)), + metadata_name, self.file, self.scope, self.prev_dbg_line, @@ -9547,7 +9538,7 @@ pub const FuncGen = struct { const lbrace_col = func.lbrace_column + 1; const debug_parameter = try o.builder.debugParameter( - try o.builder.metadataString(name), + if (name.len > 0) try o.builder.metadataString(name) else null, self.file, self.scope, lbrace_line, @@ -9556,14 +9547,12 @@ pub const FuncGen = struct { ); const old_location = self.wip.debug_location; - self.wip.debug_location = .{ - .location = .{ - .line = lbrace_line, - .column = lbrace_col, - .scope = self.scope, - .inlined_at = .none, - }, - }; + self.wip.debug_location = .{ .location = .{ + .line = lbrace_line, + .column = lbrace_col, + .scope = self.scope.toOptional(), + .inlined_at = .none, + } }; if (isByRef(inst_ty, zcu)) { _ = try self.wip.callIntrinsic( @@ -12614,11 +12603,7 @@ fn iterateParamTypes(object: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key }; } -fn ccAbiPromoteInt( - cc: std.builtin.CallingConvention, - zcu: *Zcu, - ty: Type, -) ?std.builtin.Signedness { +fn ccAbiPromoteInt(cc: std.builtin.CallingConvention, zcu: *Zcu, ty: Type) ?std.builtin.Signedness { const target = zcu.getTarget(); switch (cc) { .auto, .@"inline", .async => return null,