summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2016-11-15 01:23:06 +0000
committerGreg Clayton <gclayton@apple.com>2016-11-15 01:23:06 +0000
commit6f6e4dbd5dacf9ec1c43921bad76d5a3b3ab67b0 (patch)
treeb5f1b457398183c51166e3fd02e934f1b08ef748 /llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
parentf83806a8adb4fdc7d785b66d48b42459f7874807 (diff)
downloadbcm5719-llvm-6f6e4dbd5dacf9ec1c43921bad76d5a3b3ab67b0.tar.gz
bcm5719-llvm-6f6e4dbd5dacf9ec1c43921bad76d5a3b3ab67b0.zip
Improve DWARF parsing speed by improving DWARFAbbreviationDeclaration
This patch gets a DWARF parsing speed improvement by having DWARFAbbreviationDeclaration instances know if they have a fixed byte size. If an abbreviation has a fixed byte size that can be calculated given a DWARFUnit, then parsing a DIE becomes two steps: parse ULEB128 abbrev code, and then add constant size to the offset. This patch also adds a fixed byte size to each DWARFAbbreviationDeclaration::AttributeSpec so that attributes can quickly skip their values if needed without the need to lookup the fixed for size. Notable improvements: - DWARFAbbreviationDeclaration::findAttributeIndex() now returns an Optional<uint32_t> instead of a uint32_t and we no longer have to look for the magic -1U return value - Optional<uint32_t> DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute attr) const; - DWARFAbbreviationDeclaration now has a getAttributeValue() function that extracts an attribute value given a DIE offset that takes advantage of the DWARFAbbreviationDeclaration::AttributeSpec::ByteSize - bool DWARFAbbreviationDeclaration::getAttributeValue(const uint32_t DIEOffset, const dwarf::Attribute Attr, const DWARFUnit &U, DWARFFormValue &FormValue) const; - A DWARFAbbreviationDeclaration instance can return a fixed byte size for itself so DWARF parsing is faster: - Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(const DWARFUnit &U) const; - Any functions that used to take a "const DWARFUnit *U" that would crash if U was NULL now take a "const DWARFUnit &U" and are only called with a valid DWARFUnit Differential Revision: https://reviews.llvm.org/D26567 llvm-svn: 286924
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp109
1 files changed, 104 insertions, 5 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
index 637d12ddd43..638830ee568 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -17,8 +19,10 @@ using namespace dwarf;
void DWARFAbbreviationDeclaration::clear() {
Code = 0;
Tag = DW_TAG_null;
+ CodeByteSize = 0;
HasChildren = false;
AttributeSpecs.clear();
+ FixedAttributeSize.reset();
}
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
@@ -29,10 +33,12 @@ bool
DWARFAbbreviationDeclaration::extract(DataExtractor Data,
uint32_t* OffsetPtr) {
clear();
+ const uint32_t Offset = *OffsetPtr;
Code = Data.getULEB128(OffsetPtr);
if (Code == 0) {
return false;
}
+ CodeByteSize = *OffsetPtr - Offset;
Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
if (Tag == DW_TAG_null) {
clear();
@@ -40,12 +46,52 @@ DWARFAbbreviationDeclaration::extract(DataExtractor Data,
}
uint8_t ChildrenByte = Data.getU8(OffsetPtr);
HasChildren = (ChildrenByte == DW_CHILDREN_yes);
+ // Assign a value to our optional FixedAttributeSize member variable. If
+ // this member variable still has a value after the while loop below, then
+ // all attribute data in this abbreviation declaration has a fixed byte size.
+ FixedAttributeSize = FixedSizeInfo();
+ // Read all of the abbreviation attributes and forms.
while (true) {
auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
if (A && F) {
- AttributeSpecs.push_back(AttributeSpec(A, F));
+ auto FixedFormByteSize = DWARFFormValue::getFixedByteSize(F);
+ AttributeSpecs.push_back(AttributeSpec(A, F, FixedFormByteSize));
+ // If this abbrevation still has a fixed byte size, then update the
+ // FixedAttributeSize as needed.
+ if (FixedAttributeSize) {
+ if (FixedFormByteSize)
+ FixedAttributeSize->NumBytes += *FixedFormByteSize;
+ else {
+ switch (F) {
+ case DW_FORM_addr:
+ ++FixedAttributeSize->NumAddrs;
+ break;
+
+ case DW_FORM_ref_addr:
+ ++FixedAttributeSize->NumRefAddrs;
+ break;
+
+ case DW_FORM_strp:
+ case DW_FORM_GNU_ref_alt:
+ case DW_FORM_GNU_strp_alt:
+ case DW_FORM_line_strp:
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp_sup:
+ case DW_FORM_ref_sup:
+ ++FixedAttributeSize->NumDwarfOffsets;
+ break;
+
+ default:
+ // Indicate we no longer have a fixed byte size for this
+ // abbreviation by clearing the FixedAttributeSize optional value
+ // so it doesn't have a value.
+ FixedAttributeSize.reset();
+ break;
+ }
+ }
+ }
} else if (A == 0 && F == 0) {
// We successfully reached the end of this abbreviation declaration
// since both attribute and form are zero.
@@ -88,11 +134,64 @@ void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
OS << '\n';
}
-uint32_t
-DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute attr) const {
+Optional<uint32_t>
+DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
- if (AttributeSpecs[i].Attr == attr)
+ if (AttributeSpecs[i].Attr == Attr)
return i;
}
- return -1U;
+ return None;
+}
+
+bool DWARFAbbreviationDeclaration::getAttributeValue(
+ const uint32_t DIEOffset, const dwarf::Attribute Attr, const DWARFUnit &U,
+ DWARFFormValue &FormValue) const {
+ Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
+ if (!MatchAttrIndex)
+ return false;
+
+ auto DebugInfoData = U.getDebugInfoExtractor();
+
+ // Add the byte size of ULEB that for the abbrev Code so we can start
+ // skipping the attribute data.
+ uint32_t Offset = DIEOffset + CodeByteSize;
+ uint32_t AttrIndex = 0;
+ for (const auto &Spec : AttributeSpecs) {
+ if (*MatchAttrIndex == AttrIndex) {
+ // We have arrived at the attribute to extract, extract if from Offset.
+ FormValue.setForm(Spec.Form);
+ return FormValue.extractValue(DebugInfoData, &Offset, &U);
+ }
+ // March Offset along until we get to the attribute we want.
+ if (Optional<uint8_t> FixedSize = Spec.getByteSize(U))
+ Offset += *FixedSize;
+ else
+ DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset, &U);
+ ++AttrIndex;
+ }
+ return false;
+}
+
+size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
+ const DWARFUnit &U) const {
+ size_t ByteSize = NumBytes;
+ if (NumAddrs)
+ ByteSize += NumAddrs * U.getAddressByteSize();
+ if (NumRefAddrs)
+ ByteSize += NumRefAddrs * U.getRefAddrByteSize();
+ if (NumDwarfOffsets)
+ ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
+ return ByteSize;
+}
+
+Optional<uint8_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
+ const DWARFUnit &U) const {
+ return ByteSize ? ByteSize : DWARFFormValue::getFixedByteSize(Form, &U);
+}
+
+Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
+ const DWARFUnit &U) const {
+ if (FixedAttributeSize)
+ return FixedAttributeSize->getByteSize(U);
+ return None;
}
OpenPOWER on IntegriCloud