Add support for hashing attributes with DW_FORM_block. This required
authorEric Christopher <echristo@gmail.com>
Thu, 20 Feb 2014 02:50:45 +0000 (02:50 +0000)
committerEric Christopher <echristo@gmail.com>
Thu, 20 Feb 2014 02:50:45 +0000 (02:50 +0000)
passing down an AsmPrinter instance so we could compute the size of
the block which could be target specific. All of the test cases in
the unittest don't have any target specific data so we can use a NULL
AsmPrinter there. This also depends upon block data being added as
integers.

We can now hash the entire fission-cu.ll compile unit so turn the
flag on there with the hash value.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201752 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AsmPrinter/DIEHash.cpp
lib/CodeGen/AsmPrinter/DIEHash.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
test/DebugInfo/X86/fission-cu.ll
unittests/CodeGen/DIEHashTest.cpp

index 1275d69a262d2e35c2496b68a26edb3796de9a81..dbeb5890b00b0b0900850e182e57999ce182ac85 100644 (file)
@@ -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<DIEValue *> &Values) {
+  for (SmallVectorImpl<DIEValue *>::const_iterator I = Values.begin(),
+                                                   E = Values.end();
+       I != E; ++I)
+    Hash.update((uint64_t)cast<DIEInteger>(*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<DIEInteger>(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<DIEBlock>(Value)) {
+      addULEB128(cast<DIEBlock>(Value)->ComputeSize(AP));
+      hashBlockData(cast<DIEBlock>(Value)->getValues());
+    } else {
+      addULEB128(cast<DIELoc>(Value)->ComputeSize(AP));
+      hashBlockData(cast<DIELoc>(Value)->getValues());
+    }
+    break;
   default:
     llvm_unreachable("Add support for additional forms");
   }
index bac3c5578447075a158ef1fe4db70d9bb5a7619b..40d6f44f311a4dcac83ec1f114f55471adc46cec 100644 (file)
@@ -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<DIEValue *> &Values);
+
   /// \brief Hashes an individual attribute.
   void hashAttribute(AttrEntry Attr, dwarf::Tag Tag);
 
@@ -143,6 +150,7 @@ private:
 
 private:
   MD5 Hash;
+  AsmPrinter *AP;
   DenseMap<const DIE *, unsigned> Numbering;
 };
 }
index 70db96e43a1e837c4b77b4a9bd2c82e6e8a38102..9428fea7e1471cf4d30b4b5eecc538783f0f4110 100644 (file)
@@ -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,
index 1482ec27cf60ca28190ef0bf303f46fd12d498b1..43d36266c8b03759ae717461683a5d96d36ab3df 100644 (file)
@@ -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]*]]})
index e613181996cda0e6b8a4632d71ccdcb00bcb8f39..c874cef92409cd431fef13726da8dd45d0346d01 100644 (file)
@@ -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);
+}
 }