[llvm] r188243 - Add the start of DIE hashing for DWARF4 type units and split dwarf
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Tue Aug 13 00:34:36 PDT 2013
On Tue, Aug 13, 2013 at 5:21 AM, 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) {
I wonder if you meant to pass Attrs by reference?
Otherwise this function does not seem to be doing anything useful.
> + 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));
> + 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