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 <jacobly0@users.noreply.github.com>
This commit is contained in:
Andrew Kelley 2024-08-19 16:29:45 -07:00 committed by mlugg
parent f2d7096bb9
commit 72e00805a6
No known key found for this signature in database
GPG Key ID: 3F5B7DCCBF4AF02E
2 changed files with 254 additions and 106 deletions

View File

@ -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();
}

View File

@ -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,
};
};