mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
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 llvm-svn: 241115
This commit is contained in:
parent
2c003442f3
commit
3c754aaf59
@ -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; }
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user