authorgravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2024-02-21 16:23:15+01:00
committergravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2024-02-21 16:24:59+01:00
log626c3f795990ea32878bcd3f93467d00478c2d69
treedab380e84870293f5ab02289648d8444781ee68d
parentd35080b792ee7ecac14c19918ab07526ad05601d

LLVM Builder: Emit debug info and metadata


1 files changed, 478 insertions(+), 3 deletions(-)

src/codegen/llvm/Builder.zig+478-3
......@@ -14466,19 +14466,449 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1446614466 try constants_block.end();
1446714467 }
1446814468
14469 const MetadataAdapter = struct {
14470 builder: *const Builder,
14471 constant_adapter: ConstantAdapter,
14472
14473 pub fn init(
14474 builder: *const Builder,
14475 const_adapter: ConstantAdapter,
14476 ) @This() {
14477 return .{
14478 .builder = builder,
14479 .constant_adapter = const_adapter,
14480 };
14481 }
14482
14483 pub fn get(adapter: @This(), value: anytype, comptime field_name: []const u8) @TypeOf(value) {
14484 _ = field_name;
14485 const Ty = @TypeOf(value);
14486 return switch (Ty) {
14487 Metadata => @enumFromInt(adapter.getMetadataIndex(value)),
14488 MetadataString => @enumFromInt(adapter.getMetadataStringIndex(value)),
14489 Constant => @enumFromInt(adapter.constant_adapter.getConstantIndex(value)),
14490 else => value,
14491 };
14492 }
14493
14494 pub fn getMetadataIndex(adapter: @This(), metadata: Metadata) u32 {
14495 if (metadata == .none) return 0;
14496 return @intCast(adapter.builder.metadata_strings.count() +
14497 @intFromEnum(metadata.unwrap(adapter.builder)));
14498 }
14499
14500 pub fn getMetadataStringIndex(_: @This(), metadata_string: MetadataString) u32 {
14501 return @intFromEnum(metadata_string) + 1;
14502 }
14503 };
14504
14505 const metadata_adapter = MetadataAdapter.init(self, constant_adapter);
14506
14507 // METADATA_BLOCK
14508 if (!self.strip) {
14509 const MetadataBlock = IR.MetadataBlock;
14510 var metadata_block = try module_block.enterSubBlock(MetadataBlock);
14511
14512 const MetadataBlockWriter = @TypeOf(metadata_block);
14513
14514 // Emit all MetadataStrings
14515 {
14516 const strings_offset, const strings_size = blk: {
14517 var strings_offset: u32 = 0;
14518 var strings_size: u32 = 0;
14519 for (self.metadata_strings.keys()) |metadata_string| {
14520 if (metadata_string.slice(self)) |slice| {
14521 strings_offset += bitcode.bitsVBR(@as(u32, @intCast(slice.len)), 6);
14522 strings_size += @intCast(slice.len * 8);
14523 }
14524 }
14525 break :blk .{
14526 std.mem.alignForward(u32, strings_offset, 32) / 8,
14527 std.mem.alignForward(u32, strings_size, 32) / 8,
14528 };
14529 };
14530
14531 try bitcode.writeBits(
14532 comptime MetadataBlockWriter.abbrevId(MetadataBlock.Strings),
14533 MetadataBlockWriter.abbrev_len,
14534 );
14535
14536 try bitcode.writeVBR(@as(u32, @intCast(self.metadata_strings.count())), 6);
14537 try bitcode.writeVBR(strings_offset, 6);
14538
14539 try bitcode.writeVBR(strings_size + strings_offset, 6);
14540
14541 try bitcode.alignTo32();
14542
14543 for (self.metadata_strings.keys()) |metadata_string| {
14544 if (metadata_string.slice(self)) |slice|
14545 try bitcode.writeVBR(@as(u32, @intCast(slice.len)), 6);
14546 }
14547
14548 try bitcode.alignTo32();
14549
14550 for (self.metadata_strings.keys()) |metadata_string| {
14551 if (metadata_string.slice(self)) |slice| {
14552 for (slice) |c| {
14553 try bitcode.writeBits(c, 8);
14554 }
14555 }
14556 }
14557
14558 try bitcode.alignTo32();
14559 }
14560
14561 for (1..self.metadata_items.len) |metadata_index| {
14562 const tag = self.metadata_items.items(.tag)[metadata_index];
14563 const data = self.metadata_items.items(.data)[metadata_index];
14564 switch (tag) {
14565 .none => unreachable,
14566 .file => {
14567 const extra = self.metadataExtraData(Metadata.File, data);
14568
14569 try metadata_block.writeAbbrevAdapted(MetadataBlock.File{
14570 .name = extra.name,
14571 .path = extra.path,
14572 }, metadata_adapter);
14573 },
14574 .compile_unit, .@"compile_unit optimized" => |kind| {
14575 const is_optimized = kind == .@"compile_unit optimized";
14576 const extra = self.metadataExtraData(Metadata.CompileUnit, data);
14577 try metadata_block.writeAbbrevAdapted(MetadataBlock.CompileUnit{
14578 .file = extra.file,
14579 .producer = extra.producer,
14580 .is_optimized = is_optimized,
14581 .enums = extra.enums,
14582 .globals = extra.globals,
14583 }, metadata_adapter);
14584 },
14585 .subprogram,
14586 .@"subprogram optimized",
14587 .@"subprogram local",
14588 .@"subprogram definition",
14589 .@"subprogram optimized local",
14590 .@"subprogram optimized definition",
14591 .@"subprogram optimized local definition",
14592 .@"subprogram local definition",
14593 => |kind| {
14594 const sp_flags: u32 = switch (kind) {
14595 .subprogram => 0,
14596 .@"subprogram optimized" => 1 << 4,
14597 .@"subprogram local" => 1 << 2,
14598 .@"subprogram definition" => 1 << 3,
14599 .@"subprogram optimized local" => (1 << 4) | (1 << 2),
14600 .@"subprogram optimized definition" => (1 << 4) | (1 << 3),
14601 .@"subprogram optimized local definition" => (1 << 4) | (1 << 2) | (1 << 3),
14602 .@"subprogram local definition" => (1 << 2) | (1 << 3),
14603 else => unreachable,
14604 };
14605 const extra = self.metadataExtraData(Metadata.Subprogram, data);
14606
14607 try metadata_block.writeAbbrevAdapted(MetadataBlock.Subprogram{
14608 .scope = extra.file,
14609 .name = extra.name,
14610 .linkage_name = extra.linkage_name,
14611 .file = extra.file,
14612 .line = extra.line,
14613 .ty = Metadata.none, //extra.ty,
14614 .scope_line = extra.scope_line,
14615 .sp_flags = sp_flags,
14616 .flags = extra.debug_info_flags,
14617 .compile_unit = extra.compile_unit,
14618 }, metadata_adapter);
14619 },
14620 .lexical_block => {
14621 const extra = self.metadataExtraData(Metadata.LexicalBlock, data);
14622 try metadata_block.writeAbbrevAdapted(MetadataBlock.LexicalBlock{
14623 .scope = extra.scope,
14624 .file = extra.file,
14625 .line = extra.line,
14626 .column = extra.column,
14627 }, metadata_adapter);
14628 },
14629 .location => {
14630 const extra = self.metadataExtraData(Metadata.Location, data);
14631 std.debug.assert(extra.scope != Metadata.none);
14632 try metadata_block.writeAbbrev(MetadataBlock.Location{
14633 .line = extra.line,
14634 .column = extra.column,
14635 .scope = metadata_adapter.getMetadataIndex(extra.scope) - 1,
14636 .inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(extra.inlined_at)),
14637 });
14638 },
14639 .basic_bool_type,
14640 .basic_unsigned_type,
14641 .basic_signed_type,
14642 .basic_float_type,
14643 => |kind| {
14644 const extra = self.metadataExtraData(Metadata.BasicType, data);
14645 try metadata_block.writeAbbrevAdapted(MetadataBlock.BasicType{
14646 .name = extra.name,
14647 .size_in_bits = @as(u64, extra.size_in_bits_lo) | @as(u64, extra.size_in_bits_hi) << 32,
14648 .encoding = switch (kind) {
14649 .basic_bool_type => std.dwarf.ATE.boolean,
14650 .basic_unsigned_type => std.dwarf.ATE.unsigned,
14651 .basic_signed_type => std.dwarf.ATE.signed,
14652 .basic_float_type => std.dwarf.ATE.float,
14653 else => unreachable,
14654 },
14655 }, metadata_adapter);
14656 },
14657 .composite_struct_type,
14658 .composite_union_type,
14659 .composite_enumeration_type,
14660 .composite_array_type,
14661 => |kind| {
14662 const extra = self.metadataExtraData(Metadata.CompositeType, data);
14663
14664 try metadata_block.writeAbbrevAdapted(MetadataBlock.CompositeType{
14665 .tag = switch (kind) {
14666 .composite_struct_type => std.dwarf.TAG.structure_type,
14667 .composite_union_type => std.dwarf.TAG.union_type,
14668 .composite_enumeration_type => std.dwarf.TAG.enumeration_type,
14669 .composite_array_type => std.dwarf.TAG.array_type,
14670 else => unreachable,
14671 },
14672 .name = extra.name,
14673 .file = extra.file,
14674 .line = extra.line,
14675 .scope = extra.scope,
14676 .underlying_type = extra.underlying_type,
14677 .size_in_bits = @as(u64, extra.size_in_bits_lo) | @as(u64, extra.size_in_bits_hi) << 32,
14678 .align_in_bits = @as(u64, extra.align_in_bits_lo) | @as(u64, extra.align_in_bits_hi) << 32,
14679 .elements = extra.fields_tuple,
14680 }, metadata_adapter);
14681 },
14682 .derived_pointer_type,
14683 .derived_member_type,
14684 => |kind| {
14685 const extra = self.metadataExtraData(Metadata.DerivedType, data);
14686 try metadata_block.writeAbbrevAdapted(MetadataBlock.DerivedType{
14687 .tag = switch (kind) {
14688 .derived_pointer_type => std.dwarf.TAG.pointer_type,
14689 .derived_member_type => std.dwarf.TAG.member,
14690 else => unreachable,
14691 },
14692 .name = extra.name,
14693 .file = extra.file,
14694 .line = extra.line,
14695 .scope = extra.scope,
14696 .underlying_type = extra.underlying_type,
14697 .size_in_bits = @as(u64, extra.size_in_bits_lo) | @as(u64, extra.size_in_bits_hi) << 32,
14698 .align_in_bits = @as(u64, extra.align_in_bits_lo) | @as(u64, extra.align_in_bits_hi) << 32,
14699 .offset_in_bits = @as(u64, extra.offset_in_bits_lo) | @as(u64, extra.offset_in_bits_hi) << 32,
14700 }, metadata_adapter);
14701 },
14702 .subroutine_type => {
14703 const extra = self.metadataExtraData(Metadata.SubroutineType, data);
14704
14705 try metadata_block.writeAbbrevAdapted(MetadataBlock.SubroutineType{
14706 .types = extra.types_tuple,
14707 }, metadata_adapter);
14708 },
14709 .enumerator_unsigned,
14710 .enumerator_signed_positive,
14711 .enumerator_signed_negative,
14712 => |kind| {
14713 const positive = switch (kind) {
14714 .enumerator_unsigned,
14715 .enumerator_signed_positive,
14716 => true,
14717 .enumerator_signed_negative => false,
14718 else => unreachable,
14719 };
14720
14721 const unsigned = switch (kind) {
14722 .enumerator_unsigned => true,
14723 .enumerator_signed_positive,
14724 .enumerator_signed_negative,
14725 => false,
14726 else => unreachable,
14727 };
14728
14729 const extra = self.metadataExtraData(Metadata.Enumerator, data);
14730
14731 const limbs = self.metadata_limbs.items[extra.limbs_index..][0..extra.limbs_len];
14732
14733 const bigint = std.math.big.int.Const{
14734 .limbs = limbs,
14735 .positive = positive,
14736 };
14737
14738 if (extra.bit_width <= 64) {
14739 const val = bigint.to(i64) catch unreachable;
14740 const emit_val = if (positive)
14741 @shlWithOverflow(val, 1)[0]
14742 else
14743 (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1);
14744 try metadata_block.writeAbbrevAdapted(MetadataBlock.Enumerator{
14745 .flags = .{
14746 .unsigned = unsigned,
14747 .bigint = false,
14748 },
14749 .bit_width = extra.bit_width,
14750 .name = extra.name,
14751 .value = @bitCast(emit_val),
14752 }, metadata_adapter);
14753 } else {
14754 const word_count = std.mem.alignForward(u32, extra.bit_width, 64) / 64;
14755 try record.ensureUnusedCapacity(self.gpa, 3 + word_count);
14756
14757 const flags = MetadataBlock.Enumerator.Flags{
14758 .unsigned = unsigned,
14759 .bigint = true,
14760 };
14761
14762 const FlagsInt = @typeInfo(MetadataBlock.Enumerator.Flags).Struct.backing_integer.?;
14763
14764 const flags_int: FlagsInt = @bitCast(flags);
14765
14766 record.appendAssumeCapacity(@intCast(flags_int));
14767 record.appendAssumeCapacity(@intCast(extra.bit_width));
14768 record.appendAssumeCapacity(metadata_adapter.getMetadataStringIndex(extra.name));
14769
14770 const buffer: [*]u8 = @ptrCast(record.items.ptr);
14771 bigint.writeTwosComplement(buffer[0..(word_count * 8)], .little);
14772
14773 const signed_buffer: [*]i64 = @ptrCast(record.items.ptr);
14774 for (signed_buffer[0..word_count], 0..) |val, i| {
14775 signed_buffer[i] = if (val >= 0)
14776 @shlWithOverflow(val, 1)[0]
14777 else
14778 (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1);
14779 }
14780
14781 try metadata_block.writeUnabbrev(
14782 MetadataBlock.Enumerator.id,
14783 record.items.ptr[0..(3 + word_count)],
14784 );
14785 }
14786 },
14787 .subrange => {
14788 const extra = self.metadataExtraData(Metadata.Subrange, data);
14789
14790 try metadata_block.writeAbbrevAdapted(MetadataBlock.Subrange{
14791 .count = extra.count,
14792 .lower_bound = extra.lower_bound,
14793 }, metadata_adapter);
14794 },
14795 .expression => {
14796 var extra = self.metadataExtraDataTrail(Metadata.Expression, data);
14797
14798 const elements = extra.trail.next(extra.data.elements_len, u32, self);
14799
14800 try metadata_block.writeAbbrevAdapted(MetadataBlock.Expression{
14801 .elements = elements,
14802 }, metadata_adapter);
14803 },
14804 .tuple => {
14805 var extra = self.metadataExtraDataTrail(Metadata.Tuple, data);
14806
14807 const elements = extra.trail.next(extra.data.elements_len, Metadata, self);
14808
14809 try metadata_block.writeAbbrevAdapted(MetadataBlock.Node{
14810 .elements = elements,
14811 }, metadata_adapter);
14812 },
14813 .module_flag => {
14814 const extra = self.metadataExtraData(Metadata.ModuleFlag, data);
14815 try metadata_block.writeAbbrev(MetadataBlock.Node{
14816 .elements = &.{
14817 @enumFromInt(metadata_adapter.getMetadataIndex(extra.behaviour)),
14818 @enumFromInt(metadata_adapter.getMetadataStringIndex(extra.name)),
14819 @enumFromInt(metadata_adapter.getMetadataIndex(extra.constant)),
14820 },
14821 });
14822 },
14823 .local_var => {
14824 const extra = self.metadataExtraData(Metadata.LocalVar, data);
14825 try metadata_block.writeAbbrevAdapted(MetadataBlock.LocalVar{
14826 .scope = extra.scope,
14827 .name = extra.name,
14828 .file = extra.file,
14829 .line = extra.line,
14830 .ty = extra.ty,
14831 }, metadata_adapter);
14832 },
14833 .parameter => {
14834 const extra = self.metadataExtraData(Metadata.Parameter, data);
14835 try metadata_block.writeAbbrevAdapted(MetadataBlock.Parameter{
14836 .scope = extra.scope,
14837 .name = extra.name,
14838 .file = extra.file,
14839 .line = extra.line,
14840 .ty = extra.ty,
14841 .arg = extra.arg_no,
14842 }, metadata_adapter);
14843 },
14844 .global_var,
14845 .@"global_var local",
14846 => |kind| {
14847 const extra = self.metadataExtraData(Metadata.GlobalVar, data);
14848 try metadata_block.writeAbbrevAdapted(MetadataBlock.GlobalVar{
14849 .scope = extra.scope,
14850 .name = extra.name,
14851 .linkage_name = extra.linkage_name,
14852 .file = extra.file,
14853 .line = extra.line,
14854 .ty = extra.ty,
14855 .local = kind == .@"global_var local",
14856 }, metadata_adapter);
14857 },
14858 .global_var_expression => {
14859 const extra = self.metadataExtraData(Metadata.GlobalVarExpression, data);
14860 try metadata_block.writeAbbrevAdapted(MetadataBlock.GlobalVarExpression{
14861 .variable = extra.variable,
14862 .expression = extra.expression,
14863 }, metadata_adapter);
14864 },
14865 .constant => {
14866 const constant: Constant = @enumFromInt(data);
14867 try metadata_block.writeAbbrevAdapted(MetadataBlock.Constant{
14868 .ty = constant.typeOf(self),
14869 .constant = constant,
14870 }, metadata_adapter);
14871 },
14872 }
14873 record.clearRetainingCapacity();
14874 }
14875
14876 // Write named metadata
14877 for (self.metadata_named.keys(), self.metadata_named.values()) |name, operands| {
14878 const slice = name.slice(self).?;
14879 try metadata_block.writeAbbrev(MetadataBlock.Name{
14880 .name = slice,
14881 });
14882
14883 const elements = self.metadata_extra.items[operands.index..][0..operands.len];
14884 for (elements) |*e| {
14885 e.* = metadata_adapter.getMetadataIndex(@enumFromInt(e.*)) - 1;
14886 }
14887
14888 try metadata_block.writeAbbrev(MetadataBlock.NamedNode{
14889 .elements = @ptrCast(elements),
14890 });
14891 }
14892
14893 try metadata_block.end();
14894 }
14895
1446914896 // FUNCTION_BLOCKS
1447014897 {
1447114898 const FunctionAdapter = struct {
1447214899 constant_adapter: ConstantAdapter,
14900 metadata_adapter: MetadataAdapter,
1447314901 func: *const Function,
1447414902 instruction_index: u32 = 0,
1447514903
1447614904 pub fn init(
1447714905 const_adapter: ConstantAdapter,
14906 meta_adapter: MetadataAdapter,
1447814907 func: *const Function,
1447914908 ) @This() {
1448014909 return .{
1448114910 .constant_adapter = const_adapter,
14911 .metadata_adapter = meta_adapter,
1448214912 .func = func,
1448314913 .instruction_index = 0,
1448414914 };
......@@ -14499,12 +14929,21 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1449914929 return @intCast(switch (value.unwrap()) {
1450014930 .instruction => |instruction| instruction.valueIndex(adapter.func) + adapter.firstInstr(),
1450114931 .constant => |constant| adapter.constant_adapter.getConstantIndex(constant),
14502 .metadata => unreachable,
14932 .metadata => |metadata| if (!adapter.metadata_adapter.builder.strip) blk: {
14933 const real_metadata = metadata.unwrap(adapter.metadata_adapter.builder);
14934 if (@intFromEnum(real_metadata) < Metadata.first_local_metadata)
14935 break :blk adapter.metadata_adapter.getMetadataIndex(real_metadata) - 1;
14936
14937 return @intCast(@intFromEnum(metadata) -
14938 Metadata.first_local_metadata +
14939 adapter.metadata_adapter.builder.metadata_strings.count() +
14940 adapter.metadata_adapter.builder.metadata_map.count() - 1);
14941 } else unreachable,
1450314942 });
1450414943 }
1450514944
1450614945 pub fn getOffsetValueIndex(adapter: @This(), value: Value) u32 {
14507 return adapter.offset() - adapter.getValueIndex(value);
14946 return @subWithOverflow(adapter.offset(), adapter.getValueIndex(value))[0];
1450814947 }
1450914948
1451014949 pub fn getOffsetValueSignedIndex(adapter: @This(), value: Value) i32 {
......@@ -14543,11 +14982,28 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1454314982
1454414983 try function_block.writeAbbrev(FunctionBlock.DeclareBlocks{ .num_blocks = func.blocks.len });
1454514984
14546 var adapter = FunctionAdapter.init(constant_adapter, &func);
14985 var adapter = FunctionAdapter.init(constant_adapter, metadata_adapter, &func);
14986
14987 // Emit function level metadata block
14988 if (!self.strip and func.debug_values.len != 0) {
14989 const MetadataBlock = IR.FunctionMetadataBlock;
14990 var metadata_block = try function_block.enterSubBlock(MetadataBlock);
14991
14992 for (func.debug_values) |value| {
14993 try metadata_block.writeAbbrev(MetadataBlock.Value{
14994 .ty = value.typeOf(@enumFromInt(func_index), self),
14995 .value = @enumFromInt(adapter.getValueIndex(value.toValue())),
14996 });
14997 }
14998
14999 try metadata_block.end();
15000 }
1454715001
1454815002 const tags = func.instructions.items(.tag);
1454915003 const datas = func.instructions.items(.data);
1455015004
15005 var has_location = false;
15006
1455115007 var block_incoming_len: u32 = undefined;
1455215008 for (0..func.instructions.len) |instr_index| {
1455315009 const tag = tags[instr_index];
......@@ -14990,6 +15446,25 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1499015446 },
1499115447 }
1499215448
15449 if (!self.strip) {
15450 if (func.debug_locations.get(@enumFromInt(instr_index))) |maybe_location| {
15451 if (maybe_location) |location| {
15452 try function_block.writeAbbrev(FunctionBlock.DebugLoc{
15453 .line = location.line,
15454 .column = location.column,
15455 .scope = @enumFromInt(metadata_adapter.getMetadataIndex(location.scope)),
15456 .inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(location.inlined_at)),
15457 .is_implicit = false,
15458 });
15459 has_location = true;
15460 } else {
15461 has_location = false;
15462 }
15463 } else if (has_location) {
15464 try function_block.writeAbbrev(FunctionBlock.DebugLocAgain{});
15465 }
15466 }
15467
1499315468 adapter.next();
1499415469 }
1499515470