From: Rafael Espindola Date: Mon, 1 Jun 2015 14:34:40 +0000 (+0000) Subject: The fragment implies the section, don't store both. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=ba9e3285d0f2e82cd2ebedc5287d09c295c94f5c;p=oota-llvm.git The fragment implies the section, don't store both. This reduces MCSymbol from 64 to 56 bytes on x86_64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238747 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index d335db92d0c..a6178c214d4 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -23,7 +23,6 @@ #include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include @@ -910,15 +909,7 @@ public: return true; } - void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr) { - bool New = !Symbol.isRegistered(); - if (Created) - *Created = New; - if (New) { - Symbol.setIsRegistered(true); - Symbols.push_back(&Symbol); - } - } + void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr); ArrayRef getFileNames() { return FileNames; } diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 3194ed1863b..68c2d99a904 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -14,8 +14,8 @@ #ifndef LLVM_MC_MCSYMBOL_H #define LLVM_MC_MCSYMBOL_H -#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringMap.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCExpr.h" #include "llvm/Support/Compiler.h" @@ -44,10 +44,20 @@ class MCSymbol { /// held by the StringMap that lives in MCContext. const StringMapEntry *Name; - /// The section the symbol is defined in. This is null for undefined symbols, - /// and the special AbsolutePseudoSection value for absolute symbols. If this - /// is a variable symbol, this caches the variable value's section. - mutable MCSection *Section; + /// If a symbol has a Fragment, the section is implied, so we only need + /// one pointer. + /// FIXME: We might be able to simplify this by having the asm streamer create + /// dummy fragments. + union { + /// The section the symbol is defined in. This is null for undefined + /// symbols, and the special AbsolutePseudoSection value for absolute + /// symbols. If this is a variable symbol, this caches the variable value's + /// section. + mutable MCSection *Section; + + /// The fragment this symbol's value is relative to, if any. + mutable MCFragment *Fragment; + }; /// Value - If non-null, the value for a variable symbol. const MCExpr *Value; @@ -65,6 +75,14 @@ class MCSymbol { mutable bool IsRegistered : 1; + /// This symbol is visible outside this translation unit. + mutable unsigned IsExternal : 1; + + /// This symbol is private extern. + mutable unsigned IsPrivateExtern : 1; + + mutable unsigned HasFragment : 1; + /// Index field, for use by the object file implementation. mutable uint32_t Index = 0; @@ -89,23 +107,22 @@ class MCSymbol { /// additional per symbol information which is not easily classified. mutable uint32_t Flags = 0; - /// The fragment this symbol's value is relative to, if any. Also stores if - /// this symbol is visible outside this translation unit (bit 0) or if it is - /// private extern (bit 1). - mutable PointerIntPair Fragment; - private: // MCContext creates and uniques these. friend class MCExpr; friend class MCContext; MCSymbol(const StringMapEntry *Name, bool isTemporary) : Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary), - IsRedefinable(false), IsUsed(false), IsRegistered(false) { + IsRedefinable(false), IsUsed(false), IsRegistered(false), + IsExternal(false), IsPrivateExtern(false), HasFragment(false) { Offset = 0; } MCSymbol(const MCSymbol &) = delete; void operator=(const MCSymbol &) = delete; MCSection *getSectionPtr() const { + if (MCFragment *F = getFragment()) + return F->getParent(); + assert(!HasFragment); if (Section || !Value) return Section; return Section = Value->findAssociatedSection(); @@ -137,6 +154,7 @@ public: if (IsRedefinable) { Value = nullptr; Section = nullptr; + HasFragment = false; IsRedefinable = false; } } @@ -169,11 +187,15 @@ public: /// Mark the symbol as defined in the section \p S. void setSection(MCSection &S) { assert(!isVariable() && "Cannot set section of variable"); + assert(!HasFragment); Section = &S; } - /// setUndefined - Mark the symbol as undefined. - void setUndefined() { Section = nullptr; } + /// Mark the symbol as undefined. + void setUndefined() { + HasFragment = false; + Section = nullptr; + } /// @} /// \name Variable Symbols @@ -252,19 +274,22 @@ public: Flags = (Flags & ~Mask) | Value; } - MCFragment *getFragment() const { return Fragment.getPointer(); } - void setFragment(MCFragment *Value) const { Fragment.setPointer(Value); } - - bool isExternal() const { return Fragment.getInt() & 1; } - void setExternal(bool Value) const { - Fragment.setInt((Fragment.getInt() & ~1) | unsigned(Value)); + MCFragment *getFragment() const { + if (!HasFragment) + return nullptr; + return Fragment; } - - bool isPrivateExtern() const { return Fragment.getInt() & 2; } - void setPrivateExtern(bool Value) { - Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1)); + void setFragment(MCFragment *Value) const { + HasFragment = true; + Fragment = Value; } + bool isExternal() const { return IsExternal; } + void setExternal(bool Value) const { IsExternal = Value; } + + bool isPrivateExtern() const { return IsPrivateExtern; } + void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } + /// print - Print the value to the stream \p OS. void print(raw_ostream &OS) const; diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 7f09e748eb1..087caae59c4 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -579,6 +579,16 @@ static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) { OW->WriteBytes(EF.getContents()); } +void MCAssembler::registerSymbol(const MCSymbol &Symbol, bool *Created) { + bool New = !Symbol.isRegistered(); + if (Created) + *Created = New; + if (New) { + Symbol.setIsRegistered(true); + Symbols.push_back(&Symbol); + } +} + void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize, MCObjectWriter *OW) const { // Should NOP padding be written out before this fragment? diff --git a/lib/MC/MCELF.cpp b/lib/MC/MCELF.cpp index 2d27994428f..8d7fbf25549 100644 --- a/lib/MC/MCELF.cpp +++ b/lib/MC/MCELF.cpp @@ -13,6 +13,7 @@ #include "llvm/MC/MCELF.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/Support/ELF.h" diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 74ec6a8fe26..ff4b391789f 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -419,11 +419,11 @@ void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, if (ByteAlignment != 1) new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, Section); + AssignSection(Symbol, Section); + MCFragment *F = new MCFillFragment(0, 0, Size, Section); Symbol->setFragment(F); - AssignSection(Symbol, Section); - // Update the maximum alignment on the zero fill section if necessary. if (ByteAlignment > Section->getAlignment()) Section->setAlignment(ByteAlignment); diff --git a/lib/MC/MCSymbol.cpp b/lib/MC/MCSymbol.cpp index ddc381407df..35208eb0466 100644 --- a/lib/MC/MCSymbol.cpp +++ b/lib/MC/MCSymbol.cpp @@ -42,7 +42,8 @@ void MCSymbol::setVariableValue(const MCExpr *Value) { assert(!IsUsed && "Cannot set a variable that has already been used."); assert(Value && "Invalid variable value!"); this->Value = Value; - this->Section = nullptr; + Section = nullptr; + HasFragment = false; } void MCSymbol::print(raw_ostream &OS) const {