Index: llvm/include/llvm/Object/IRSymtab.h =================================================================== --- llvm/include/llvm/Object/IRSymtab.h +++ llvm/include/llvm/Object/IRSymtab.h @@ -59,6 +59,9 @@ /// 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 @@ 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 @@ 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 @@ -247,15 +247,9 @@ /// 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; @@ -265,16 +259,24 @@ 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(); } @@ -282,15 +284,16 @@ }; 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)}; } } Index: llvm/lib/Object/IRSymtab.cpp =================================================================== --- llvm/lib/Object/IRSymtab.cpp +++ llvm/lib/Object/IRSymtab.cpp @@ -34,8 +34,6 @@ StringSaver Saver{Alloc}; DenseMap ComdatMap; - ModuleSymbolTable Msymtab; - SmallPtrSet Used; Mangler Mang; Triple TT; @@ -59,18 +57,24 @@ } Error addModule(Module *M); - Error addSymbol(ModuleSymbolTable::Symbol Sym); + Error addSymbol(const ModuleSymbolTable &Msymtab, + const SmallPtrSet &Used, + ModuleSymbolTable::Symbol Sym); Error build(ArrayRef Mods); }; Error Builder::addModule(Module *M) { + SmallPtrSet 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()) { @@ -84,20 +88,25 @@ } } + 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 &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 = {}; @@ -193,15 +202,10 @@ 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);