From 6109b51ef1ef92ff9f11b07f954943c2262c7a11 Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Tue, 9 Jun 2015 22:21:37 +0000 Subject: [PATCH] Move MCSymbol Value in to the union of Offset and CommonSize. It wasn't possible to have a variable Symbol with offset or 'isCommon' so this just enables better packing of the MCSymbol class. Reviewed by Rafael Espindola. llvm-svn: 239440 --- llvm/include/llvm/MC/MCSymbol.h | 48 ++++++++++++++++++++++++++++++----------- llvm/lib/MC/MCSymbol.cpp | 4 ++++ 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/llvm/include/llvm/MC/MCSymbol.h b/llvm/include/llvm/MC/MCSymbol.h index 78b7c51..8bf949a 100644 --- a/llvm/include/llvm/MC/MCSymbol.h +++ b/llvm/include/llvm/MC/MCSymbol.h @@ -65,9 +65,6 @@ protected: /// relative to, if any. mutable PointerUnion SectionOrFragment; - /// Value - If non-null, the value for a variable symbol. - const MCExpr *Value; - /// IsTemporary - True if this is an assembler temporary label, which /// typically does not survive in the .o file's symbol table. Usually /// "Lfoo" or ".foo". @@ -96,6 +93,17 @@ protected: /// unsigned to avoid sign extension and achieve better bitpacking with MSVC. unsigned Kind : 2; + /// A symbol can contain an Offset, or Value, or be Common, but never more + /// than one of these. + enum Contents : uint8_t { + SymContentsUnset, + SymContentsOffset, + SymContentsVariable, + SymContentsCommon, + }; + + Contents SymbolContents : 2; + /// Index field, for use by the object file implementation. mutable uint32_t Index = 0; @@ -105,6 +113,9 @@ protected: /// The size of the symbol, if it is 'common'. uint64_t CommonSize; + + /// If non-null, the value for a variable symbol. + const MCExpr *Value; }; /// The alignment of the symbol, if it is 'common', or -1. @@ -130,10 +141,10 @@ protected: // MCContext creates and uniques these. } NameEntryStorageTy; MCSymbol(SymbolKind Kind, const StringMapEntry *Name, bool isTemporary) - : Value(nullptr), IsTemporary(isTemporary), + : IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false), IsRegistered(false), IsExternal(false), IsPrivateExtern(false), HasName(!!Name), - Kind(Kind) { + Kind(Kind), SymbolContents(SymContentsUnset) { Offset = 0; if (Name) getNameEntryPtr() = Name; @@ -163,9 +174,9 @@ private: return F->getParent(); assert(!SectionOrFragment.is() && "Section or null expected"); MCSection *Section = SectionOrFragment.dyn_cast(); - if (Section || !Value) + if (Section || !isVariable()) return Section; - return Section = Value->findAssociatedSection(); + return Section = getVariableValue()->findAssociatedSection(); } /// \brief Get a reference to the name field. Requires that we have a name @@ -207,7 +218,10 @@ public: /// \brief Prepare this symbol to be redefined. void redefineIfPossible() { if (IsRedefinable) { - Value = nullptr; + if (SymbolContents == SymContentsVariable) { + Value = nullptr; + SymbolContents = SymContentsUnset; + } SectionOrFragment = nullptr; IsRedefinable = false; } @@ -261,7 +275,9 @@ public: /// @{ /// isVariable - Check if this is a variable symbol. - bool isVariable() const { return Value != nullptr; } + bool isVariable() const { + return SymbolContents == SymContentsVariable; + } /// getVariableValue() - Get the value for variable symbols. const MCExpr *getVariableValue() const { @@ -285,12 +301,17 @@ public: } uint64_t getOffset() const { - assert(!isCommon()); + assert((SymbolContents == SymContentsUnset || + SymbolContents == SymContentsOffset) && + "Cannot get offset for a common/variable symbol"); return Offset; } void setOffset(uint64_t Value) { - assert(!isCommon()); + assert((SymbolContents == SymContentsUnset || + SymbolContents == SymContentsOffset) && + "Cannot set offset for a common/variable symbol"); Offset = Value; + SymbolContents = SymContentsOffset; } /// Return the size of a 'common' symbol. @@ -307,6 +328,7 @@ public: assert(getOffset() == 0); CommonSize = Size; CommonAlign = Align; + SymbolContents = SymContentsCommon; } /// Return the alignment of a 'common' symbol. @@ -331,7 +353,9 @@ public: } /// Is this a 'common' symbol. - bool isCommon() const { return CommonAlign != -1U; } + bool isCommon() const { + return SymbolContents == SymContentsCommon; + } MCFragment *getFragment() const { return SectionOrFragment.dyn_cast(); diff --git a/llvm/lib/MC/MCSymbol.cpp b/llvm/lib/MC/MCSymbol.cpp index 836d282..9ca85b0 100644 --- a/llvm/lib/MC/MCSymbol.cpp +++ b/llvm/lib/MC/MCSymbol.cpp @@ -40,7 +40,11 @@ void *MCSymbol::operator new(size_t s, const StringMapEntry *Name, void MCSymbol::setVariableValue(const MCExpr *Value) { assert(!IsUsed && "Cannot set a variable that has already been used."); assert(Value && "Invalid variable value!"); + assert((SymbolContents == SymContentsUnset || + SymbolContents == SymContentsVariable) && + "Cannot give common/offset symbol a variable value"); this->Value = Value; + SymbolContents = SymContentsVariable; SectionOrFragment = nullptr; } -- 2.7.4