diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp index 1275d69a262..dbeb5890b00 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -17,6 +17,7 @@ #include "DIE.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Endian.h" @@ -269,6 +270,15 @@ void DIEHash::hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag, computeHash(Entry); } +// Hash all of the values in a block like set of values. This assumes that +// all of the data is going to be added as integers. +void DIEHash::hashBlockData(const SmallVectorImpl &Values) { + for (SmallVectorImpl::const_iterator I = Values.begin(), + E = Values.end(); + I != E; ++I) + Hash.update((uint64_t)cast(*I)->getValue()); +} + // Hash an individual attribute \param Attr based on the type of attribute and // the form. void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { @@ -321,6 +331,22 @@ void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { addULEB128(dwarf::DW_FORM_flag); addULEB128((int64_t)cast(Value)->getValue()); break; + case dwarf::DW_FORM_exprloc: + case dwarf::DW_FORM_block1: + case dwarf::DW_FORM_block2: + case dwarf::DW_FORM_block4: + case dwarf::DW_FORM_block: + addULEB128('A'); + addULEB128(Attribute); + addULEB128(dwarf::DW_FORM_block); + if (isa(Value)) { + addULEB128(cast(Value)->ComputeSize(AP)); + hashBlockData(cast(Value)->getValues()); + } else { + addULEB128(cast(Value)->ComputeSize(AP)); + hashBlockData(cast(Value)->getValues()); + } + break; default: llvm_unreachable("Add support for additional forms"); } diff --git a/lib/CodeGen/AsmPrinter/DIEHash.h b/lib/CodeGen/AsmPrinter/DIEHash.h index bac3c557844..40d6f44f311 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.h +++ b/lib/CodeGen/AsmPrinter/DIEHash.h @@ -17,6 +17,7 @@ namespace llvm { +class AsmPrinter; class CompileUnit; /// \brief An object containing the capability of hashing and adding hash @@ -84,6 +85,8 @@ class DIEHash { }; public: + DIEHash(AsmPrinter *A = NULL) : AP(A) {} + /// \brief Computes the ODR signature. uint64_t computeDIEODRSignature(const DIE &Die); @@ -122,6 +125,10 @@ private: /// \brief Hashes the attributes in \param Attrs in order. void hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag); + /// \brief Hashes the data in a block like DIEValue, e.g. DW_FORM_block or + /// DW_FORM_exprloc. + void hashBlockData(const SmallVectorImpl &Values); + /// \brief Hashes an individual attribute. void hashAttribute(AttrEntry Attr, dwarf::Tag Tag); @@ -143,6 +150,7 @@ private: private: MD5 Hash; + AsmPrinter *AP; DenseMap Numbering; }; } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 70db96e43a1..9428fea7e14 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1007,7 +1007,7 @@ void DwarfDebug::finalizeModuleInfo() { // This should be a unique identifier when we want to build .dwp files. uint64_t ID = 0; if (GenerateCUHash) { - DIEHash CUHash; + DIEHash CUHash(Asm); ID = CUHash.computeCUSignature(*TheU->getUnitDie()); } TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, diff --git a/test/DebugInfo/X86/fission-cu.ll b/test/DebugInfo/X86/fission-cu.ll index 1482ec27cf6..43d36266c8b 100644 --- a/test/DebugInfo/X86/fission-cu.ll +++ b/test/DebugInfo/X86/fission-cu.ll @@ -1,4 +1,4 @@ -; RUN: llc -split-dwarf=Enable -O0 %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o %t +; RUN: llc -split-dwarf=Enable -generate-cu-hash -O0 %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o %t ; RUN: llvm-dwarfdump -debug-dump=all %t | FileCheck %s ; RUN: llvm-readobj --relocations %t | FileCheck --check-prefix=OBJ %s @@ -61,7 +61,7 @@ ; CHECK: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x00000000] = "baz.dwo") ; CHECK: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000000) ; CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000008] = "/usr/local/google/home/echristo/tmp") -; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x0000000000000000) +; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x1f1f859683d49324) ; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000) ; Check that the rest of the compile units have information. @@ -73,7 +73,7 @@ ; CHECK-NOT: DW_AT_low_pc ; CHECK-NOT: DW_AT_stmt_list ; CHECK-NOT: DW_AT_comp_dir -; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x0000000000000000) +; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x1f1f859683d49324) ; CHECK: DW_TAG_variable ; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000002) string = "a") ; CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x{{[0-9a-f]*}} => {[[TYPE:0x[0-9a-f]*]]}) diff --git a/unittests/CodeGen/DIEHashTest.cpp b/unittests/CodeGen/DIEHashTest.cpp index e613181996c..c874cef9240 100644 --- a/unittests/CodeGen/DIEHashTest.cpp +++ b/unittests/CodeGen/DIEHashTest.cpp @@ -594,4 +594,59 @@ TEST(DIEHashTest, MemberSdata) { uint64_t MD5Res = DIEHash().computeTypeSignature(A); ASSERT_EQ(0x9a216000dd3788a7ULL, MD5Res); } + +// Derived from: +// struct A { +// const static float PI = 3.14; +// }; +// A a; +TEST(DIEHashTest, MemberBlock) { + DIE A(dwarf::DW_TAG_structure_type); + DIEInteger One(1); + DIEString AStr(&One, "A"); + A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr); + A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One); + A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One); + A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One); + + DIEInteger Four(4); + DIEString FStr(&One, "float"); + DIE *FloatTyDIE = new DIE(dwarf::DW_TAG_base_type); + FloatTyDIE->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four); + FloatTyDIE->addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Four); + FloatTyDIE->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FStr); + + DIEEntry FloatTy(FloatTyDIE); + DIE *PITyDIE = new DIE(dwarf::DW_TAG_const_type); + PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FloatTy); + + DIEEntry PITy(PITyDIE); + DIE *PI = new DIE(dwarf::DW_TAG_member); + DIEString PIStr(&One, "PI"); + DIEInteger Two(2); + PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &PIStr); + PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One); + PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &Two); + PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PITy); + PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One); + PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One); + + DIEBlock *PIBlock = new DIEBlock(); + DIEInteger Blk1(0xc3); + DIEInteger Blk2(0xf5); + DIEInteger Blk3(0x48); + DIEInteger Blk4(0x40); + + PIBlock->addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk1); + PIBlock->addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk2); + PIBlock->addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk3); + PIBlock->addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk4); + + PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_block1, PIBlock); + + A.addChild(PI); + + uint64_t MD5Res = DIEHash().computeTypeSignature(A); + ASSERT_EQ(0x493af53ad3d3f651ULL, MD5Res); +} }