Skip to content

Commit

Permalink
DebugInfo: Emit member variable locations as data instead of expressi…
Browse files Browse the repository at this point in the history
…ons in blocks

Drive by space optimization. Also makes the DIEs more regular which
might speed up DWARF parsing.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193835 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
dwblaikie committed Nov 1, 2013
1 parent 6f45b1f commit 9b93392
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 33 deletions.
60 changes: 31 additions & 29 deletions lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1830,33 +1830,6 @@ void CompileUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
addUInt(MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);

uint64_t Size = DT.getSizeInBits();
uint64_t FieldSize = getBaseTypeSize(DD, DT);

if (Size != FieldSize) {
// Handle bitfield.
addUInt(MemberDie, dwarf::DW_AT_byte_size, None,
getBaseTypeSize(DD, DT) >> 3);
addUInt(MemberDie, dwarf::DW_AT_bit_size, None, DT.getSizeInBits());

uint64_t Offset = DT.getOffsetInBits();
uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
uint64_t HiMark = (Offset + FieldSize) & AlignMask;
uint64_t FieldOffset = (HiMark - FieldSize);
Offset -= FieldOffset;

// Maybe we need to work from the other end.
if (Asm->getDataLayout().isLittleEndian())
Offset = FieldSize - (Offset + Size);
addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, Offset);

// Here WD_AT_data_member_location points to the anonymous
// field that includes this bit field.
addUInt(MemLocationDie, dwarf::DW_FORM_udata, FieldOffset >> 3);

} else
// This is not a bitfield.
addUInt(MemLocationDie, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);

if (DT.getTag() == dwarf::DW_TAG_inheritance && DT.isVirtual()) {

Expand All @@ -1874,8 +1847,37 @@ void CompileUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);

addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
} else
addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
} else {
uint64_t Size = DT.getSizeInBits();
uint64_t FieldSize = getBaseTypeSize(DD, DT);
uint64_t OffsetInBytes;

if (Size != FieldSize) {
// Handle bitfield.
addUInt(MemberDie, dwarf::DW_AT_byte_size, None,
getBaseTypeSize(DD, DT) >> 3);
addUInt(MemberDie, dwarf::DW_AT_bit_size, None, DT.getSizeInBits());

uint64_t Offset = DT.getOffsetInBits();
uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
uint64_t HiMark = (Offset + FieldSize) & AlignMask;
uint64_t FieldOffset = (HiMark - FieldSize);
Offset -= FieldOffset;

// Maybe we need to work from the other end.
if (Asm->getDataLayout().isLittleEndian())
Offset = FieldSize - (Offset + Size);
addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, Offset);

// Here WD_AT_data_member_location points to the anonymous
// field that includes this bit field.
OffsetInBytes = FieldOffset >> 3;
} else
// This is not a bitfield.
OffsetInBytes = DT.getOffsetInBits() >> 3;
addUInt(MemberDie, dwarf::DW_AT_data_member_location, None,
OffsetInBytes);
}

if (DT.isProtected())
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Expand Down
6 changes: 3 additions & 3 deletions test/DebugInfo/X86/concrete_out_of_line.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
; first check that we have a TAG_subprogram at a given offset and it has
; AT_inline.

; CHECK: 0x0000011e: DW_TAG_subprogram [17]
; CHECK: 0x0000011c: DW_TAG_subprogram [17]
; CHECK-NEXT: DW_AT_specification
; CHECK-NEXT: DW_AT_inline


; and then that a TAG_subprogram refers to it with AT_abstract_origin.

; CHECK: 0x0000015f: DW_TAG_subprogram [19]
; CHECK-NEXT: DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x011e => {0x0000011e})
; CHECK: 0x0000015d: DW_TAG_subprogram [19]
; CHECK-NEXT: DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x011c => {0x0000011c})

define i32 @_ZN17nsAutoRefCnt7ReleaseEv() {
entry:
Expand Down
2 changes: 1 addition & 1 deletion test/DebugInfo/X86/gnu-public-names.ll
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
; CHECK-NEXT: Length: 231
; CHECK-NEXT: Version: 2
; CHECK-NEXT: Offset in .debug_info: 0
; CHECK-NEXT: Size: 381
; CHECK-NEXT: Size: 379
; CHECK-NEXT: Offset Linkage Kind Name
; CHECK-DAG: [[GLOBAL_FUNC]] EXTERNAL FUNCTION "global_function"
; CHECK-DAG: [[NS]] EXTERNAL TYPE "ns"
Expand Down

0 comments on commit 9b93392

Please sign in to comment.