summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2013-10-24 17:51:43 +0000
committerDavid Blaikie <dblaikie@gmail.com>2013-10-24 17:51:43 +0000
commit851aa948cb7fa379c9e674ae1cfe7276dd9ab171 (patch)
tree62de58da06cee845508d4bdf8fd9709bbbdbb4c8 /lib
parent724452e94c0bdbcd45a95f62b21c5a06632f38eb (diff)
downloadllvm-851aa948cb7fa379c9e674ae1cfe7276dd9ab171.tar.gz
llvm-851aa948cb7fa379c9e674ae1cfe7276dd9ab171.tar.bz2
llvm-851aa948cb7fa379c9e674ae1cfe7276dd9ab171.tar.xz
DIEHash: Refactor ref attribute hashing into smaller functions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193360 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.h1
-rw-r--r--lib/CodeGen/AsmPrinter/DIEHash.cpp152
-rw-r--r--lib/CodeGen/AsmPrinter/DIEHash.h13
3 files changed, 98 insertions, 68 deletions
diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h
index 51773ad9fe..6d4f305c84 100644
--- a/lib/CodeGen/AsmPrinter/DIE.h
+++ b/lib/CodeGen/AsmPrinter/DIE.h
@@ -138,6 +138,7 @@ namespace llvm {
// Accessors.
DIEAbbrev &getAbbrev() { return Abbrev; }
+ const DIEAbbrev &getAbbrev() const { return Abbrev; }
unsigned getAbbrevNumber() const { return Abbrev.getNumber(); }
dwarf::Tag getTag() const { return Abbrev.getTag(); }
unsigned getOffset() const { return Offset; }
diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp
index ea5cbad346..34d9fffb1a 100644
--- a/lib/CodeGen/AsmPrinter/DIEHash.cpp
+++ b/lib/CodeGen/AsmPrinter/DIEHash.cpp
@@ -28,9 +28,9 @@ using namespace llvm;
/// \brief Grabs the string in whichever attribute is passed in and returns
/// a reference to it.
-static StringRef getDIEStringAttr(DIE *Die, uint16_t Attr) {
- const SmallVectorImpl<DIEValue *> &Values = Die->getValues();
- const DIEAbbrev &Abbrevs = Die->getAbbrev();
+static StringRef getDIEStringAttr(const DIE &Die, uint16_t Attr) {
+ const SmallVectorImpl<DIEValue *> &Values = Die.getValues();
+ const DIEAbbrev &Abbrevs = Die.getAbbrev();
// Iterate through all the attributes until we find the one we're
// looking for, if we can't find it return an empty string.
@@ -109,7 +109,7 @@ void DIEHash::addParentContext(DIE *Parent) {
addULEB128(Die->getTag());
// ... Then the name, taken from the DW_AT_name attribute.
- StringRef Name = getDIEStringAttr(Die, dwarf::DW_AT_name);
+ StringRef Name = getDIEStringAttr(*Die, dwarf::DW_AT_name);
DEBUG(dbgs() << "... adding context: " << Name << "\n");
if (!Name.empty())
addString(Name);
@@ -187,6 +187,84 @@ void DIEHash::collectAttributes(DIE *Die, DIEAttrs &Attrs) {
}
}
+void DIEHash::hashShallowTypeReference(dwarf::Attribute Attribute,
+ const DIE &Entry, StringRef Name) {
+ // append the letter 'N'
+ addULEB128('N');
+
+ // the DWARF attribute code (DW_AT_type or DW_AT_friend),
+ addULEB128(Attribute);
+
+ // the context of the tag,
+ if (DIE *Parent = Entry.getParent())
+ addParentContext(Parent);
+
+ // the letter 'E',
+ addULEB128('E');
+
+ // and the name of the type.
+ addString(Name);
+
+ // Currently DW_TAG_friends are not used by Clang, but if they do become so,
+ // here's the relevant spec text to implement:
+ //
+ // 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).
+}
+
+void DIEHash::hashRepeatedTypeReference(dwarf::Attribute Attribute,
+ unsigned DieNumber) {
+ // a) If T is in the list of [previously hashed types], use the letter
+ // 'R' as the marker
+ addULEB128('R');
+
+ addULEB128(Attribute);
+
+ // and use the unsigned LEB128 encoding of [the index of T in the
+ // list] as the attribute value;
+ addULEB128(DieNumber);
+}
+
+void DIEHash::hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag,
+ DIE &Entry) {
+ assert(Tag != dwarf::DW_TAG_friend && "No current LLVM clients emit friend "
+ "tags. Add support here when there's "
+ "a use case");
+ // Step 5
+ // If the tag in Step 3 is one of [the below tags]
+ if ((Tag == dwarf::DW_TAG_pointer_type ||
+ Tag == dwarf::DW_TAG_reference_type ||
+ Tag == dwarf::DW_TAG_rvalue_reference_type ||
+ Tag == dwarf::DW_TAG_ptr_to_member_type) &&
+ // and the referenced type (via the [below attributes])
+ // FIXME: This seems overly restrictive, and causes hash mismatches
+ // there's a decl/def difference in the containing type of a
+ // ptr_to_member_type, but it's what DWARF says, for some reason.
+ Attribute == dwarf::DW_AT_type) {
+ // [FIXME] ... has a DW_AT_name attribute,
+ hashShallowTypeReference(Attribute, Entry,
+ getDIEStringAttr(Entry, dwarf::DW_AT_name));
+ return;
+ }
+
+ unsigned &DieNumber = Numbering[&Entry];
+ if (DieNumber) {
+ hashRepeatedTypeReference(Attribute, DieNumber);
+ return;
+ }
+
+ // otherwise, b) use the letter 'T' as a the marker, ...
+ addULEB128('T');
+
+ addULEB128(Attribute);
+
+ // ... process the type T recursively by performing Steps 2 through 7, and
+ // use the result as the attribute value.
+ DieNumber = Numbering.size();
+ computeHash(&Entry);
+}
+
// Hash an individual attribute \param Attr based on the type of attribute and
// the form.
void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) {
@@ -198,69 +276,7 @@ void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) {
// ... 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();
-
- assert(Tag != dwarf::DW_TAG_friend && "No current LLVM clients emit friend "
- "tags. Add support here when there's "
- "a use case");
- // Step 5
- // If the tag in Step 3 is one of [the below tags]
- if ((Tag == dwarf::DW_TAG_pointer_type ||
- Tag == dwarf::DW_TAG_reference_type ||
- Tag == dwarf::DW_TAG_rvalue_reference_type ||
- Tag == dwarf::DW_TAG_ptr_to_member_type) &&
- // and the referenced type (via the [below attributes])
- // FIXME: This seems overly restrictive, and causes hash mismatches
- // there's a decl/def difference in the containing type of a
- // ptr_to_member_type.
- Attribute == dwarf::DW_AT_type) {
- // [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
- // 'R' as the marker
- addULEB128('R');
-
- addULEB128(Attribute);
-
- // and use the unsigned LEB128 encoding of [the index of T in the
- // list] as the attribute value;
- addULEB128(DieNumber);
- return;
- }
-
- // otherwise, b) use the letter 'T' as a the marker, ...
- addULEB128('T');
-
- addULEB128(Attribute);
-
- // ... process the type T recursively by performing Steps 2 through 7, and
- // use the result as the attribute value.
- DieNumber = Numbering.size();
- computeHash(Entry);
+ hashDIEEntry(Attribute, Tag, *EntryAttr->getEntry());
return;
}
@@ -407,7 +423,7 @@ uint64_t DIEHash::computeDIEODRSignature(DIE *Die) {
addULEB128(Die->getTag());
// Add the name of the type to the hash.
- addString(getDIEStringAttr(Die, dwarf::DW_AT_name));
+ addString(getDIEStringAttr(*Die, dwarf::DW_AT_name));
// Now get the result.
MD5::MD5Result Result;
diff --git a/lib/CodeGen/AsmPrinter/DIEHash.h b/lib/CodeGen/AsmPrinter/DIEHash.h
index a59df35a0d..2869ce7614 100644
--- a/lib/CodeGen/AsmPrinter/DIEHash.h
+++ b/lib/CodeGen/AsmPrinter/DIEHash.h
@@ -124,6 +124,19 @@ private:
/// \brief Hashes an individual attribute.
void hashAttribute(AttrEntry Attr, dwarf::Tag Tag);
+ /// \brief Hashes an attribute that refers to another DIE.
+ void hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag,
+ DIE &Entry);
+
+ /// \brief Hashes a reference to a named type in such a way that is
+ /// independent of whether that type is described by a declaration or a
+ /// definition.
+ void hashShallowTypeReference(dwarf::Attribute Attribute,
+ const DIE &Entry, StringRef Name);
+
+ /// \brief Hashes a reference to a previously referenced type DIE.
+ void hashRepeatedTypeReference(dwarf::Attribute Attribute, unsigned DieNumber);
+
private:
MD5 Hash;
DenseMap<DIE*, unsigned> Numbering;