[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
This commit is contained in:
@@ -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<decltype(DataRefImpl::p)>{}(S.getRawDataRefImpl().p);
|
||||
}
|
||||
};
|
||||
std::unordered_map<SymbolRef, StringRef, SymbolRefHash> SymbolToFileName;
|
||||
for (const ELFSymbolRef &Symbol : InputFile->symbols()) {
|
||||
Expected<StringRef> 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 <id> 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();
|
||||
|
||||
Reference in New Issue
Block a user