[llvm] [FuncAttrs][LTO] Relax norecurse attribute inference during postlink LTO (PR #158608)

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 22 06:45:04 PDT 2025


================
@@ -2429,3 +2445,62 @@ ReversePostOrderFunctionAttrsPass::run(Module &M, ModuleAnalysisManager &AM) {
   PA.preserve<LazyCallGraphAnalysis>();
   return PA;
 }
+
+PreservedAnalyses NoRecurseLTOInferencePass::run(Module &M,
+                                                 ModuleAnalysisManager &MAM) {
+
+  // Check if any function in the whole program has its address taken or has
+  // potentially external linkage.
+  // We use this information when inferring norecurse attribute: If there is
+  // no function whose address is taken and all functions have internal
+  // linkage, there is no path for a callback to any user function.
+  bool AnyFunctionsAddressIsTaken = false;
+  for (Function &F : M) {
+    if (F.isDeclaration() || F.doesNotRecurse())
+      continue;
+    if (!F.hasLocalLinkage() || F.hasAddressTaken()) {
+      AnyFunctionsAddressIsTaken = true;
+      break;
+    }
+  }
+
+  // Run norecurse inference on all RefSCCs in the LazyCallGraph for this
+  // module.
+  bool Changed = false;
+  LazyCallGraph &CG = MAM.getResult<LazyCallGraphAnalysis>(M);
+  CG.buildRefSCCs();
+
+  for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs()) {
+    // Skip any RefSCC that is part of a call cycle. A RefSCC containing more
+    // than one SCC indicates a recursive relationship, which could involve
+    // direct or indirect calls.
+    if (RC.size() > 1)
+      continue;
+
+    // A single-SCC RefSCC could still be a self-loop.
----------------
david-arm wrote:

If a SCC has more than one component doesn't that just mean that there are N functions that can all reach each other? i.e.

foo1 -> foo2 - > foo3 -> foo1 ...

so I'm not sure what the `self-loop` comment refers to here. Are you suggesting that if the size is 1 then it still could be a self-loop? If so, perhaps it's clearer to move the comment after the `S.size() > 1` check?

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


More information about the llvm-commits mailing list