@@ -77,6 +77,10 @@ cl::opt<bool> EnableLTOInternalization(
7777 " enable-lto-internalization" , cl::init(true ), cl::Hidden,
7878 cl::desc(" Enable global value internalization in LTO" ));
7979
80+ static cl::opt<bool >
81+ LTOKeepSymbolCopies (" lto-keep-symbol-copies" , cl::init(false ), cl::Hidden,
82+ cl::desc (" Keep copies of symbols in LTO indexing" ));
83+
8084// / Indicate we are linking with an allocator that supports hot/cold operator
8185// / new interfaces.
8286extern cl::opt<bool > SupportsHotColdNew;
@@ -587,8 +591,14 @@ LTO::LTO(Config Conf, ThinBackend Backend,
587591 : Conf(std::move(Conf)),
588592 RegularLTO(ParallelCodeGenParallelismLevel, this ->Conf),
589593 ThinLTO(std::move(Backend)),
590- GlobalResolutions(std::make_optional<StringMap<GlobalResolution>>()),
591- LTOMode(LTOMode) {}
594+ GlobalResolutions(
595+ std::make_unique<DenseMap<StringRef, GlobalResolution>>()),
596+ LTOMode(LTOMode) {
597+ if (Conf.KeepSymbolNameCopies || LTOKeepSymbolCopies) {
598+ Alloc = std::make_unique<BumpPtrAllocator>();
599+ GlobalResolutionSymbolSaver = std::make_unique<llvm::StringSaver>(*Alloc);
600+ }
601+ }
592602
593603// Requires a destructor for MapVector<BitcodeModule>.
594604LTO::~LTO () = default ;
@@ -606,7 +616,12 @@ void LTO::addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms,
606616 assert (ResI != ResE);
607617 SymbolResolution Res = *ResI++;
608618
609- auto &GlobalRes = (*GlobalResolutions)[Sym.getName ()];
619+ StringRef SymbolName = Sym.getName ();
620+ // Keep copies of symbols if the client of LTO says so.
621+ if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains (SymbolName))
622+ SymbolName = GlobalResolutionSymbolSaver->save (SymbolName);
623+
624+ auto &GlobalRes = (*GlobalResolutions)[SymbolName];
610625 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr ();
611626 if (Res.Prevailing ) {
612627 assert (!GlobalRes.Prevailing &&
@@ -660,6 +675,14 @@ void LTO::addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms,
660675 }
661676}
662677
678+ void LTO::releaseGlobalResolutionsMemory () {
679+ // Release GlobalResolutions dense-map itself.
680+ GlobalResolutions.reset ();
681+ // Release the string saver memory.
682+ GlobalResolutionSymbolSaver.reset ();
683+ Alloc.reset ();
684+ }
685+
663686static void writeToResolutionFile (raw_ostream &OS, InputFile *Input,
664687 ArrayRef<SymbolResolution> Res) {
665688 StringRef Path = Input->getName ();
@@ -1771,7 +1794,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
17711794 // are no further accesses. We specifically want to do this before computing
17721795 // cross module importing, which adds to peak memory via the computed import
17731796 // and export lists.
1774- GlobalResolutions. reset ();
1797+ releaseGlobalResolutionsMemory ();
17751798
17761799 if (Conf.OptLevel > 0 )
17771800 ComputeCrossModuleImport (ThinLTO.CombinedIndex , ModuleToDefinedGVSummaries,
0 commit comments