[llvm] r188243 - Add the start of DIE hashing for DWARF4 type units and split dwarf
Eric Christopher
echristo at gmail.com
Tue Oct 15 17:46:23 PDT 2013
On Tue, Oct 15, 2013 at 5:07 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
>
>
> On Mon, Aug 12, 2013 at 6:21 PM, Eric Christopher <echristo at gmail.com>
> wrote:
>>
>> Author: echristo
>> Date: Mon Aug 12 20:21:55 2013
>> New Revision: 188243
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=188243&view=rev
>> Log:
>> Add the start of DIE hashing for DWARF4 type units and split dwarf
>> CUs.
>>
>> Currently only hashes the name of CUs and the names of any children,
>> but it's an obvious first step to show the framework. The testcase
>> should continue to be correct, however, as it's an empty TU.
>>
>> Added:
>> llvm/trunk/test/DebugInfo/X86/fission-hash.ll
>> Modified:
>> llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp
>> llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.h
>> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
>>
>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp?rev=188243&r1=188242&r2=188243&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp Mon Aug 12 20:21:55 2013
>> @@ -102,6 +102,92 @@ void DIEHash::addParentContext(DIE *Pare
>> }
>> }
>>
>> +// Collect all of the attributes for a particular DIE in single
>> structure.
>> +void DIEHash::collectAttributes(DIE *Die, DIEAttrs Attrs) {
>> + const SmallVectorImpl<DIEValue *> &Values = Die->getValues();
>> + const DIEAbbrev &Abbrevs = Die->getAbbrev();
>> +
>> +#define COLLECT_ATTR(NAME)
>> \
>> + Attrs.NAME.Val = Values[i];
>> \
>> + Attrs.NAME.Desc = &Abbrevs.getData()[i];
>> +
>> + for (size_t i = 0, e = Values.size(); i != e; ++i) {
>> + DEBUG(dbgs() << "Attribute: "
>> + <<
>> dwarf::AttributeString(Abbrevs.getData()[i].getAttribute())
>> + << " added.\n");
>> + switch (Abbrevs.getData()[i].getAttribute()) {
>> + case dwarf::DW_AT_name:
>> + COLLECT_ATTR(DW_AT_name);
>> + break;
>> + default:
>> + break;
>> + }
>> + }
>> +}
>> +
>> +// Hash an individual attribute \param Attr based on the type of
>> attribute and
>> +// the form.
>> +void DIEHash::hashAttribute(AttrEntry Attr) {
>> + const DIEValue *Value = Attr.Val;
>> + const DIEAbbrevData *Desc = Attr.Desc;
>> +
>> + // TODO: Add support for types.
>> +
>> + // Add the letter A to the hash.
>> + addULEB128('A');
>> +
>> + // Then the attribute code and form.
>> + addULEB128(Desc->getAttribute());
>> + addULEB128(Desc->getForm());
>> +
>> + // TODO: Add support for additional forms.
>> + switch (Desc->getForm()) {
>> + case dwarf::DW_FORM_strp:
>> + addString(cast<DIEString>(Value)->getString());
>> + break;
>> + }
>> +}
>> +
>> +// Go through the attributes from \param Attrs in the order specified in
>> 7.27.4
>> +// and hash them.
>> +void DIEHash::hashAttributes(DIEAttrs Attrs) {
>> +#define ADD_ATTR(ATTR)
>> \
>> + {
>> \
>> + if (ATTR.Val != 0)
>> \
>> + hashAttribute(ATTR);
>> \
>> + }
>> +
>> + // FIXME: Add the rest.
>> + ADD_ATTR(Attrs.DW_AT_name);
>> +}
>> +
>> +// Add all of the attributes for \param Die to the hash.
>> +void DIEHash::addAttributes(DIE *Die) {
>> + DIEAttrs Attrs;
>> + memset(&Attrs, 0, sizeof(Attrs));
>
>
> I'd thought this was equivalent to:
>
> DIEAttrs Attrs = {};
>
> is it not? Is there a benefit to writing it with memset?
>
Sure, let's go with that! :)
-eric
>>
>> + collectAttributes(Die, Attrs);
>> + hashAttributes(Attrs);
>> +}
>> +
>> +// 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.
>> +void DIEHash::computeHash(DIE *Die) {
>> +
>> + // Append the letter 'D', followed by the DWARF tag of the DIE.
>> + addULEB128('D');
>> + addULEB128(Die->getTag());
>> +
>> + // Add each of the attributes of the DIE.
>> + addAttributes(Die);
>> +
>> + // Then hash each of the children of the DIE.
>> + for (std::vector<DIE *>::const_iterator I = Die->getChildren().begin(),
>> + E = Die->getChildren().end();
>> + I != E; ++I)
>> + computeHash(*I);
>> +}
>> +
>> /// 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
>> /// with the exception that we are hashing only the context and the name
>> of the
>> @@ -129,6 +215,24 @@ uint64_t DIEHash::computeDIEODRSignature
>> MD5::MD5Result Result;
>> Hash.final(Result);
>>
>> + // ... take the least significant 8 bytes and return those. Our MD5
>> + // implementation always returns its results in little endian, swap
>> bytes
>> + // appropriately.
>> + return *reinterpret_cast<support::ulittle64_t *>(Result + 8);
>> +}
>> +
>> +/// This is based on the type signature computation given in section 7.27
>> of the
>> +/// DWARF4 standard. It is an md5 hash of the flattened description of
>> the DIE
>> +/// with the inclusion of the full CU and all top level CU entities.
>> +uint64_t DIEHash::computeCUSignature(DIE *Die) {
>> +
>> + // Hash the DIE.
>> + computeHash(Die);
>> +
>> + // Now return the result.
>> + MD5::MD5Result Result;
>> + Hash.final(Result);
>> +
>> // ... take the least significant 8 bytes and return those. Our MD5
>> // implementation always returns its results in little endian, swap
>> bytes
>> // appropriately.
>>
>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.h?rev=188243&r1=188242&r2=188243&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.h (original)
>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.h Mon Aug 12 20:21:55 2013
>> @@ -20,15 +20,35 @@ class CompileUnit;
>> /// \brief An object containing the capability of hashing and adding hash
>> /// attributes onto a DIE.
>> class DIEHash {
>> + // The entry for a particular attribute.
>> + struct AttrEntry {
>> + const DIEValue *Val;
>> + const DIEAbbrevData *Desc;
>> + };
>> +
>> + // Collection of all attributes used in hashing a particular DIE.
>> + struct DIEAttrs {
>> + AttrEntry DW_AT_name;
>> + };
>> +
>> public:
>> /// \brief Computes the ODR signature
>> uint64_t computeDIEODRSignature(DIE *Die);
>>
>> + /// \brief Computes the CU signature
>> + uint64_t computeCUSignature(DIE *Die);
>> +
>> // Helper routines to process parts of a DIE.
>> - private:
>> +private:
>> /// \brief Adds the parent context of \param Die to the hash.
>> void addParentContext(DIE *Die);
>> -
>> +
>> + /// \brief Adds the attributes of \param Die to the hash.
>> + void addAttributes(DIE *Die);
>> +
>> + /// \brief Computes the full DWARF4 7.27 hash of the DIE.
>> + void computeHash(DIE *Die);
>> +
>> // Routines that add DIEValues to the hash.
>> private:
>> /// \brief Encodes and adds \param Value to the hash as a ULEB128.
>> @@ -36,7 +56,17 @@ private:
>>
>> /// \brief Adds \param Str to the hash and includes a NULL byte.
>> void addString(StringRef Str);
>> -
>> +
>> + /// \brief Collects the attributes of DIE \param Die into the \param
>> Attrs
>> + /// structure.
>> + void collectAttributes(DIE *Die, DIEAttrs Attrs);
>> +
>> + /// \brief Hashes the attributes in \param Attrs in order.
>> + void hashAttributes(DIEAttrs Attrs);
>> +
>> + /// \brief Hashes an individual attribute.
>> + void hashAttribute(AttrEntry Attr);
>> +
>> private:
>> MD5 Hash;
>> };
>>
>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=188243&r1=188242&r2=188243&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Aug 12 20:21:55
>> 2013
>> @@ -67,6 +67,11 @@ GenerateODRHash("generate-odr-hash", cl:
>> cl::desc("Add an ODR hash to external type DIEs."),
>> cl::init(false));
>>
>> +static cl::opt<bool>
>> +GenerateCUHash("generate-cu-hash", cl::Hidden,
>> + cl::desc("Add the CU hash as the dwo_id."),
>> + cl::init(false));
>> +
>> namespace {
>> enum DefaultOnOff {
>> Default,
>> @@ -1024,14 +1029,19 @@ void DwarfDebug::finalizeModuleInfo() {
>> // If we're splitting the dwarf out now that we've got the entire
>> // CU then construct a skeleton CU based upon it.
>> if (useSplitDwarf()) {
>> + uint64_t ID = 0;
>> + if (GenerateCUHash) {
>> + DIEHash CUHash;
>> + ID = CUHash.computeCUSignature(TheCU->getCUDie());
>> + }
>> // This should be a unique identifier when we want to build .dwp
>> files.
>> TheCU->addUInt(TheCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id,
>> - dwarf::DW_FORM_data8, 0);
>> + dwarf::DW_FORM_data8, ID);
>> // Now construct the skeleton CU associated.
>> CompileUnit *SkCU = constructSkeletonCU(CUI->first);
>> // This should be a unique identifier when we want to build .dwp
>> files.
>> SkCU->addUInt(SkCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id,
>> - dwarf::DW_FORM_data8, 0);
>> + dwarf::DW_FORM_data8, ID);
>> }
>> }
>>
>>
>> Added: llvm/trunk/test/DebugInfo/X86/fission-hash.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/fission-hash.ll?rev=188243&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/X86/fission-hash.ll (added)
>> +++ llvm/trunk/test/DebugInfo/X86/fission-hash.ll Mon Aug 12 20:21:55 2013
>> @@ -0,0 +1,15 @@
>> +; 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
>> +
>> +; The source is an empty file.
>> +
>> +; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x356a7d50a77f5177)
>> +; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x356a7d50a77f5177)
>> +
>> +!llvm.dbg.cu = !{!0}
>> +!llvm.module.flags = !{!3}
>> +
>> +!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version
>> 3.4 (trunk 188230) (llvm/trunk 188234)", i1 false, metadata !"", i32 0,
>> metadata !2, metadata !2, metadata !2, metadata !2, metadata !2, metadata
>> !"foo.dwo"} ; [ DW_TAG_compile_unit ]
>> [/usr/local/google/home/echristo/tmp/foo.c] [DW_LANG_C99]
>> +!1 = metadata !{metadata !"foo.c", metadata
>> !"/usr/local/google/home/echristo/tmp"}
>> +!2 = metadata !{i32 0}
>> +!3 = metadata !{i32 2, metadata !"Dwarf Version", i32 3}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
More information about the llvm-commits
mailing list