[llvm] [Passes][Inliner] Add separate optsize inlinehint threshold (PR #191213)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 9 08:16:56 PDT 2026


https://github.com/nikic created https://github.com/llvm/llvm-project/pull/191213

PGO pre-inlining wants to set a different inlinehint threshold when optimizing for size. Currently this is done by adjusting the InlineHint threshold based on the pipeline optimization level.

Replace this with a separate OptSizeInlineHint threshold that is applied based on attributes instead.

>From 178251293d1b3b3eb40b7789b927d0a1c49ddf5e Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 9 Apr 2026 17:13:44 +0200
Subject: [PATCH] [Passes][Inliner] Add separate optsize inlinehint threshold

PGO pre-inlining wants to set a different inlinehint threshold
when optimizing for size. Currently this is done by adjusting the
InlineHint threshold based on the pipeline optimization level.

Replace this with a separate OptSizeInlineHint threshold that is
applied based on attributes instead.
---
 llvm/include/llvm/Analysis/InlineCost.h  |  4 ++++
 llvm/lib/Analysis/InlineCost.cpp         | 11 +++++++++--
 llvm/lib/Passes/PassBuilderPipelines.cpp |  3 ++-
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/Analysis/InlineCost.h b/llvm/include/llvm/Analysis/InlineCost.h
index ae86f353f16d9..1d89296685772 100644
--- a/llvm/include/llvm/Analysis/InlineCost.h
+++ b/llvm/include/llvm/Analysis/InlineCost.h
@@ -211,6 +211,10 @@ struct InlineParams {
   /// Threshold to use for callees with inline hint.
   std::optional<int> HintThreshold;
 
+  /// Threshold to use for callees with inline hint, when the caller is
+  /// optimized for size.
+  std::optional<int> OptSizeHintThreshold;
+
   /// Threshold to use for cold callees.
   std::optional<int> ColdThreshold;
 
diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp
index e1e47b6bc0db6..2ae5cfb06d981 100644
--- a/llvm/lib/Analysis/InlineCost.cpp
+++ b/llvm/lib/Analysis/InlineCost.cpp
@@ -1319,6 +1319,7 @@ class InlineCostFeaturesAnalyzer final : public CallAnalyzer {
     if (IsIndirectCall) {
       InlineParams IndirectCallParams = {/* DefaultThreshold*/ 0,
                                          /*HintThreshold*/ {},
+                                         /*OptSizeHintThreshold*/ {},
                                          /*ColdThreshold*/ {},
                                          /*OptSizeThreshold*/ {},
                                          /*OptMinSizeThreshold*/ {},
@@ -2130,8 +2131,11 @@ void InlineCostCallAnalyzer::updateThreshold(CallBase &Call, Function &Callee) {
   // Adjust the threshold based on inlinehint attribute and profile based
   // hotness information if the caller does not have MinSize attribute.
   if (!Caller->hasMinSize()) {
+    std::optional<int> HintThreshold = Caller->hasOptSize()
+                                           ? Params.OptSizeHintThreshold
+                                           : Params.HintThreshold;
     if (Callee.hasFnAttribute(Attribute::InlineHint))
-      Threshold = MaxIfValid(Threshold, Params.HintThreshold);
+      Threshold = MaxIfValid(Threshold, HintThreshold);
 
     // FIXME: After switching to the new passmanager, simplify the logic below
     // by checking only the callsite hotness/coldness as we will reliably
@@ -2165,7 +2169,7 @@ void InlineCostCallAnalyzer::updateThreshold(CallBase &Call, Function &Callee) {
         // If callsite hotness can not be determined, we may still know
         // that the callee is hot and treat it as a weaker hint for threshold
         // increase.
-        Threshold = MaxIfValid(Threshold, Params.HintThreshold);
+        Threshold = MaxIfValid(Threshold, HintThreshold);
       } else if (PSI->isFunctionEntryCold(&Callee)) {
         LLVM_DEBUG(dbgs() << "Cold callee.\n");
         // Do not apply bonuses for a cold callee including the
@@ -3148,6 +3152,7 @@ std::optional<int> llvm::getInliningCostEstimate(
     ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE) {
   const InlineParams Params = {/* DefaultThreshold*/ 0,
                                /*HintThreshold*/ {},
+                               /*OptSizeHintThreshold*/ {},
                                /*ColdThreshold*/ {},
                                /*OptSizeThreshold*/ {},
                                /*OptMinSizeThreshold*/ {},
@@ -3387,6 +3392,8 @@ InlineParams llvm::getInlineParams(int Threshold) {
 
   // Set the HintThreshold knob from the -inlinehint-threshold.
   Params.HintThreshold = HintThreshold;
+  // Use same threshold for optsize by default.
+  Params.OptSizeHintThreshold = HintThreshold;
 
   // Set the HotCallSiteThreshold knob from the -hot-callsite-threshold.
   Params.HotCallSiteThreshold = HotCallSiteThreshold;
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 255dfa8e4e9c6..0c568bc8d4419 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -820,7 +820,8 @@ void PassBuilder::addPreInlinerPasses(ModulePassManager &MPM,
   // when not optimzing for size. This should probably be lowered after
   // performance testing.
   // FIXME: this comment is cargo culted from the old pass manager, revisit).
-  IP.HintThreshold = Level.isOptimizingForSize() ? PreInlineThreshold : 325;
+  IP.HintThreshold = 325;
+  IP.OptSizeHintThreshold = PreInlineThreshold;
   ModuleInlinerWrapperPass MIWP(
       IP, /* MandatoryFirst */ true,
       InlineContext{LTOPhase, InlinePass::EarlyInliner});



More information about the llvm-commits mailing list