/// table.
struct Module {
Word Begin, End;
+
+ /// The index of the first Uncommon for this Module.
+ Word UncBegin;
};
/// This is equivalent to an IR comdat.
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,
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
/// 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;
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();
}
};
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)};
}
}
StringSaver Saver{Alloc};
DenseMap<const Comdat *, unsigned> ComdatMap;
- ModuleSymbolTable Msymtab;
- SmallPtrSet<GlobalValue *, 8> Used;
Mangler Mang;
Triple TT;
}
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()) {
}
}
+ 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 = {};
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);