Pack MCSymbol::HasName in to a spare bit in the section/fragment union.

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
This commit is contained in:
Pete Cooper 2015-06-30 20:54:21 +00:00
parent 28a83187a2
commit 8cdbab9dd6
2 changed files with 23 additions and 19 deletions

View File

@ -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<MCSection *, MCFragment *> 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<PointerUnion<MCSection *, MCFragment *>, 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<bool> *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<MCFragment *>() && "Section or null expected");
MCSection *Section = SectionOrFragment.dyn_cast<MCSection *>();
if (Section || !isVariable())
@ -185,7 +187,7 @@ private:
/// \brief Get a reference to the name field. Requires that we have a name
const StringMapEntry<bool> *&getNameEntryPtr() {
assert(HasName && "Name is required");
assert(SectionOrFragmentAndHasName.getInt() && "Name is required");
NameEntryStorageTy *Name = reinterpret_cast<NameEntryStorageTy *>(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<MCFragment *>() && "Section or null expected");
SectionOrFragment = &S;
assert(!SectionOrFragmentAndHasName.getPointer().is<MCFragment *>() &&
"Section or null expected");
SectionOrFragmentAndHasName.setPointer(&S);
}
/// Mark the symbol as undefined.
void setUndefined() {
SectionOrFragment = nullptr;
SectionOrFragmentAndHasName.setPointer(
PointerUnion<MCSection *, MCFragment *>());
}
bool isELF() const { return Kind == SymbolKindELF; }
@ -365,10 +369,10 @@ public:
}
MCFragment *getFragment() const {
return SectionOrFragment.dyn_cast<MCFragment *>();
return SectionOrFragmentAndHasName.getPointer().dyn_cast<MCFragment *>();
}
void setFragment(MCFragment *Value) const {
SectionOrFragment = Value;
SectionOrFragmentAndHasName.setPointer(Value);
}
bool isExternal() const { return IsExternal; }

View File

@ -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 {