[llvm] [LLVM] Add flatten function attribute to LLVM IR and implement recursive inlining in AlwaysInliner (PR #174899)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 2 11:59:31 PST 2026
================
@@ -99,11 +110,78 @@ bool AlwaysInlineImpl(
}
}
+ // Flatten functions with the flatten attribute using a local worklist.
+ for (Function *F : NeedFlattening) {
+ SmallVector<std::pair<CallBase *, int>, 16> Worklist;
+ SmallVector<std::pair<Function *, int>, 16> InlineHistory;
+ SmallVector<CallBase *> NewCallSites;
+ OptimizationRemarkEmitter ORE(F);
+
+ // Collect initial calls.
+ for (BasicBlock &BB : *F) {
+ for (Instruction &I : BB) {
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ if (CB->getAttributes().hasFnAttr(Attribute::NoInline))
+ continue;
+ Function *Callee = CB->getCalledFunction();
+ if (!Callee || Callee->isDeclaration())
+ continue;
+ Worklist.push_back({CB, -1});
+ }
+ }
+ }
+
+ while (!Worklist.empty()) {
+ auto Item = Worklist.pop_back_val();
+ CallBase *CB = Item.first;
+ int InlineHistoryID = Item.second;
+ Function *Callee = CB->getCalledFunction();
+ if (!Callee)
+ continue;
+
+ // Detect recursion.
+ if (Callee == F ||
+ inlineHistoryIncludes(Callee, InlineHistoryID, InlineHistory)) {
+ ORE.emit([&]() {
+ return OptimizationRemarkMissed("inline", "NotInlined",
+ CB->getDebugLoc(), CB->getParent())
+ << "'" << ore::NV("Callee", Callee)
+ << "' is not inlined into '"
+ << ore::NV("Caller", CB->getCaller())
+ << "': recursive call during flattening";
+ });
+ continue;
+ }
+
+ if (Callee->isPresplitCoroutine() || !isInlineViable(*Callee).isSuccess())
+ continue;
+
+ // Check TTI for target-specific inlining restrictions (e.g., SME ABI).
+ TargetTransformInfo &TTI = GetTTI(*Callee);
+ if (!TTI.areInlineCompatible(F, Callee))
+ continue;
+
+ if (!TryInline(*CB, *Callee, ORE, "flatten attribute", &NewCallSites))
+ continue;
+
+ Changed = true;
+
+ // Add new call sites from the inlined function to the worklist.
+ if (!NewCallSites.empty()) {
+ int NewHistoryID = InlineHistory.size();
+ InlineHistory.push_back({Callee, InlineHistoryID});
+ for (CallBase *NewCB : NewCallSites) {
+ Function *NewCallee = NewCB->getCalledFunction();
+ if (NewCallee && !NewCallee->isDeclaration() &&
+ !NewCB->getAttributes().hasFnAttr(Attribute::NoInline))
+ Worklist.push_back({NewCB, NewHistoryID});
+ }
+ }
+ }
+ }
+
if (!InlinedComdatFunctions.empty()) {
- // Now we just have the comdat functions. Filter out the ones whose comdats
- // are not actually dead.
----------------
nikic wrote:
Why did these comments get dropped?
https://github.com/llvm/llvm-project/pull/174899
More information about the llvm-commits
mailing list