From f0d32575a1193741bc9ca90e5beced693cba28b0 Mon Sep 17 00:00:00 2001 From: Amir Ayupov Date: Fri, 20 Jun 2025 14:29:32 -0700 Subject: [PATCH] [BOLT][NFCI] Use FileSymbols for local symbol disambiguation (#89088) Remove SymbolToFileName mapping from every local symbol to its containing FILE symbol name, and reuse FileSymbols to disambiguate local symbols instead. Also removes the check for `ld-temp.o` file symbol which was added to prevent LTO build mode from affecting the disambiguated name. This may cause incompatibility when using the profile collected on a binary built in a different mode than the input binary. Addresses #90661. Speeds up discover file objects by 5-10% for large binaries: - binary with ~1.2M symbols: 12.6422s -> 12.0297s - binary with ~4.5M symbols: 48.8851s -> 43.7315s --- bolt/lib/Rewrite/RewriteInstance.cpp | 37 ++++++---------------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index d650e5db54bf..93bd93b6cb98 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -780,14 +780,6 @@ void RewriteInstance::discoverFileObjects() { // For local symbols we want to keep track of associated FILE symbol name for // disambiguation by combined name. - StringRef FileSymbolName; - bool SeenFileName = false; - struct SymbolRefHash { - size_t operator()(SymbolRef const &S) const { - return std::hash{}(S.getRawDataRefImpl().p); - } - }; - std::unordered_map SymbolToFileName; for (const ELFSymbolRef &Symbol : InputFile->symbols()) { Expected NameOrError = Symbol.getName(); if (NameOrError && NameOrError->starts_with("__asan_init")) { @@ -806,21 +798,8 @@ void RewriteInstance::discoverFileObjects() { if (cantFail(Symbol.getFlags()) & SymbolRef::SF_Undefined) continue; - if (cantFail(Symbol.getType()) == SymbolRef::ST_File) { + if (cantFail(Symbol.getType()) == SymbolRef::ST_File) FileSymbols.emplace_back(Symbol); - StringRef Name = - cantFail(std::move(NameOrError), "cannot get symbol name for file"); - // Ignore Clang LTO artificial FILE symbol as it is not always generated, - // and this uncertainty is causing havoc in function name matching. - if (Name == "ld-temp.o") - continue; - FileSymbolName = Name; - SeenFileName = true; - continue; - } - if (!FileSymbolName.empty() && - !(cantFail(Symbol.getFlags()) & SymbolRef::SF_Global)) - SymbolToFileName[Symbol] = FileSymbolName; } // Sort symbols in the file by value. Ignore symbols from non-allocatable @@ -1028,14 +1007,14 @@ void RewriteInstance::discoverFileObjects() { // The field is used for disambiguation of local symbols since there // could be identical function names coming from identical file names // (e.g. from different directories). - std::string AltPrefix; - auto SFI = SymbolToFileName.find(Symbol); - if (SymbolType == SymbolRef::ST_Function && SFI != SymbolToFileName.end()) - AltPrefix = Name + "/" + std::string(SFI->second); + auto SFI = llvm::upper_bound(FileSymbols, ELFSymbolRef(Symbol)); + if (SymbolType == SymbolRef::ST_Function && SFI != FileSymbols.begin()) { + StringRef FileSymbolName = cantFail(SFI[-1].getName()); + if (!FileSymbolName.empty()) + AlternativeName = NR.uniquify(Name + "/" + FileSymbolName.str()); + } UniqueName = NR.uniquify(Name); - if (!AltPrefix.empty()) - AlternativeName = NR.uniquify(AltPrefix); } uint64_t SymbolSize = ELFSymbolRef(Symbol).getSize(); @@ -1294,7 +1273,7 @@ void RewriteInstance::discoverFileObjects() { FDE->getAddressRange()); } - BC->setHasSymbolsWithFileName(SeenFileName); + BC->setHasSymbolsWithFileName(FileSymbols.size()); // Now that all the functions were created - adjust their boundaries. adjustFunctionBoundaries();