StringRef getNameInModule(StringRef Name, const Module *M) const {
if (Format != SPF_Compact_Binary)
return Name;
- // Expect CurrentModule to be initialized by GUIDToFuncNameMapper.
- if (M != CurrentModule)
- llvm_unreachable("Input Module should be the same as CurrentModule");
- auto iter = GUIDToFuncNameMap.find(std::stoull(Name.data()));
- if (iter == GUIDToFuncNameMap.end())
+
+ assert(GUIDToFuncNameMap && "GUIDToFuncNameMap needs to be popluated first");
+ auto iter = GUIDToFuncNameMap->find(std::stoull(Name.data()));
+ if (iter == GUIDToFuncNameMap->end())
return StringRef();
return iter->second;
}
const FunctionSamples *findFunctionSamples(const DILocation *DIL) const;
static SampleProfileFormat Format;
- /// GUIDToFuncNameMap saves the mapping from GUID to the symbol name, for
- /// all the function symbols defined or declared in CurrentModule.
- static DenseMap<uint64_t, StringRef> GUIDToFuncNameMap;
- static Module *CurrentModule;
-
- class GUIDToFuncNameMapper {
- public:
- GUIDToFuncNameMapper(Module &M) {
- if (Format != SPF_Compact_Binary)
- return;
-
- for (const auto &F : M) {
- StringRef OrigName = F.getName();
- GUIDToFuncNameMap.insert({Function::getGUID(OrigName), OrigName});
- /// Local to global var promotion used by optimization like thinlto
- /// will rename the var and add suffix like ".llvm.xxx" to the
- /// original local name. In sample profile, the suffixes of function
- /// names are all stripped. Since it is possible that the mapper is
- /// built in post-thin-link phase and var promotion has been done,
- /// we need to add the substring of function name without the suffix
- /// into the GUIDToFuncNameMap.
- StringRef CanonName = getCanonicalFnName(F);
- if (CanonName != OrigName)
- GUIDToFuncNameMap.insert({Function::getGUID(CanonName), CanonName});
- }
- CurrentModule = &M;
- }
- ~GUIDToFuncNameMapper() {
- if (Format != SPF_Compact_Binary)
- return;
-
- GUIDToFuncNameMap.clear();
- CurrentModule = nullptr;
- }
- };
+ /// GUIDToFuncNameMap saves the mapping from GUID to the symbol name, for
+ /// all the function symbols defined or declared in current module.
+ DenseMap<uint64_t, StringRef> *GUIDToFuncNameMap = nullptr;
// Assume the input \p Name is a name coming from FunctionSamples itself.
// If the format is SPF_Compact_Binary, the name is already a GUID and we
#include <limits>
#include <map>
#include <memory>
+#include <queue>
#include <string>
#include <system_error>
#include <utility>
uint64_t TotalUsedSamples = 0;
};
+class GUIDToFuncNameMapper {
+public:
+ GUIDToFuncNameMapper(Module &M, SampleProfileReader &Reader,
+ DenseMap<uint64_t, StringRef> &GUIDToFuncNameMap)
+ : CurrentReader(Reader), CurrentModule(M),
+ CurrentGUIDToFuncNameMap(GUIDToFuncNameMap) {
+ if (CurrentReader.getFormat() != SPF_Compact_Binary)
+ return;
+
+ for (const auto &F : CurrentModule) {
+ StringRef OrigName = F.getName();
+ CurrentGUIDToFuncNameMap.insert(
+ {Function::getGUID(OrigName), OrigName});
+
+ // Local to global var promotion used by optimization like thinlto
+ // will rename the var and add suffix like ".llvm.xxx" to the
+ // original local name. In sample profile, the suffixes of function
+ // names are all stripped. Since it is possible that the mapper is
+ // built in post-thin-link phase and var promotion has been done,
+ // we need to add the substring of function name without the suffix
+ // into the GUIDToFuncNameMap.
+ StringRef CanonName = FunctionSamples::getCanonicalFnName(F);
+ if (CanonName != OrigName)
+ CurrentGUIDToFuncNameMap.insert(
+ {Function::getGUID(CanonName), CanonName});
+ }
+
+ // Update GUIDToFuncNameMap for each function including inlinees.
+ SetGUIDToFuncNameMapForAll(&CurrentGUIDToFuncNameMap);
+ }
+
+ ~GUIDToFuncNameMapper() {
+ if (CurrentReader.getFormat() != SPF_Compact_Binary)
+ return;
+
+ CurrentGUIDToFuncNameMap.clear();
+
+ // Reset GUIDToFuncNameMap for of each function as they're no
+ // longer valid at this point.
+ SetGUIDToFuncNameMapForAll(nullptr);
+ }
+
+private:
+ void SetGUIDToFuncNameMapForAll(DenseMap<uint64_t, StringRef> *Map) {
+ std::queue<FunctionSamples *> FSToUpdate;
+ for (auto &IFS : CurrentReader.getProfiles()) {
+ FSToUpdate.push(&IFS.second);
+ }
+
+ while (!FSToUpdate.empty()) {
+ FunctionSamples *FS = FSToUpdate.front();
+ FSToUpdate.pop();
+ FS->GUIDToFuncNameMap = Map;
+ for (const auto &ICS : FS->getCallsiteSamples()) {
+ const FunctionSamplesMap &FSMap = ICS.second;
+ for (auto &IFS : FSMap) {
+ FunctionSamples &FS = const_cast<FunctionSamples &>(IFS.second);
+ FSToUpdate.push(&FS);
+ }
+ }
+ }
+ }
+
+ SampleProfileReader &CurrentReader;
+ Module &CurrentModule;
+ DenseMap<uint64_t, StringRef> &CurrentGUIDToFuncNameMap;
+};
+
/// Sample profile pass.
///
/// This pass reads profile data from the file specified by
uint64_t entryCount;
};
DenseMap<Function *, NotInlinedProfileInfo> notInlinedCallInfo;
+
+ // GUIDToFuncNameMap saves the mapping from GUID to the symbol name, for
+ // all the function symbols defined or declared in current module.
+ DenseMap<uint64_t, StringRef> GUIDToFuncNameMap;
};
class SampleProfileLoaderLegacyPass : public ModulePass {
bool SampleProfileLoader::runOnModule(Module &M, ModuleAnalysisManager *AM,
ProfileSummaryInfo *_PSI) {
- FunctionSamples::GUIDToFuncNameMapper Mapper(M);
+ GUIDToFuncNameMapper Mapper(M, *Reader, GUIDToFuncNameMap);
if (!ProfileIsValid)
return false;