[llvm] [MemProf] Support cloning for indirect calls with ThinLTO (PR #110625)

Snehasish Kumar via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 4 10:47:54 PDT 2024


================
@@ -4108,6 +4456,119 @@ bool MemProfContextDisambiguation::applyImport(Module &M) {
         I.setMetadata(LLVMContext::MD_callsite, nullptr);
       }
     }
+
+    // Now do any promotion required for cloning. Specifically, for each
+    // recorded ICP candidate (which was only recorded because one clone of that
+    // candidate should call a cloned target), we perform ICP (speculative
+    // devirtualization) for each clone of the callsite, and update its callee
+    // to the appropriate clone. Note that the ICP compares against the original
+    // version of the target, which is what is in the vtable.
+    for (auto &ICallInfo : ICallAnalysisMap) {
+      auto *CB = ICallInfo.first;
+      auto &Info = ICallInfo.second;
+      auto CallsiteIndex = Info.CallsiteInfoStartIndex;
+      auto TotalCount = Info.TotalCount;
+      unsigned NumPromoted = 0;
+      unsigned NumClones = 0;
+
+      for (auto &Candidate : Info.CandidateProfileData) {
+        auto &StackNode = FS->callsites()[CallsiteIndex++];
+
+        // All calls in the same function must have the same number of clones.
+        assert(!NumClones || NumClones == StackNode.Clones.size());
+        NumClones = StackNode.Clones.size();
+
+        // See if the target is in the module. If it wasn't imported, it is
+        // possible that this profile could have been collected on a different
+        // target (or version of the code), and we need to be conservative
+        // (similar to what is done in the ICP pass).
+        Function *TargetFunction = Symtab.getFunction(Candidate.Value);
+        if (TargetFunction == nullptr || TargetFunction->isDeclaration()) {
+          ORE.emit([&]() {
+            return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToFindTarget",
+                                            CB)
+                   << "Cannot promote indirect call: target with md5sum "
+                   << ore::NV("target md5sum", Candidate.Value) << " not found";
+          });
+          // FIXME: See if we can use the new declaration importing support to
+          // at least get the declarations imported for this case. Hot indirect
+          // targets should have been imported normally, however.
+          continue;
+        }
+
+        // Check if legal to promote
+        const char *Reason = nullptr;
+        if (!isLegalToPromote(*CB, TargetFunction, &Reason)) {
+          ORE.emit([&]() {
+            return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToPromote", CB)
+                   << "Cannot promote indirect call to "
+                   << ore::NV("TargetFunction", TargetFunction)
+                   << " with count of " << ore::NV("TotalCount", TotalCount)
+                   << ": " << Reason;
+          });
+          continue;
+        }
+
+        assert(!IsMemProfClone(*TargetFunction));
+
+        // Handle each call clone, applying ICP so that each clone directly
+        // calls the specified callee clone, guarded by the appropriate ICP
+        // check.
+        auto CalleeOrigName = TargetFunction->getName();
----------------
snehasish wrote:

I think this is only used on L4537, can we inline this call there?

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


More information about the llvm-commits mailing list