From 72e00805a61719174b1668d5ce3cbef8338e4690 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 19 Aug 2024 16:29:45 -0700 Subject: [PATCH] llvm.Builder: add support for more instruction metadata mlugg: this is cherry-picked from Andrew's nosanitize branch (with Jacob's fixes squashed in) since I needed this for `unpredictable` and `prof` metadata. The nosanitize-specific changes are reverted in the next commit. Co-authored-by: Jacob Young --- src/codegen/llvm/Builder.zig | 155 +++++++++++++------------- src/codegen/llvm/ir.zig | 205 ++++++++++++++++++++++++++++++----- 2 files changed, 254 insertions(+), 106 deletions(-) diff --git a/src/codegen/llvm/Builder.zig b/src/codegen/llvm/Builder.zig index 90da3bdd7a92..f3acbd522496 100644 --- a/src/codegen/llvm/Builder.zig +++ b/src/codegen/llvm/Builder.zig @@ -7697,6 +7697,7 @@ pub const MetadataString = enum(u32) { pub const Metadata = enum(u32) { none = 0, + empty_tuple = 1, _, const first_forward_reference = 1 << 29; @@ -8355,7 +8356,7 @@ pub const Metadata = enum(u32) { }; pub fn init(options: Options) Allocator.Error!Builder { - var self = Builder{ + var self: Builder = .{ .gpa = options.allocator, .strip = options.strip, @@ -8458,6 +8459,7 @@ pub fn init(options: Options) Allocator.Error!Builder { try self.metadata_string_indices.append(self.gpa, 0); assert(try self.metadataString("") == .none); + assert(try self.debugTuple(&.{}) == .empty_tuple); return self; } @@ -13759,7 +13761,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co const MetadataKindBlock = ir.MetadataKindBlock; var metadata_kind_block = try module_block.enterSubBlock(MetadataKindBlock, true); - inline for (@typeInfo(ir.MetadataKind).Enum.fields) |field| { + inline for (@typeInfo(ir.FixedMetadataKind).Enum.fields) |field| { try metadata_kind_block.writeAbbrev(MetadataKindBlock.Kind{ .id = field.value, .name = field.name, @@ -14046,7 +14048,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co else -%val << 1 | 1); } - try metadata_block.writeUnabbrev(MetadataBlock.Enumerator.id, record.items); + try metadata_block.writeUnabbrev(@intFromEnum(MetadataBlock.Enumerator.id), record.items); continue; }; try metadata_block.writeAbbrevAdapted(MetadataBlock.Enumerator{ @@ -14177,7 +14179,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co try metadata_block.writeAbbrev(MetadataBlock.GlobalDeclAttachment{ .value = @enumFromInt(constant_adapter.getConstantIndex(global.toConst())), - .kind = ir.MetadataKind.dbg, + .kind = .dbg, .metadata = @enumFromInt(metadata_adapter.getMetadataIndex(global_ptr.dbg) - 1), }); } @@ -14220,20 +14222,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co constant_adapter: ConstantAdapter, metadata_adapter: MetadataAdapter, func: *const Function, - instruction_index: u32 = 0, - - pub fn init( - const_adapter: ConstantAdapter, - meta_adapter: MetadataAdapter, - func: *const Function, - ) @This() { - return .{ - .constant_adapter = const_adapter, - .metadata_adapter = meta_adapter, - .func = func, - .instruction_index = 0, - }; - } + instruction_index: Function.Instruction.Index, pub fn get(adapter: @This(), value: anytype, comptime field_name: []const u8) @TypeOf(value) { _ = field_name; @@ -14282,19 +14271,12 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co } pub fn offset(adapter: @This()) u32 { - return @as( - Function.Instruction.Index, - @enumFromInt(adapter.instruction_index), - ).valueIndex(adapter.func) + adapter.firstInstr(); + return adapter.instruction_index.valueIndex(adapter.func) + adapter.firstInstr(); } fn firstInstr(adapter: @This()) u32 { return adapter.constant_adapter.numConstants(); } - - pub fn next(adapter: *@This()) void { - adapter.instruction_index += 1; - } }; for (self.functions.items, 0..) |func, func_index| { @@ -14307,7 +14289,12 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co try function_block.writeAbbrev(FunctionBlock.DeclareBlocks{ .num_blocks = func.blocks.len }); - var adapter = FunctionAdapter.init(constant_adapter, metadata_adapter, &func); + var adapter: FunctionAdapter = .{ + .constant_adapter = constant_adapter, + .metadata_adapter = metadata_adapter, + .func = &func, + .instruction_index = @enumFromInt(0), + }; // Emit function level metadata block if (!func.strip and func.debug_values.len > 0) { @@ -14330,21 +14317,23 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co var has_location = false; var block_incoming_len: u32 = undefined; - for (0..func.instructions.len) |instr_index| { - const tag = tags[instr_index]; - + for (tags, datas, 0..) |tag, data, instr_index| { + adapter.instruction_index = @enumFromInt(instr_index); record.clearRetainingCapacity(); switch (tag) { - .block => block_incoming_len = datas[instr_index], - .arg => {}, + .arg => continue, + .block => { + block_incoming_len = data; + continue; + }, .@"unreachable" => try function_block.writeAbbrev(FunctionBlock.Unreachable{}), .call, .@"musttail call", .@"notail call", .@"tail call", => |kind| { - var extra = func.extraDataTrail(Function.Instruction.Call, datas[instr_index]); + var extra = func.extraDataTrail(Function.Instruction.Call, data); const call_conv = extra.data.info.call_conv; const args = extra.trail.next(extra.data.args_len, Value, &func); @@ -14367,7 +14356,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .@"notail call fast", .@"tail call fast", => |kind| { - var extra = func.extraDataTrail(Function.Instruction.Call, datas[instr_index]); + var extra = func.extraDataTrail(Function.Instruction.Call, data); const call_conv = extra.data.info.call_conv; const args = extra.trail.next(extra.data.args_len, Value, &func); @@ -14405,7 +14394,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .srem, .ashr, => |kind| { - const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Binary, data); try function_block.writeAbbrev(FunctionBlock.Binary{ .opcode = kind.toBinaryOpcode(), .lhs = adapter.getOffsetValueIndex(extra.lhs), @@ -14417,7 +14406,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .@"lshr exact", .@"ashr exact", => |kind| { - const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Binary, data); try function_block.writeAbbrev(FunctionBlock.BinaryExact{ .opcode = kind.toBinaryOpcode(), .lhs = adapter.getOffsetValueIndex(extra.lhs), @@ -14437,7 +14426,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .@"shl nuw", .@"shl nuw nsw", => |kind| { - const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Binary, data); try function_block.writeAbbrev(FunctionBlock.BinaryNoWrap{ .opcode = kind.toBinaryOpcode(), .lhs = adapter.getOffsetValueIndex(extra.lhs), @@ -14468,7 +14457,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .@"frem fast", .@"fsub fast", => |kind| { - const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Binary, data); try function_block.writeAbbrev(FunctionBlock.BinaryFast{ .opcode = kind.toBinaryOpcode(), .lhs = adapter.getOffsetValueIndex(extra.lhs), @@ -14479,7 +14468,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .alloca, .@"alloca inalloca", => |kind| { - const extra = func.extraData(Function.Instruction.Alloca, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Alloca, data); const alignment = extra.info.alignment.toLlvm(); try function_block.writeAbbrev(FunctionBlock.Alloca{ .inst_type = extra.type, @@ -14508,7 +14497,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .sext, .zext, => |kind| { - const extra = func.extraData(Function.Instruction.Cast, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Cast, data); try function_block.writeAbbrev(FunctionBlock.Cast{ .val = adapter.getOffsetValueIndex(extra.val), .type_index = extra.type, @@ -14542,7 +14531,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .@"icmp ule", .@"icmp ult", => |kind| { - const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Binary, data); try function_block.writeAbbrev(FunctionBlock.Cmp{ .lhs = adapter.getOffsetValueIndex(extra.lhs), .rhs = adapter.getOffsetValueIndex(extra.rhs), @@ -14566,7 +14555,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .@"fcmp fast une", .@"fcmp fast uno", => |kind| { - const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Binary, data); try function_block.writeAbbrev(FunctionBlock.CmpFast{ .lhs = adapter.getOffsetValueIndex(extra.lhs), .rhs = adapter.getOffsetValueIndex(extra.rhs), @@ -14575,14 +14564,14 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .fneg => try function_block.writeAbbrev(FunctionBlock.FNeg{ - .val = adapter.getOffsetValueIndex(@enumFromInt(datas[instr_index])), + .val = adapter.getOffsetValueIndex(@enumFromInt(data)), }), .@"fneg fast" => try function_block.writeAbbrev(FunctionBlock.FNegFast{ - .val = adapter.getOffsetValueIndex(@enumFromInt(datas[instr_index])), + .val = adapter.getOffsetValueIndex(@enumFromInt(data)), .fast_math = FastMath.fast, }), .extractvalue => { - var extra = func.extraDataTrail(Function.Instruction.ExtractValue, datas[instr_index]); + var extra = func.extraDataTrail(Function.Instruction.ExtractValue, data); const indices = extra.trail.next(extra.data.indices_len, u32, &func); try function_block.writeAbbrev(FunctionBlock.ExtractValue{ .val = adapter.getOffsetValueIndex(extra.data.val), @@ -14590,7 +14579,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .insertvalue => { - var extra = func.extraDataTrail(Function.Instruction.InsertValue, datas[instr_index]); + var extra = func.extraDataTrail(Function.Instruction.InsertValue, data); const indices = extra.trail.next(extra.data.indices_len, u32, &func); try function_block.writeAbbrev(FunctionBlock.InsertValue{ .val = adapter.getOffsetValueIndex(extra.data.val), @@ -14599,14 +14588,14 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .extractelement => { - const extra = func.extraData(Function.Instruction.ExtractElement, datas[instr_index]); + const extra = func.extraData(Function.Instruction.ExtractElement, data); try function_block.writeAbbrev(FunctionBlock.ExtractElement{ .val = adapter.getOffsetValueIndex(extra.val), .index = adapter.getOffsetValueIndex(extra.index), }); }, .insertelement => { - const extra = func.extraData(Function.Instruction.InsertElement, datas[instr_index]); + const extra = func.extraData(Function.Instruction.InsertElement, data); try function_block.writeAbbrev(FunctionBlock.InsertElement{ .val = adapter.getOffsetValueIndex(extra.val), .elem = adapter.getOffsetValueIndex(extra.elem), @@ -14614,7 +14603,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .select => { - const extra = func.extraData(Function.Instruction.Select, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Select, data); try function_block.writeAbbrev(FunctionBlock.Select{ .lhs = adapter.getOffsetValueIndex(extra.lhs), .rhs = adapter.getOffsetValueIndex(extra.rhs), @@ -14622,7 +14611,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .@"select fast" => { - const extra = func.extraData(Function.Instruction.Select, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Select, data); try function_block.writeAbbrev(FunctionBlock.SelectFast{ .lhs = adapter.getOffsetValueIndex(extra.lhs), .rhs = adapter.getOffsetValueIndex(extra.rhs), @@ -14631,7 +14620,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .shufflevector => { - const extra = func.extraData(Function.Instruction.ShuffleVector, datas[instr_index]); + const extra = func.extraData(Function.Instruction.ShuffleVector, data); try function_block.writeAbbrev(FunctionBlock.ShuffleVector{ .lhs = adapter.getOffsetValueIndex(extra.lhs), .rhs = adapter.getOffsetValueIndex(extra.rhs), @@ -14641,7 +14630,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .getelementptr, .@"getelementptr inbounds", => |kind| { - var extra = func.extraDataTrail(Function.Instruction.GetElementPtr, datas[instr_index]); + var extra = func.extraDataTrail(Function.Instruction.GetElementPtr, data); const indices = extra.trail.next(extra.data.indices_len, Value, &func); try function_block.writeAbbrevAdapted( FunctionBlock.GetElementPtr{ @@ -14654,7 +14643,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co ); }, .load => { - const extra = func.extraData(Function.Instruction.Load, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Load, data); try function_block.writeAbbrev(FunctionBlock.Load{ .ptr = adapter.getOffsetValueIndex(extra.ptr), .ty = extra.type, @@ -14663,7 +14652,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .@"load atomic" => { - const extra = func.extraData(Function.Instruction.Load, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Load, data); try function_block.writeAbbrev(FunctionBlock.LoadAtomic{ .ptr = adapter.getOffsetValueIndex(extra.ptr), .ty = extra.type, @@ -14674,7 +14663,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .store => { - const extra = func.extraData(Function.Instruction.Store, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Store, data); try function_block.writeAbbrev(FunctionBlock.Store{ .ptr = adapter.getOffsetValueIndex(extra.ptr), .val = adapter.getOffsetValueIndex(extra.val), @@ -14683,7 +14672,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .@"store atomic" => { - const extra = func.extraData(Function.Instruction.Store, datas[instr_index]); + const extra = func.extraData(Function.Instruction.Store, data); try function_block.writeAbbrev(FunctionBlock.StoreAtomic{ .ptr = adapter.getOffsetValueIndex(extra.ptr), .val = adapter.getOffsetValueIndex(extra.val), @@ -14695,11 +14684,11 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }, .br => { try function_block.writeAbbrev(FunctionBlock.BrUnconditional{ - .block = datas[instr_index], + .block = data, }); }, .br_cond => { - const extra = func.extraData(Function.Instruction.BrCond, datas[instr_index]); + const extra = func.extraData(Function.Instruction.BrCond, data); try function_block.writeAbbrev(FunctionBlock.BrConditional{ .then_block = @intFromEnum(extra.then), .else_block = @intFromEnum(extra.@"else"), @@ -14707,7 +14696,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .@"switch" => { - var extra = func.extraDataTrail(Function.Instruction.Switch, datas[instr_index]); + var extra = func.extraDataTrail(Function.Instruction.Switch, data); try record.ensureUnusedCapacity(self.gpa, 3 + extra.data.cases_len * 2); @@ -14730,7 +14719,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co try function_block.writeUnabbrev(12, record.items); }, .va_arg => { - const extra = func.extraData(Function.Instruction.VaArg, datas[instr_index]); + const extra = func.extraData(Function.Instruction.VaArg, data); try function_block.writeAbbrev(FunctionBlock.VaArg{ .list_type = extra.list.typeOf(@enumFromInt(func_index), self), .list = adapter.getOffsetValueIndex(extra.list), @@ -14740,7 +14729,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .phi, .@"phi fast", => |kind| { - var extra = func.extraDataTrail(Function.Instruction.Phi, datas[instr_index]); + var extra = func.extraDataTrail(Function.Instruction.Phi, data); const vals = extra.trail.next(block_incoming_len, Value, &func); const blocks = extra.trail.next(block_incoming_len, Function.Block.Index, &func); @@ -14764,11 +14753,11 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co try function_block.writeUnabbrev(16, record.items); }, .ret => try function_block.writeAbbrev(FunctionBlock.Ret{ - .val = adapter.getOffsetValueIndex(@enumFromInt(datas[instr_index])), + .val = adapter.getOffsetValueIndex(@enumFromInt(data)), }), .@"ret void" => try function_block.writeAbbrev(FunctionBlock.RetVoid{}), .atomicrmw => { - const extra = func.extraData(Function.Instruction.AtomicRmw, datas[instr_index]); + const extra = func.extraData(Function.Instruction.AtomicRmw, data); try function_block.writeAbbrev(FunctionBlock.AtomicRmw{ .ptr = adapter.getOffsetValueIndex(extra.ptr), .val = adapter.getOffsetValueIndex(extra.val), @@ -14782,7 +14771,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .cmpxchg, .@"cmpxchg weak", => |kind| { - const extra = func.extraData(Function.Instruction.CmpXchg, datas[instr_index]); + const extra = func.extraData(Function.Instruction.CmpXchg, data); try function_block.writeAbbrev(FunctionBlock.CmpXchg{ .ptr = adapter.getOffsetValueIndex(extra.ptr), @@ -14797,7 +14786,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }); }, .fence => { - const info: MemoryAccessInfo = @bitCast(datas[instr_index]); + const info: MemoryAccessInfo = @bitCast(data); try function_block.writeAbbrev(FunctionBlock.Fence{ .ordering = info.success_ordering, .sync_scope = info.sync_scope, @@ -14806,7 +14795,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co } if (!func.strip) { - if (func.debug_locations.get(@enumFromInt(instr_index))) |debug_location| { + if (func.debug_locations.get(adapter.instruction_index)) |debug_location| { switch (debug_location) { .no_location => has_location = false, .location => |location| { @@ -14823,8 +14812,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co try function_block.writeAbbrev(FunctionBlock.DebugLocAgain{}); } } - - adapter.next(); } // VALUE_SYMTAB @@ -14850,18 +14837,32 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co } // METADATA_ATTACHMENT_BLOCK - if (!func.strip) blk: { - const dbg = func.global.ptrConst(self).dbg; - - if (dbg == .none) break :blk; - + const any_nosanitize = true; + if (!func.strip or any_nosanitize) { const MetadataAttachmentBlock = ir.MetadataAttachmentBlock; var metadata_attach_block = try function_block.enterSubBlock(MetadataAttachmentBlock, false); - try metadata_attach_block.writeAbbrev(MetadataAttachmentBlock.AttachmentSingle{ - .kind = ir.MetadataKind.dbg, - .metadata = @enumFromInt(metadata_adapter.getMetadataIndex(dbg) - 1), - }); + if (!func.strip) blk: { + const dbg = func.global.ptrConst(self).dbg; + if (dbg == .none) break :blk; + try metadata_attach_block.writeAbbrev(MetadataAttachmentBlock.AttachmentGlobalSingle{ + .kind = .dbg, + .metadata = @enumFromInt(metadata_adapter.getMetadataIndex(dbg) - 1), + }); + } + + var instr_index: u32 = 0; + for (func.instructions.items(.tag)) |instr_tag| switch (instr_tag) { + .arg, .block => {}, + else => { + try metadata_attach_block.writeAbbrev(MetadataAttachmentBlock.AttachmentInstructionSingle{ + .inst = instr_index, + .kind = .nosanitize, + .metadata = @enumFromInt(metadata_adapter.getMetadataIndex(.empty_tuple) - 1), + }); + instr_index += 1; + }, + }; try metadata_attach_block.end(); } diff --git a/src/codegen/llvm/ir.zig b/src/codegen/llvm/ir.zig index 6a7c6c6857db..3b8cc14fcfdb 100644 --- a/src/codegen/llvm/ir.zig +++ b/src/codegen/llvm/ir.zig @@ -20,8 +20,142 @@ const ColumnAbbrev = AbbrevOp{ .vbr = 8 }; const BlockAbbrev = AbbrevOp{ .vbr = 6 }; -pub const MetadataKind = enum(u1) { +/// 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) { dbg = 0, + //tbaa = 1, + //prof = 2, + //fpmath = 3, + //range = 4, + //@"tbaa.struct" = 5, + //@"invariant.load" = 6, + //@"alias.scope" = 7, + //@"noalias" = 8, + //nontemporal = 9, + //@"llvm.mem.parallel_loop_access" = 10, + //nonnull = 11, + //dereferenceable = 12, + //dereferenceable_or_null = 13, + //@"make.implicit" = 14, + //unpredictable = 15, + //@"invariant.group" = 16, + //@"align" = 17, + //@"llvm.loop" = 18, + //type = 19, + //section_prefix = 20, + //absolute_symbol = 21, + //associated = 22, + //callees = 23, + //irr_loop = 24, + //@"llvm.access.group" = 25, + //callback = 26, + //@"llvm.preserve.access.index" = 27, + //vcall_visibility = 28, + //noundef = 29, + //annotation = 30, + nosanitize = 31, + //func_sanitize = 32, + //exclude = 33, + //memprof = 34, + //callsite = 35, + //kcfi_type = 36, + //pcsections = 37, + //DIAssignID = 38, + //@"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 Identification = struct { @@ -622,16 +756,29 @@ pub const MetadataAttachmentBlock = struct { pub const id = 16; pub const abbrevs = [_]type{ - AttachmentSingle, + AttachmentGlobalSingle, + AttachmentInstructionSingle, }; - pub const AttachmentSingle = struct { + pub const AttachmentGlobalSingle = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 11 }, + .{ .literal = @intFromEnum(MetadataCode.ATTACHMENT) }, .{ .fixed = 1 }, MetadataAbbrev, }; - kind: MetadataKind, + 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, }; }; @@ -666,7 +813,7 @@ pub const MetadataBlock = struct { pub const Strings = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 35 }, + .{ .literal = @intFromEnum(MetadataCode.STRINGS) }, .{ .vbr = 6 }, .{ .vbr = 6 }, .blob, @@ -678,7 +825,7 @@ pub const MetadataBlock = struct { pub const File = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 16 }, + .{ .literal = @intFromEnum(MetadataCode.FILE) }, .{ .literal = 0 }, // is distinct MetadataAbbrev, // filename MetadataAbbrev, // directory @@ -692,7 +839,7 @@ pub const MetadataBlock = struct { pub const CompileUnit = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 20 }, + .{ .literal = @intFromEnum(MetadataCode.COMPILE_UNIT) }, .{ .literal = 1 }, // is distinct .{ .literal = std.dwarf.LANG.C99 }, // source language MetadataAbbrev, // file @@ -726,7 +873,7 @@ pub const MetadataBlock = struct { pub const Subprogram = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 21 }, + .{ .literal = @intFromEnum(MetadataCode.SUBPROGRAM) }, .{ .literal = 0b111 }, // is distinct | has sp flags | has flags MetadataAbbrev, // scope MetadataAbbrev, // name @@ -763,7 +910,7 @@ pub const MetadataBlock = struct { pub const LexicalBlock = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 22 }, + .{ .literal = @intFromEnum(MetadataCode.LEXICAL_BLOCK) }, .{ .literal = 0 }, // is distinct MetadataAbbrev, // scope MetadataAbbrev, // file @@ -779,7 +926,7 @@ pub const MetadataBlock = struct { pub const Location = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 7 }, + .{ .literal = @intFromEnum(MetadataCode.LOCATION) }, .{ .literal = 0 }, // is distinct LineAbbrev, // line ColumnAbbrev, // column @@ -796,7 +943,7 @@ pub const MetadataBlock = struct { pub const BasicType = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 15 }, + .{ .literal = @intFromEnum(MetadataCode.BASIC_TYPE) }, .{ .literal = 0 }, // is distinct .{ .literal = std.dwarf.TAG.base_type }, // tag MetadataAbbrev, // name @@ -813,7 +960,7 @@ pub const MetadataBlock = struct { pub const CompositeType = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 18 }, + .{ .literal = @intFromEnum(MetadataCode.COMPOSITE_TYPE) }, .{ .literal = 0 | 0x2 }, // is distinct | is not used in old type ref .{ .fixed = 32 }, // tag MetadataAbbrev, // name @@ -852,7 +999,7 @@ pub const MetadataBlock = struct { pub const DerivedType = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 17 }, + .{ .literal = @intFromEnum(MetadataCode.DERIVED_TYPE) }, .{ .literal = 0 }, // is distinct .{ .fixed = 32 }, // tag MetadataAbbrev, // name @@ -880,7 +1027,7 @@ pub const MetadataBlock = struct { pub const SubroutineType = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 19 }, + .{ .literal = @intFromEnum(MetadataCode.SUBROUTINE_TYPE) }, .{ .literal = 0 | 0x2 }, // is distinct | has no old type refs .{ .literal = 0 }, // flags MetadataAbbrev, // types @@ -891,7 +1038,7 @@ pub const MetadataBlock = struct { }; pub const Enumerator = struct { - pub const id = 14; + pub const id: MetadataCode = .ENUMERATOR; pub const Flags = packed struct(u3) { distinct: bool = false, @@ -900,7 +1047,7 @@ pub const MetadataBlock = struct { }; pub const ops = [_]AbbrevOp{ - .{ .literal = Enumerator.id }, + .{ .literal = @intFromEnum(Enumerator.id) }, .{ .fixed = @bitSizeOf(Flags) }, // flags .{ .vbr = 6 }, // bit width MetadataAbbrev, // name @@ -915,7 +1062,7 @@ pub const MetadataBlock = struct { pub const Subrange = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 13 }, + .{ .literal = @intFromEnum(MetadataCode.SUBRANGE) }, .{ .literal = 0b10 }, // is distinct | version MetadataAbbrev, // count MetadataAbbrev, // lower bound @@ -929,7 +1076,7 @@ pub const MetadataBlock = struct { pub const Expression = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 29 }, + .{ .literal = @intFromEnum(MetadataCode.EXPRESSION) }, .{ .literal = 0 | (3 << 1) }, // is distinct | version MetadataArrayAbbrev, // elements }; @@ -939,7 +1086,7 @@ pub const MetadataBlock = struct { pub const Node = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 3 }, + .{ .literal = @intFromEnum(MetadataCode.NODE) }, MetadataArrayAbbrev, // elements }; @@ -948,7 +1095,7 @@ pub const MetadataBlock = struct { pub const LocalVar = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 28 }, + .{ .literal = @intFromEnum(MetadataCode.LOCAL_VAR) }, .{ .literal = 0b10 }, // is distinct | has alignment MetadataAbbrev, // scope MetadataAbbrev, // name @@ -970,7 +1117,7 @@ pub const MetadataBlock = struct { pub const Parameter = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 28 }, + .{ .literal = @intFromEnum(MetadataCode.LOCAL_VAR) }, .{ .literal = 0b10 }, // is distinct | has alignment MetadataAbbrev, // scope MetadataAbbrev, // name @@ -993,7 +1140,7 @@ pub const MetadataBlock = struct { pub const GlobalVar = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 27 }, + .{ .literal = @intFromEnum(MetadataCode.GLOBAL_VAR) }, .{ .literal = 0b101 }, // is distinct | version MetadataAbbrev, // scope MetadataAbbrev, // name @@ -1020,7 +1167,7 @@ pub const MetadataBlock = struct { pub const GlobalVarExpression = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 37 }, + .{ .literal = @intFromEnum(MetadataCode.GLOBAL_VAR_EXPR) }, .{ .literal = 0 }, // is distinct MetadataAbbrev, // variable MetadataAbbrev, // expression @@ -1032,7 +1179,7 @@ pub const MetadataBlock = struct { pub const Constant = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 2 }, + .{ .literal = @intFromEnum(MetadataCode.VALUE) }, MetadataAbbrev, // type MetadataAbbrev, // value }; @@ -1043,7 +1190,7 @@ pub const MetadataBlock = struct { pub const Name = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 4 }, + .{ .literal = @intFromEnum(MetadataCode.NAME) }, .{ .array_fixed = 8 }, // name }; @@ -1052,7 +1199,7 @@ pub const MetadataBlock = struct { pub const NamedNode = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 10 }, + .{ .literal = @intFromEnum(MetadataCode.NAMED_NODE) }, MetadataArrayAbbrev, // elements }; @@ -1061,14 +1208,14 @@ pub const MetadataBlock = struct { pub const GlobalDeclAttachment = struct { pub const ops = [_]AbbrevOp{ - .{ .literal = 36 }, + .{ .literal = @intFromEnum(MetadataCode.GLOBAL_DECL_ATTACHMENT) }, ValueAbbrev, // value id .{ .fixed = 1 }, // kind MetadataAbbrev, // elements }; value: Builder.Constant, - kind: MetadataKind, + kind: FixedMetadataKind, metadata: Builder.Metadata, }; };