From 8cdbab9dd653560218f872244c23b7cab2fa6451 Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Tue, 30 Jun 2015 20:54:21 +0000 Subject: [PATCH] Pack MCSymbol::HasName in to a spare bit in the section/fragment union. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is part of an effort to pack the average MCSymbol down to 24 bytes. The HasName bit was pushing the size of the bitfield over to another word, so this change uses a PointerIntPair to fit in it to unused bits of a PointerUnion. Reviewed by Rafael EspĂ­ndola git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241115 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCSymbol.h | 40 +++++++++++++++++++++----------------- lib/MC/MCSymbol.cpp | 2 +- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index a62f87f0354..48b50d9ada1 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -14,6 +14,7 @@ #ifndef LLVM_MC_MCSYMBOL_H #define LLVM_MC_MCSYMBOL_H +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringMap.h" #include "llvm/MC/MCAssembler.h" @@ -71,7 +72,12 @@ protected: /// /// If this is a fragment, then it gives the fragment this symbol's value is /// relative to, if any. - mutable PointerUnion SectionOrFragment; + /// + /// For the 'HasName' integer, this is true if this symbol is named. + /// A named symbol will have a pointer to the name allocated in the bytes + /// immediately prior to the MCSymbol. + mutable PointerIntPair, 1> + SectionOrFragmentAndHasName; /// IsTemporary - True if this is an assembler temporary label, which /// typically does not survive in the .o file's symbol table. Usually @@ -92,11 +98,6 @@ protected: /// This symbol is private extern. mutable unsigned IsPrivateExtern : 1; - /// True if this symbol is named. - /// A named symbol will have a pointer to the name allocated in the bytes - /// immediately prior to the MCSymbol. - unsigned HasName : 1; - /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is /// unsigned to avoid sign extension and achieve better bitpacking with MSVC. unsigned Kind : 2; @@ -145,11 +146,11 @@ protected: // MCContext creates and uniques these. } NameEntryStorageTy; MCSymbol(SymbolKind Kind, const StringMapEntry *Name, bool isTemporary) - : IsTemporary(isTemporary), IsRedefinable(false), - IsUsed(false), IsRegistered(false), IsExternal(false), - IsPrivateExtern(false), HasName(!!Name), Kind(Kind), - IsUsedInReloc(false), SymbolContents(SymContentsUnset) { + : IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false), + IsRegistered(false), IsExternal(false), IsPrivateExtern(false), + Kind(Kind), IsUsedInReloc(false), SymbolContents(SymContentsUnset) { Offset = 0; + SectionOrFragmentAndHasName.setInt(!!Name); if (Name) getNameEntryPtr() = Name; } @@ -176,6 +177,7 @@ private: MCSection *getSectionPtr() const { if (MCFragment *F = getFragment()) return F->getParent(); + const auto &SectionOrFragment = SectionOrFragmentAndHasName.getPointer(); assert(!SectionOrFragment.is() && "Section or null expected"); MCSection *Section = SectionOrFragment.dyn_cast(); if (Section || !isVariable()) @@ -185,7 +187,7 @@ private: /// \brief Get a reference to the name field. Requires that we have a name const StringMapEntry *&getNameEntryPtr() { - assert(HasName && "Name is required"); + assert(SectionOrFragmentAndHasName.getInt() && "Name is required"); NameEntryStorageTy *Name = reinterpret_cast(this); return (*(Name - 1)).NameEntry; } @@ -196,7 +198,7 @@ private: public: /// getName - Get the symbol name. StringRef getName() const { - if (!HasName) + if (!SectionOrFragmentAndHasName.getInt()) return StringRef(); return getNameEntryPtr()->first(); @@ -229,7 +231,7 @@ public: Value = nullptr; SymbolContents = SymContentsUnset; } - SectionOrFragment = nullptr; + setUndefined(); IsRedefinable = false; } } @@ -262,13 +264,15 @@ public: /// Mark the symbol as defined in the section \p S. void setSection(MCSection &S) { assert(!isVariable() && "Cannot set section of variable"); - assert(!SectionOrFragment.is() && "Section or null expected"); - SectionOrFragment = &S; + assert(!SectionOrFragmentAndHasName.getPointer().is() && + "Section or null expected"); + SectionOrFragmentAndHasName.setPointer(&S); } /// Mark the symbol as undefined. void setUndefined() { - SectionOrFragment = nullptr; + SectionOrFragmentAndHasName.setPointer( + PointerUnion()); } bool isELF() const { return Kind == SymbolKindELF; } @@ -365,10 +369,10 @@ public: } MCFragment *getFragment() const { - return SectionOrFragment.dyn_cast(); + return SectionOrFragmentAndHasName.getPointer().dyn_cast(); } void setFragment(MCFragment *Value) const { - SectionOrFragment = Value; + SectionOrFragmentAndHasName.setPointer(Value); } bool isExternal() const { return IsExternal; } diff --git a/lib/MC/MCSymbol.cpp b/lib/MC/MCSymbol.cpp index bbd34f15740..125380a9d14 100644 --- a/lib/MC/MCSymbol.cpp +++ b/lib/MC/MCSymbol.cpp @@ -45,7 +45,7 @@ void MCSymbol::setVariableValue(const MCExpr *Value) { "Cannot give common/offset symbol a variable value"); this->Value = Value; SymbolContents = SymContentsVariable; - SectionOrFragment = nullptr; + setUndefined(); } void MCSymbol::print(raw_ostream &OS, const MCAsmInfo *MAI) const {