[llvm] r193126 - DWARF type hashing: begin implementing Step 5, summary hashing in declarable contexts

David Blaikie dblaikie at gmail.com
Mon Oct 21 15:36:50 PDT 2013


Author: dblaikie
Date: Mon Oct 21 17:36:50 2013
New Revision: 193126

URL: http://llvm.org/viewvc/llvm-project?rev=193126&view=rev
Log:
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.

Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.h
    llvm/trunk/unittests/CodeGen/DIEHashTest.cpp

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp?rev=193126&r1=193125&r2=193126&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp Mon Oct 21 17:36:50 2013
@@ -189,15 +189,47 @@ void DIEHash::collectAttributes(DIE *Die
 
 // 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<DIEEntry>(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 At
 
 // 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 DIEAt
 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

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.h?rev=193126&r1=193125&r2=193126&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.h Mon Oct 21 17:36:50 2013
@@ -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;

Modified: llvm/trunk/unittests/CodeGen/DIEHashTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/CodeGen/DIEHashTest.cpp?rev=193126&r1=193125&r2=193126&view=diff
==============================================================================
--- llvm/trunk/unittests/CodeGen/DIEHashTest.cpp (original)
+++ llvm/trunk/unittests/CodeGen/DIEHashTest.cpp Mon Oct 21 17:36:50 2013
@@ -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);
+}
 }





More information about the llvm-commits mailing list