Object: Shrink the size of irsymtab::Symbol by a word. NFCI.

Instead of storing an UncommonIndex on the Symbol, use a flag bit to store
whether the Symbol has an Uncommon. This shrinks Chromium's .bc files (after
D32061) by about 1%.

Differential Revision: https://reviews.llvm.org/D32070

llvm-svn: 300514
This commit is contained in:
Peter Collingbourne 2017-04-17 23:43:49 +00:00
parent a9b3d0975a
commit 76423dce15
2 changed files with 42 additions and 35 deletions

View File

@ -59,6 +59,9 @@ template <typename T> struct Range {
/// table.
struct Module {
Word Begin, End;
/// The index of the first Uncommon for this Module.
Word UncBegin;
};
/// This is equivalent to an IR comdat.
@ -82,7 +85,8 @@ struct Symbol {
Word Flags;
enum FlagBits {
FB_visibility, // 2 bits
FB_undefined = FB_visibility + 2,
FB_has_uncommon = FB_visibility + 2,
FB_undefined,
FB_weak,
FB_common,
FB_indirect,
@ -94,10 +98,6 @@ struct Symbol {
FB_unnamed_addr,
FB_executable,
};
/// The index into the Uncommon table, or -1 if this symbol does not have an
/// Uncommon.
Word UncommonIndex;
};
/// This data structure contains rarely used symbol fields and is optionally
@ -249,15 +249,9 @@ public:
/// Reader::module_symbols().
class Reader::SymbolRef : public Symbol {
const storage::Symbol *SymI, *SymE;
const storage::Uncommon *UncI;
const Reader *R;
public:
SymbolRef(const storage::Symbol *SymI, const storage::Symbol *SymE,
const Reader *R)
: SymI(SymI), SymE(SymE), R(R) {
read();
}
void read() {
if (SymI == SymE)
return;
@ -267,16 +261,24 @@ public:
ComdatIndex = SymI->ComdatIndex;
Flags = SymI->Flags;
uint32_t UncI = SymI->UncommonIndex;
if (UncI != -1u) {
const storage::Uncommon &Unc = R->Uncommons[UncI];
CommonSize = Unc.CommonSize;
CommonAlign = Unc.CommonAlign;
COFFWeakExternFallbackName = R->str(Unc.COFFWeakExternFallbackName);
if (Flags & (1 << storage::Symbol::FB_has_uncommon)) {
CommonSize = UncI->CommonSize;
CommonAlign = UncI->CommonAlign;
COFFWeakExternFallbackName = R->str(UncI->COFFWeakExternFallbackName);
}
}
public:
SymbolRef(const storage::Symbol *SymI, const storage::Symbol *SymE,
const storage::Uncommon *UncI, const Reader *R)
: SymI(SymI), SymE(SymE), UncI(UncI), R(R) {
read();
}
void moveNext() {
++SymI;
if (Flags & (1 << storage::Symbol::FB_has_uncommon))
++UncI;
read();
}
@ -284,15 +286,16 @@ public:
};
inline Reader::symbol_range Reader::symbols() const {
return {SymbolRef(Symbols.begin(), Symbols.end(), this),
SymbolRef(Symbols.end(), Symbols.end(), this)};
return {SymbolRef(Symbols.begin(), Symbols.end(), Uncommons.begin(), this),
SymbolRef(Symbols.end(), Symbols.end(), nullptr, this)};
}
inline Reader::symbol_range Reader::module_symbols(unsigned I) const {
const storage::Module &M = Modules[I];
const storage::Symbol *MBegin = Symbols.begin() + M.Begin,
*MEnd = Symbols.begin() + M.End;
return {SymbolRef(MBegin, MEnd, this), SymbolRef(MEnd, MEnd, this)};
return {SymbolRef(MBegin, MEnd, Uncommons.begin() + M.UncBegin, this),
SymbolRef(MEnd, MEnd, nullptr, this)};
}
}

View File

@ -34,8 +34,6 @@ struct Builder {
StringSaver Saver{Alloc};
DenseMap<const Comdat *, unsigned> ComdatMap;
ModuleSymbolTable Msymtab;
SmallPtrSet<GlobalValue *, 8> Used;
Mangler Mang;
Triple TT;
@ -60,18 +58,24 @@ struct Builder {
}
Error addModule(Module *M);
Error addSymbol(ModuleSymbolTable::Symbol Sym);
Error addSymbol(const ModuleSymbolTable &Msymtab,
const SmallPtrSet<GlobalValue *, 8> &Used,
ModuleSymbolTable::Symbol Sym);
Error build(ArrayRef<Module *> Mods);
};
Error Builder::addModule(Module *M) {
SmallPtrSet<GlobalValue *, 8> Used;
collectUsedGlobalVariables(*M, Used, /*CompilerUsed*/ false);
storage::Module Mod;
Mod.Begin = Msymtab.symbols().size();
ModuleSymbolTable Msymtab;
Msymtab.addModule(M);
Mod.End = Msymtab.symbols().size();
storage::Module Mod;
Mod.Begin = Syms.size();
Mod.End = Syms.size() + Msymtab.symbols().size();
Mod.UncBegin = Uncommons.size();
Mods.push_back(Mod);
if (TT.isOSBinFormatCOFF()) {
@ -85,20 +89,25 @@ Error Builder::addModule(Module *M) {
}
}
for (ModuleSymbolTable::Symbol Msym : Msymtab.symbols())
if (Error Err = addSymbol(Msymtab, Used, Msym))
return Err;
return Error::success();
}
Error Builder::addSymbol(ModuleSymbolTable::Symbol Msym) {
Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
const SmallPtrSet<GlobalValue *, 8> &Used,
ModuleSymbolTable::Symbol Msym) {
Syms.emplace_back();
storage::Symbol &Sym = Syms.back();
Sym = {};
Sym.UncommonIndex = -1;
storage::Uncommon *Unc = nullptr;
auto Uncommon = [&]() -> storage::Uncommon & {
if (Unc)
return *Unc;
Sym.UncommonIndex = Uncommons.size();
Sym.Flags |= 1 << storage::Symbol::FB_has_uncommon;
Uncommons.emplace_back();
Unc = &Uncommons.back();
*Unc = {};
@ -195,15 +204,10 @@ Error Builder::build(ArrayRef<Module *> IRMods) {
setStr(Hdr.SourceFileName, IRMods[0]->getSourceFileName());
TT = Triple(IRMods[0]->getTargetTriple());
// This adds the symbols for each module to Msymtab.
for (auto *M : IRMods)
if (Error Err = addModule(M))
return Err;
for (ModuleSymbolTable::Symbol Msym : Msymtab.symbols())
if (Error Err = addSymbol(Msym))
return Err;
COFFLinkerOptsOS.flush();
setStr(Hdr.COFFLinkerOpts, COFFLinkerOpts);