-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[NFCI][LTO][lld] Optimize away symbol copies within LTO global resolution in ELF #106193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a01e4c9
6d50637
c59fff7
b169ccb
dbfb00c
27c96db
0511e32
0971659
106f91c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,6 +77,10 @@ cl::opt<bool> EnableLTOInternalization( | |
| "enable-lto-internalization", cl::init(true), cl::Hidden, | ||
| cl::desc("Enable global value internalization in LTO")); | ||
|
|
||
| static cl::opt<bool> | ||
| LTOKeepSymbolCopies("lto-keep-symbol-copies", cl::init(false), cl::Hidden, | ||
| cl::desc("Keep copies of symbols in LTO indexing")); | ||
|
|
||
| /// Indicate we are linking with an allocator that supports hot/cold operator | ||
| /// new interfaces. | ||
| extern cl::opt<bool> SupportsHotColdNew; | ||
|
|
@@ -587,8 +591,14 @@ LTO::LTO(Config Conf, ThinBackend Backend, | |
| : Conf(std::move(Conf)), | ||
| RegularLTO(ParallelCodeGenParallelismLevel, this->Conf), | ||
| ThinLTO(std::move(Backend)), | ||
| GlobalResolutions(std::make_optional<StringMap<GlobalResolution>>()), | ||
| LTOMode(LTOMode) {} | ||
| GlobalResolutions( | ||
| std::make_unique<DenseMap<StringRef, GlobalResolution>>()), | ||
| LTOMode(LTOMode) { | ||
| if (Conf.KeepSymbolNameCopies || LTOKeepSymbolCopies) { | ||
| Alloc = std::make_unique<BumpPtrAllocator>(); | ||
| GlobalResolutionSymbolSaver = std::make_unique<llvm::StringSaver>(*Alloc); | ||
| } | ||
| } | ||
|
|
||
| // Requires a destructor for MapVector<BitcodeModule>. | ||
| LTO::~LTO() = default; | ||
|
|
@@ -606,7 +616,12 @@ void LTO::addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms, | |
| assert(ResI != ResE); | ||
| SymbolResolution Res = *ResI++; | ||
|
|
||
| auto &GlobalRes = (*GlobalResolutions)[Sym.getName()]; | ||
| StringRef SymbolName = Sym.getName(); | ||
| // Keep copies of symbols if the client of LTO says so. | ||
| if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName)) | ||
| SymbolName = GlobalResolutionSymbolSaver->save(SymbolName); | ||
|
|
||
| auto &GlobalRes = (*GlobalResolutions)[SymbolName]; | ||
|
Comment on lines
+619
to
+624
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A somewhat nit picky suggestion, but should we create a wrapper class for This way, the application logic should stay clear. That is: staying as is. We should be able to put members like: into the wrapper class and probably strip away below.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a helper method |
||
| GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr(); | ||
| if (Res.Prevailing) { | ||
| assert(!GlobalRes.Prevailing && | ||
|
|
@@ -660,6 +675,14 @@ void LTO::addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms, | |
| } | ||
| } | ||
|
|
||
| void LTO::releaseGlobalResolutionsMemory() { | ||
| // Release GlobalResolutions dense-map itself. | ||
| GlobalResolutions.reset(); | ||
| // Release the string saver memory. | ||
| GlobalResolutionSymbolSaver.reset(); | ||
| Alloc.reset(); | ||
| } | ||
|
|
||
| static void writeToResolutionFile(raw_ostream &OS, InputFile *Input, | ||
| ArrayRef<SymbolResolution> Res) { | ||
| StringRef Path = Input->getName(); | ||
|
|
@@ -1771,7 +1794,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache, | |
| // are no further accesses. We specifically want to do this before computing | ||
| // cross module importing, which adds to peak memory via the computed import | ||
| // and export lists. | ||
| GlobalResolutions.reset(); | ||
| releaseGlobalResolutionsMemory(); | ||
|
|
||
| if (Conf.OptLevel > 0) | ||
| ComputeCrossModuleImport(ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is an option needed? I think this can just be set through the config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a back-up option in case this change hit any corner case (missed a symbol) but not caught in release. Though all symbols used by GlobalResolutions should be covered by looking at the code.