mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
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
This commit is contained in:
parent
724452e94c
commit
851aa948cb
@ -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; }
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user