From: David Blaikie Date: Fri, 1 Nov 2013 00:25:45 +0000 (+0000) Subject: DebugInfo: Emit member variable locations as data instead of expressions in blocks X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=9b93392185d3838cc438629981d7c3fee634176d;p=oota-llvm.git DebugInfo: Emit member variable locations as data instead of expressions 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 --- diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 575cf31eaa6..37eef4111ed 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -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()) { @@ -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, diff --git a/test/DebugInfo/X86/concrete_out_of_line.ll b/test/DebugInfo/X86/concrete_out_of_line.ll index e3a25894c9e..395d5a94f23 100644 --- a/test/DebugInfo/X86/concrete_out_of_line.ll +++ b/test/DebugInfo/X86/concrete_out_of_line.ll @@ -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: diff --git a/test/DebugInfo/X86/gnu-public-names.ll b/test/DebugInfo/X86/gnu-public-names.ll index 34f42a0922f..2a6d9978058 100644 --- a/test/DebugInfo/X86/gnu-public-names.ll +++ b/test/DebugInfo/X86/gnu-public-names.ll @@ -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"