mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-16 14:31:59 +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.
|
// Accessors.
|
||||||
DIEAbbrev &getAbbrev() { return Abbrev; }
|
DIEAbbrev &getAbbrev() { return Abbrev; }
|
||||||
|
const DIEAbbrev &getAbbrev() const { return Abbrev; }
|
||||||
unsigned getAbbrevNumber() const { return Abbrev.getNumber(); }
|
unsigned getAbbrevNumber() const { return Abbrev.getNumber(); }
|
||||||
dwarf::Tag getTag() const { return Abbrev.getTag(); }
|
dwarf::Tag getTag() const { return Abbrev.getTag(); }
|
||||||
unsigned getOffset() const { return Offset; }
|
unsigned getOffset() const { return Offset; }
|
||||||
|
@ -28,9 +28,9 @@ using namespace llvm;
|
|||||||
|
|
||||||
/// \brief Grabs the string in whichever attribute is passed in and returns
|
/// \brief Grabs the string in whichever attribute is passed in and returns
|
||||||
/// a reference to it.
|
/// a reference to it.
|
||||||
static StringRef getDIEStringAttr(DIE *Die, uint16_t Attr) {
|
static StringRef getDIEStringAttr(const DIE &Die, uint16_t Attr) {
|
||||||
const SmallVectorImpl<DIEValue *> &Values = Die->getValues();
|
const SmallVectorImpl<DIEValue *> &Values = Die.getValues();
|
||||||
const DIEAbbrev &Abbrevs = Die->getAbbrev();
|
const DIEAbbrev &Abbrevs = Die.getAbbrev();
|
||||||
|
|
||||||
// Iterate through all the attributes until we find the one we're
|
// Iterate through all the attributes until we find the one we're
|
||||||
// looking for, if we can't find it return an empty string.
|
// looking for, if we can't find it return an empty string.
|
||||||
@ -109,7 +109,7 @@ void DIEHash::addParentContext(DIE *Parent) {
|
|||||||
addULEB128(Die->getTag());
|
addULEB128(Die->getTag());
|
||||||
|
|
||||||
// ... Then the name, taken from the DW_AT_name attribute.
|
// ... 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");
|
DEBUG(dbgs() << "... adding context: " << Name << "\n");
|
||||||
if (!Name.empty())
|
if (!Name.empty())
|
||||||
addString(Name);
|
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
|
// Hash an individual attribute \param Attr based on the type of attribute and
|
||||||
// the form.
|
// the form.
|
||||||
void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) {
|
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
|
// ... An attribute that refers to another type entry T is processed as
|
||||||
// follows:
|
// follows:
|
||||||
if (const DIEEntry *EntryAttr = dyn_cast<DIEEntry>(Value)) {
|
if (const DIEEntry *EntryAttr = dyn_cast<DIEEntry>(Value)) {
|
||||||
DIE *Entry = EntryAttr->getEntry();
|
hashDIEEntry(Attribute, Tag, *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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +423,7 @@ uint64_t DIEHash::computeDIEODRSignature(DIE *Die) {
|
|||||||
addULEB128(Die->getTag());
|
addULEB128(Die->getTag());
|
||||||
|
|
||||||
// Add the name of the type to the hash.
|
// 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.
|
// Now get the result.
|
||||||
MD5::MD5Result Result;
|
MD5::MD5Result Result;
|
||||||
|
@ -124,6 +124,19 @@ private:
|
|||||||
/// \brief Hashes an individual attribute.
|
/// \brief Hashes an individual attribute.
|
||||||
void hashAttribute(AttrEntry Attr, dwarf::Tag Tag);
|
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:
|
private:
|
||||||
MD5 Hash;
|
MD5 Hash;
|
||||||
DenseMap<DIE*, unsigned> Numbering;
|
DenseMap<DIE*, unsigned> Numbering;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user