[llvm] [ICP] Add a few tunings to indirect-call-promotion (PR #149892)

Mingming Liu via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 23 10:10:16 PDT 2025


================
@@ -477,14 +499,31 @@ IndirectCallPromoter::getPromotionCandidatesForCallSite(
     // the case where the symbol is globally dead in the binary and removed by
     // ThinLTO.
     Function *TargetFunction = Symtab->getFunction(Target);
-    if (TargetFunction == nullptr || TargetFunction->isDeclaration()) {
+    if (TargetFunction == nullptr) {
       LLVM_DEBUG(dbgs() << " Not promote: Cannot find the target\n");
       ORE.emit([&]() {
         return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToFindTarget", &CB)
                << "Cannot promote indirect call: target with md5sum "
                << ore::NV("target md5sum", Target) << " not found";
       });
-      break;
+      if (ICPAllowCandidateSkip)
----------------
mingmingl-llvm wrote:

There are three occurrences of `if (ICPAllowCandidateSkip) continue; else break;` in the surrounding code, and this function has become larger over time.

Given the new option and related control flows added, I wonder if it's a good chance to have some code simplification like this

```
for (uint32_t I = 0; I < NumCandidates; I++) {
    uint64_t Target = ... ;
    Function *TargetFunction = Symtab->getFunction(Target);
    if (!isValidTarget(TargetFunction)) {
       if (ICPAllowCandidateSkip)
          continue;
       else
           break;
     }
}

// could be a class function or free standalone function, depending on whether
// isValidTarget needs to use class members directly or use them as parameter.
bool IndirectCallPromoter::isValidTarget(Function* Func) {
   if (Func == nullptr) { 
      ...
      return false;
   }
   if (!ICPAllowDecls && Func->isDeclaration() {
      ...
      return false;
   }
   // other invalid cases.
   ...
   return true;
}
```

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


More information about the llvm-commits mailing list