From 93b713bb17fee26d5ecbd8a2d659b78a2d9f06bb Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Thu, 21 Sep 2017 15:27:45 +0000 Subject: [PATCH] [DWARF] Shrink AttributeSpec from 24 to 16 bytes. This is a bit ugly because we can't put Optional into a union. Hide all of that behind a set of accessors and make accesses safer using asserts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313884 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../DWARF/DWARFAbbreviationDeclaration.h | 41 +++++++++++++++---- .../DWARF/DWARFAbbreviationDeclaration.cpp | 21 +++++----- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h index 190a69b7573..84b23398b8c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h @@ -28,31 +28,54 @@ class raw_ostream; class DWARFAbbreviationDeclaration { public: struct AttributeSpec { - AttributeSpec(dwarf::Attribute A, dwarf::Form F, Optional V) - : Attr(A), Form(F), ByteSizeOrValue(V) {} + AttributeSpec(dwarf::Attribute A, dwarf::Form F, int64_t Value) + : Attr(A), Form(F), Value(Value) { + assert(isImplicitConst()); + } + AttributeSpec(dwarf::Attribute A, dwarf::Form F, Optional ByteSize) + : Attr(A), Form(F) { + assert(!isImplicitConst()); + this->ByteSize.HasByteSize = ByteSize.hasValue(); + if (this->ByteSize.HasByteSize) + this->ByteSize.ByteSize = *ByteSize; + } dwarf::Attribute Attr; dwarf::Form Form; + private: /// The following field is used for ByteSize for non-implicit_const /// attributes and as value for implicit_const ones, indicated by /// Form == DW_FORM_implicit_const. /// The following cases are distinguished: - /// * Form != DW_FORM_implicit_const and ByteSizeOrValue has a value: - /// ByteSizeOrValue contains the fixed size in bytes - /// for the Form in this object. - /// * Form != DW_FORM_implicit_const and ByteSizeOrValue is None: + /// * Form != DW_FORM_implicit_const and HasByteSize is true: + /// ByteSize contains the fixed size in bytes for the Form in this + /// object. + /// * Form != DW_FORM_implicit_const and HasByteSize is false: /// byte size of Form either varies according to the DWARFUnit /// that it is contained in or the value size varies and must be /// decoded from the debug information in order to determine its size. /// * Form == DW_FORM_implicit_const: - /// ByteSizeOrValue contains value for the implicit_const attribute. - Optional ByteSizeOrValue; - + /// Value contains value for the implicit_const attribute. + struct ByteSizeStorage { + bool HasByteSize; + uint8_t ByteSize; + }; + union { + ByteSizeStorage ByteSize; + int64_t Value; + }; + + public: bool isImplicitConst() const { return Form == dwarf::DW_FORM_implicit_const; } + int64_t getImplicitConstValue() const { + assert(isImplicitConst()); + return Value; + } + /// Get the fixed byte size of this Form if possible. This function might /// use the DWARFUnit to calculate the size of the Form, like for /// DW_AT_address and DW_AT_ref_addr, so this isn't just an accessor for diff --git a/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp index bb475a669ef..a88dcfcf542 100644 --- a/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp @@ -63,13 +63,13 @@ DWARFAbbreviationDeclaration::extract(DataExtractor Data, auto A = static_cast(Data.getULEB128(OffsetPtr)); auto F = static_cast
(Data.getULEB128(OffsetPtr)); if (A && F) { - Optional V; bool IsImplicitConst = (F == DW_FORM_implicit_const); if (IsImplicitConst) { - V = Data.getSLEB128(OffsetPtr); + int64_t V = Data.getSLEB128(OffsetPtr); AttributeSpecs.push_back(AttributeSpec(A, F, V)); continue; } + Optional ByteSize; // If this abbrevation still has a fixed byte size, then update the // FixedAttributeSize as needed. switch (F) { @@ -96,11 +96,10 @@ DWARFAbbreviationDeclaration::extract(DataExtractor Data, default: // The form has a byte size that doesn't depend on Params. // If it's a fixed size, keep track of it. - if (auto Size = - DWARFFormValue::getFixedByteSize(F, DWARFFormParams())) { - V = *Size; + if ((ByteSize = + DWARFFormValue::getFixedByteSize(F, DWARFFormParams()))) { if (FixedAttributeSize) - FixedAttributeSize->NumBytes += *V; + FixedAttributeSize->NumBytes += *ByteSize; break; } // Indicate we no longer have a fixed byte size for this @@ -110,7 +109,7 @@ DWARFAbbreviationDeclaration::extract(DataExtractor Data, break; } // Record this attribute and its fixed size if it has one. - AttributeSpecs.push_back(AttributeSpec(A, F, V)); + AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize)); } else if (A == 0 && F == 0) { // We successfully reached the end of this abbreviation declaration // since both attribute and form are zero. @@ -149,7 +148,7 @@ void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const { else OS << format("DW_FORM_Unknown_%x", Spec.Form); if (Spec.isImplicitConst()) - OS << '\t' << *Spec.ByteSizeOrValue; + OS << '\t' << Spec.getImplicitConstValue(); OS << '\n'; } OS << '\n'; @@ -182,7 +181,7 @@ Optional DWARFAbbreviationDeclaration::getAttributeValue( // We have arrived at the attribute to extract, extract if from Offset. DWARFFormValue FormValue(Spec.Form); if (Spec.isImplicitConst()) { - FormValue.setSValue(*Spec.ByteSizeOrValue); + FormValue.setSValue(Spec.getImplicitConstValue()); return FormValue; } if (FormValue.extractValue(DebugInfoData, &Offset, &U)) @@ -215,8 +214,8 @@ Optional DWARFAbbreviationDeclaration::AttributeSpec::getByteSize( const DWARFUnit &U) const { if (isImplicitConst()) return 0; - if (ByteSizeOrValue) - return ByteSizeOrValue; + if (ByteSize.HasByteSize) + return ByteSize.ByteSize; Optional S; auto FixedByteSize = DWARFFormValue::getFixedByteSize(Form, U.getFormParams()); -- 2.40.0