From a954618c6e6c5f94d3cedc0b6bc19dbc49e56ac2 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Fri, 25 Oct 2013 18:38:43 +0000 Subject: DIEHash: Summary hashing of nested types git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193427 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/Dwarf.h | 28 ++++++++++++++++++++++++++++ lib/CodeGen/AsmPrinter/DIEHash.cpp | 25 ++++++++++++++++++++++++- lib/CodeGen/AsmPrinter/DIEHash.h | 2 ++ unittests/CodeGen/DIEHashTest.cpp | 19 +++++++++++++++++++ 4 files changed, 73 insertions(+), 1 deletion(-) diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index f3f42741ef..23bbd1c384 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -141,6 +141,34 @@ enum Tag LLVM_ENUM_INT_TYPE(uint16_t) { DW_TAG_hi_user = 0xffff }; +inline bool isType(Tag T) { + switch (T) { + case DW_TAG_array_type: + case DW_TAG_class_type: + case DW_TAG_interface_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: + case DW_TAG_string_type: + case DW_TAG_structure_type: + case DW_TAG_subroutine_type: + case DW_TAG_union_type: + case DW_TAG_ptr_to_member_type: + case DW_TAG_set_type: + case DW_TAG_subrange_type: + case DW_TAG_base_type: + case DW_TAG_const_type: + case DW_TAG_file_type: + case DW_TAG_packed_type: + case DW_TAG_volatile_type: + case DW_TAG_typedef: + return true; + default: + return false; + } +} + enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) { // Attributes DW_AT_sibling = 0x01, diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp index b8b2bd2205..18264672ed 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -384,6 +384,18 @@ void DIEHash::addAttributes(const DIE &Die) { hashAttributes(Attrs, Die.getTag()); } +void DIEHash::hashNestedType(const DIE &Die, StringRef Name) { + // 7.27 Step 7 + // ... append the letter 'S', + addULEB128('S'); + + // the tag of C, + addULEB128(Die.getTag()); + + // and the name. + addString(Name); +} + // Compute the hash of a DIE. This is based on the type signature computation // given in section 7.27 of the DWARF4 standard. It is the md5 hash of a // flattened description of the DIE. @@ -398,8 +410,19 @@ void DIEHash::computeHash(const DIE &Die) { // Then hash each of the children of the DIE. for (std::vector::const_iterator I = Die.getChildren().begin(), E = Die.getChildren().end(); - I != E; ++I) + I != E; ++I) { + // 7.27 Step 7 + // If C is a nested type entry or a member function entry, ... + if (isType((*I)->getTag())) { + StringRef Name = getDIEStringAttr(**I, dwarf::DW_AT_name); + // ... and has a DW_AT_name attribute + if (!Name.empty()) { + hashNestedType(**I, Name); + continue; + } + } computeHash(**I); + } // Following the last (or if there are no children), append a zero byte. Hash.update(makeArrayRef((uint8_t)'\0')); diff --git a/lib/CodeGen/AsmPrinter/DIEHash.h b/lib/CodeGen/AsmPrinter/DIEHash.h index da373de3f0..b9cf7ce949 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.h +++ b/lib/CodeGen/AsmPrinter/DIEHash.h @@ -137,6 +137,8 @@ private: /// \brief Hashes a reference to a previously referenced type DIE. void hashRepeatedTypeReference(dwarf::Attribute Attribute, unsigned DieNumber); + void hashNestedType(const DIE &Die, StringRef Name); + private: MD5 Hash; DenseMap Numbering; diff --git a/unittests/CodeGen/DIEHashTest.cpp b/unittests/CodeGen/DIEHashTest.cpp index 6f71462bfd..fb6f4b3640 100644 --- a/unittests/CodeGen/DIEHashTest.cpp +++ b/unittests/CodeGen/DIEHashTest.cpp @@ -477,4 +477,23 @@ TEST(DIEHashTest, RefUnnamedType) { ASSERT_EQ(0x954e026f01c02529ULL, MD5Res); } + +// struct { struct bar { }; }; +TEST(DIEHashTest, NestedType) { + DIE Unnamed(dwarf::DW_TAG_structure_type); + DIEInteger One(1); + Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One); + + DIE *Foo = new DIE(dwarf::DW_TAG_structure_type); + DIEString FooStr(&One, "foo"); + Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr); + Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One); + + Unnamed.addChild(Foo); + + uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed); + + // The exact same hash GCC produces for this DIE. + ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res); +} } -- cgit v1.2.3