[llvm] [FuncAttrs][LTO] Relax norecurse attribute inference during postlink LTO (PR #158608)
Usha Gupta via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 26 03:35:24 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.
----------------
usha1830 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?
yes. That's right. I will update the comment to be clearer.
RefSCC nodes are SCCs and not individual functions. An edge in RefSCC indicates indirect call to functions between the connected SCCs. So we are first filtering out based on RefSCC size, >1 means there is indirect call/address taken.
https://github.com/llvm/llvm-project/pull/158608
More information about the llvm-commits
mailing list