[llvm] [SampleFDO] Stale profile call-graph matching (PR #92151)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 1 16:56:29 PDT 2024


================
@@ -590,14 +617,318 @@ void SampleProfileMatcher::computeAndReportProfileStaleness() {
   }
 }
 
-void SampleProfileMatcher::runOnModule() {
-  ProfileConverter::flattenProfile(Reader.getProfiles(), FlattenedProfiles,
-                                   FunctionSamples::ProfileIsCS);
+void SampleProfileMatcher::findNewIRFunctions(
+    StringMap<Function *> &NewIRFunctions) {
+  // TODO: Support MD5 profile.
+  if (FunctionSamples::UseMD5)
+    return;
+  StringSet<> NamesInProfile;
+  if (auto NameTable = Reader.getNameTable()) {
+    for (auto Name : *NameTable)
+      NamesInProfile.insert(Name.stringRef());
+  }
+
   for (auto &F : M) {
-    if (skipProfileForFunction(F))
+    // Skip declarations, as even if the function can be recognized renamed, we
+    // have nothing to do with it.
+    if (F.isDeclaration())
       continue;
-    runOnFunction(F);
+
+    StringRef CanonFName = FunctionSamples::getCanonicalFnName(F.getName());
+    const auto *FS = getFlattenedSamplesFor(F);
+    if (FS)
+      continue;
+
+    // For extended binary, functions are fully inlined may not be loaded in the
+    // top-level profile, so check the NameTable which has the all symbol names
+    // in profile.
+    if (NamesInProfile.count(CanonFName))
+      continue;
+
+    // For extended binary, non-profiled function symbols are in the profile
+    // symbol list table.
+    if (PSL && PSL->contains(CanonFName))
+      continue;
+
+    LLVM_DEBUG(dbgs() << "Function " << CanonFName
+                      << " is not in profile or symbol list table.\n");
+    NewIRFunctions[CanonFName] = &F;
   }
+}
+
+void SampleProfileMatcher::findNewIRCallees(
+    Function &Caller, const StringMap<Function *> &NewIRFunctions,
+    std::vector<Function *> &NewIRCallees) {
+  for (auto &BB : Caller) {
+    for (auto &I : BB) {
+      const auto *CB = dyn_cast<CallBase>(&I);
+      if (!CB || isa<IntrinsicInst>(&I))
+        continue;
+      Function *Callee = CB->getCalledFunction();
+      if (!Callee || Callee->isDeclaration())
+        continue;
+      StringRef CalleeName =
+          FunctionSamples::getCanonicalFnName(Callee->getName());
+      if (NewIRFunctions.count(CalleeName))
+        NewIRCallees.push_back(Callee);
+    }
+  }
+}
+
+std::pair<Function *, SampleProfileMatcher::MatchState>
+SampleProfileMatcher::findFunction(
+    const FunctionId &ProfFunc,
+    const FunctionMap &OldProfToNewSymbolMap) const {
+  auto F = SymbolMap->find(ProfFunc);
+  if (F != SymbolMap->end())
+    return {F->second, MatchState::InitialMatch};
+
+  // Existing matched function is found.
+  auto NewF = OldProfToNewSymbolMap.find(ProfFunc);
+  if (NewF != OldProfToNewSymbolMap.end())
+    return {NewF->second, MatchState::RecoveredMismatch};
+  return {nullptr, MatchState::Unknown};
+}
+
+std::pair<Function *, SampleProfileMatcher::MatchState>
+SampleProfileMatcher::findOrMatchFunction(
+    const FunctionId &ProfFunc, FunctionMap &OldProfToNewSymbolMap,
+    const std::vector<Function *> &NewIRCallees) {
+  auto R = findFunction(ProfFunc, OldProfToNewSymbolMap);
+  // We need to check the match state instead of nullptr function because the
+  // returned function can be nullptr even if it's found in the symbol map.
+  if (R.second != MatchState::Unknown)
+    return R;
+
+  for (auto *IRCallee : NewIRCallees)
+    if (functionMatchesProfile(*IRCallee, ProfFunc)) {
+      OldProfToNewSymbolMap[ProfFunc] = IRCallee;
----------------
WenleiHe wrote:

Assert the entry isn't in the map yet?

https://github.com/llvm/llvm-project/pull/92151


More information about the llvm-commits mailing list