-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Backport #164873 and #166067 to release/21.x
#166409
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
Conversation
We could inadvertently create new entries in the PrevailingModuleForGUID map during lookup, which was always using operator[]. In most cases we will have one for external symbols, but not in cases where the prevailing copy is in a native object. Or if this happened to be looked up for a local. Make the map private and create and use accessors. (cherry picked from commit 0341fb6)
Avoid the construction of `GUID` when not required. This improves the performance of a LLD `--thinlto-index-only` link of `clang` by ~4-5% on both Windows and Linux. (cherry picked from commit 564c3de)
|
@llvm/pr-subscribers-lto Author: Andrew Ng (nga888) ChangesBackport the following commits to 0341fb6: [ThinLTO] Avoid creating map entries on lookup (NFCI) (#164873) Full diff: https://github.com/llvm/llvm-project/pull/166409.diff 2 Files Affected:
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index d8e632b5a49d5..d5e7d2ede7e9b 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -464,6 +464,19 @@ class LTO {
ModuleMapType ModuleMap;
// The bitcode modules to compile, if specified by the LTO Config.
std::optional<ModuleMapType> ModulesToCompile;
+
+ void setPrevailingModuleForGUID(GlobalValue::GUID GUID, StringRef Module) {
+ PrevailingModuleForGUID[GUID] = Module;
+ }
+ bool isPrevailingModuleForGUID(GlobalValue::GUID GUID,
+ StringRef Module) const {
+ auto It = PrevailingModuleForGUID.find(GUID);
+ return It != PrevailingModuleForGUID.end() && It->second == Module;
+ }
+
+ private:
+ // Make this private so all accesses must go through above accessor methods
+ // to avoid inadvertently creating new entries on lookups.
DenseMap<GlobalValue::GUID, StringRef> PrevailingModuleForGUID;
} ThinLTO;
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 73e79c08a56ca..3c6951d8ec5fe 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -1035,63 +1035,59 @@ Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod,
Error LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
const SymbolResolution *&ResI,
const SymbolResolution *ResE) {
+ const auto BMID = BM.getModuleIdentifier();
const SymbolResolution *ResITmp = ResI;
for (const InputFile::Symbol &Sym : Syms) {
assert(ResITmp != ResE);
SymbolResolution Res = *ResITmp++;
- if (!Sym.getIRName().empty()) {
+ if (!Sym.getIRName().empty() && Res.Prevailing) {
auto GUID = GlobalValue::getGUIDAssumingExternalLinkage(
GlobalValue::getGlobalIdentifier(Sym.getIRName(),
GlobalValue::ExternalLinkage, ""));
- if (Res.Prevailing)
- ThinLTO.PrevailingModuleForGUID[GUID] = BM.getModuleIdentifier();
+ ThinLTO.setPrevailingModuleForGUID(GUID, BMID);
}
}
- if (Error Err =
- BM.readSummary(ThinLTO.CombinedIndex, BM.getModuleIdentifier(),
- [&](GlobalValue::GUID GUID) {
- return ThinLTO.PrevailingModuleForGUID[GUID] ==
- BM.getModuleIdentifier();
- }))
+ if (Error Err = BM.readSummary(
+ ThinLTO.CombinedIndex, BMID, [&](GlobalValue::GUID GUID) {
+ return ThinLTO.isPrevailingModuleForGUID(GUID, BMID);
+ }))
return Err;
- LLVM_DEBUG(dbgs() << "Module " << BM.getModuleIdentifier() << "\n");
+ LLVM_DEBUG(dbgs() << "Module " << BMID << "\n");
for (const InputFile::Symbol &Sym : Syms) {
assert(ResI != ResE);
SymbolResolution Res = *ResI++;
- if (!Sym.getIRName().empty()) {
+ if (!Sym.getIRName().empty() &&
+ (Res.Prevailing || Res.FinalDefinitionInLinkageUnit)) {
auto GUID = GlobalValue::getGUIDAssumingExternalLinkage(
GlobalValue::getGlobalIdentifier(Sym.getIRName(),
GlobalValue::ExternalLinkage, ""));
if (Res.Prevailing) {
- assert(ThinLTO.PrevailingModuleForGUID[GUID] ==
- BM.getModuleIdentifier());
+ assert(ThinLTO.isPrevailingModuleForGUID(GUID, BMID));
// For linker redefined symbols (via --wrap or --defsym) we want to
// switch the linkage to `weak` to prevent IPOs from happening.
// Find the summary in the module for this very GV and record the new
// linkage so that we can switch it when we import the GV.
if (Res.LinkerRedefined)
- if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(
- GUID, BM.getModuleIdentifier()))
+ if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID))
S->setLinkage(GlobalValue::WeakAnyLinkage);
}
// If the linker resolved the symbol to a local definition then mark it
// as local in the summary for the module we are adding.
if (Res.FinalDefinitionInLinkageUnit) {
- if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(
- GUID, BM.getModuleIdentifier())) {
+ if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID)) {
S->setDSOLocal(true);
}
}
}
}
- if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
+ if (!ThinLTO.ModuleMap.insert({BMID, BM}).second)
return make_error<StringError>(
"Expected at most one ThinLTO module per bitcode file",
inconvertibleErrorCode());
@@ -1102,10 +1098,10 @@ Error LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
// This is a fuzzy name matching where only modules with name containing the
// specified switch values are going to be compiled.
for (const std::string &Name : Conf.ThinLTOModulesToCompile) {
- if (BM.getModuleIdentifier().contains(Name)) {
- ThinLTO.ModulesToCompile->insert({BM.getModuleIdentifier(), BM});
- LLVM_DEBUG(dbgs() << "[ThinLTO] Selecting " << BM.getModuleIdentifier()
- << " to compile\n");
+ if (BMID.contains(Name)) {
+ ThinLTO.ModulesToCompile->insert({BMID, BM});
+ LLVM_DEBUG(dbgs() << "[ThinLTO] Selecting " << BMID << " to compile\n");
+ break;
}
}
}
@@ -1974,7 +1970,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
LocalWPDTargetsMap);
auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
- return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();
+ return ThinLTO.isPrevailingModuleForGUID(GUID, S->modulePath());
};
if (EnableMemProfContextDisambiguation) {
MemProfContextDisambiguation ContextDisambiguation;
|
teresajohnson
left a comment
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.
lgtm thanks
|
Hi @nga888, at this point in the release cycle we are only accepting fixes for regressions or major bug fixes. This only seems to be a performance improvement in a very specific scenario, so it does not seem to meet the bar, plus I am unsure how risky taking these two changes might be for the release branch. Can you provide some detail on why you feel we should incorporate these changes into the release branch at this time? |
Yes, I forgot that these "final" point releases are only for regressions or bug fixes. Both these changes are NFC but you're right they don't really meet the criteria. Will have to wait for the improvement in the next release. Thanks! |
Backport the following commits to
release/21.x:0341fb6: [ThinLTO] Avoid creating map entries on lookup (NFCI) (#164873)
564c3de: [ThinLTO][NFC] Improve performance of
addThinLTO(#166067)