From: David Blaikie Date: Mon, 21 Oct 2013 22:36:50 +0000 (+0000) Subject: DWARF type hashing: begin implementing Step 5, summary hashing in declarable contexts X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f1545a219744c1ae66137e64d1c456cd8e924eb7;p=oota-llvm.git DWARF type hashing: begin implementing Step 5, summary hashing in declarable contexts There are several other tag types that need similar handling but to ensure test coverage they'll be coming incrementally. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193126 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp index aa54db00461..0dacd7384e0 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -189,15 +189,47 @@ void DIEHash::collectAttributes(DIE *Die, DIEAttrs &Attrs) { // Hash an individual attribute \param Attr based on the type of attribute and // the form. -void DIEHash::hashAttribute(AttrEntry Attr) { +void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { const DIEValue *Value = Attr.Val; const DIEAbbrevData *Desc = Attr.Desc; - // 7.27s3 + // 7.27 Step 3 // ... An attribute that refers to another type entry T is processed as // follows: if (const DIEEntry *EntryAttr = dyn_cast(Value)) { DIE *Entry = EntryAttr->getEntry(); + + // Step 5 + // If the tag in Step 3 is one of ... + if (Tag == dwarf::DW_TAG_pointer_type) { + // ... and the referenced type (via the DW_AT_type or DW_AT_friend + // attribute) ... + assert(Desc->getAttribute() == dwarf::DW_AT_type || + Desc->getAttribute() == dwarf::DW_AT_friend); + // [FIXME] ... has a DW_AT_name attribute, + // append the letter 'N' + addULEB128('N'); + + // the DWARF attribute code (DW_AT_type or DW_AT_friend), + addULEB128(Desc->getAttribute()); + + // the context of the tag, + if (DIE *Parent = Entry->getParent()) + addParentContext(Parent); + + // the letter 'E', + addULEB128('E'); + + // and the name of the type. + addString(getDIEStringAttr(Entry, dwarf::DW_AT_name)); + + // FIXME: + // For DW_TAG_friend, if the referenced entry is the DW_TAG_subprogram, + // the context is omitted and the name to be used is the ABI-specific name + // of the subprogram (e.g., the mangled linker name). + return; + } + unsigned &DieNumber = Numbering[Entry]; if (DieNumber) { // a) If T is in the list of [previously hashed types], use the letter @@ -258,11 +290,11 @@ void DIEHash::hashAttribute(AttrEntry Attr) { // Go through the attributes from \param Attrs in the order specified in 7.27.4 // and hash them. -void DIEHash::hashAttributes(const DIEAttrs &Attrs) { +void DIEHash::hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag) { #define ADD_ATTR(ATTR) \ { \ if (ATTR.Val != 0) \ - hashAttribute(ATTR); \ + hashAttribute(ATTR, Tag); \ } ADD_ATTR(Attrs.DW_AT_name); @@ -322,7 +354,7 @@ void DIEHash::hashAttributes(const DIEAttrs &Attrs) { void DIEHash::addAttributes(DIE *Die) { DIEAttrs Attrs = {}; collectAttributes(Die, Attrs); - hashAttributes(Attrs); + hashAttributes(Attrs, Die->getTag()); } // Compute the hash of a DIE. This is based on the type signature computation diff --git a/lib/CodeGen/AsmPrinter/DIEHash.h b/lib/CodeGen/AsmPrinter/DIEHash.h index f6650cc93e7..a59df35a0d8 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.h +++ b/lib/CodeGen/AsmPrinter/DIEHash.h @@ -119,10 +119,10 @@ private: void collectAttributes(DIE *Die, DIEAttrs &Attrs); /// \brief Hashes the attributes in \param Attrs in order. - void hashAttributes(const DIEAttrs &Attrs); + void hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag); /// \brief Hashes an individual attribute. - void hashAttribute(AttrEntry Attr); + void hashAttribute(AttrEntry Attr, dwarf::Tag Tag); private: MD5 Hash; diff --git a/unittests/CodeGen/DIEHashTest.cpp b/unittests/CodeGen/DIEHashTest.cpp index 6c9cd895103..7d8b024e40a 100644 --- a/unittests/CodeGen/DIEHashTest.cpp +++ b/unittests/CodeGen/DIEHashTest.cpp @@ -26,9 +26,8 @@ TEST(DIEHashTest, Data1) { ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res); } +// struct {}; TEST(DIEHashTest, TrivialType) { - // A complete, but simple, type containing no members and defined on the first - // line of a file. DIE Unnamed(dwarf::DW_TAG_structure_type); DIEInteger One(1); Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One); @@ -42,9 +41,8 @@ TEST(DIEHashTest, TrivialType) { ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res); } +// struct foo { }; TEST(DIEHashTest, NamedType) { - // A complete named type containing no members and defined on the first line - // of a file. DIE Foo(dwarf::DW_TAG_structure_type); DIEInteger One(1); DIEString FooStr(&One, "foo"); @@ -57,9 +55,8 @@ TEST(DIEHashTest, NamedType) { ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res); } +// namespace space { struct foo { }; } TEST(DIEHashTest, NamespacedType) { - // A complete named type containing no members and defined on the first line - // of a file. DIE CU(dwarf::DW_TAG_compile_unit); DIE *Space = new DIE(dwarf::DW_TAG_namespace); @@ -84,6 +81,7 @@ TEST(DIEHashTest, NamespacedType) { ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res); } +// struct { int member; }; TEST(DIEHashTest, TypeWithMember) { DIE Unnamed(dwarf::DW_TAG_structure_type); DIEInteger Four(4); @@ -112,6 +110,7 @@ TEST(DIEHashTest, TypeWithMember) { ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res); } +// struct foo { int mem1, mem2; }; TEST(DIEHashTest, ReusedType) { DIE Unnamed(dwarf::DW_TAG_structure_type); DIEInteger Eight(8); @@ -149,6 +148,7 @@ TEST(DIEHashTest, ReusedType) { ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res); } +// struct foo { static foo f; }; TEST(DIEHashTest, RecursiveType) { DIE Foo(dwarf::DW_TAG_structure_type); DIEInteger One(1); @@ -169,4 +169,33 @@ TEST(DIEHashTest, RecursiveType) { ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res); } + +// struct foo { foo *mem; }; +TEST(DIEHashTest, Pointer) { + DIE Foo(dwarf::DW_TAG_structure_type); + DIEInteger Eight(8); + Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight); + DIEString FooStr(&Eight, "foo"); + Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr); + + DIE *Mem = new DIE(dwarf::DW_TAG_member); + DIEString MemStr(&Eight, "mem"); + Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr); + DIEInteger Zero(0); + Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero); + + DIE FooPtr(dwarf::DW_TAG_pointer_type); + FooPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight); + DIEEntry FooRef(&Foo); + FooPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef); + + DIEEntry FooPtrRef(&FooPtr); + Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooPtrRef); + + Foo.addChild(Mem); + + uint64_t MD5Res = DIEHash().computeTypeSignature(&Foo); + + ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res); +} }