[llvm] [GlobalOpt] Skip cold call analysis when no function can use coldcc (PR #227944)

Malavika Samak via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 20:55:52 PDT 2026


https://github.com/malavikasamak updated https://github.com/llvm/llvm-project/pull/227944

>From 024cf73e9ec2ed2fc935707a65be03b6747dc34e Mon Sep 17 00:00:00 2001
From: mmalavika <mmalavika at nvidia.com>
Date: Wed, 30 Sep 2026 22:06:28 +0000
Subject: [PATCH] [GlobalOpt] Skip cold call analysis when no function can use
 coldcc

OptimizeFunctions() starts by calling hasOnlyColdCalls() on every
function in the module to find functions whose callers are all cold.
That analysis needs BlockFrequencyInfo for each caller and can be
expensive on large modules.

The result is only used to switch functions to the cold calling
convention, which happens only if TargetTransformInfo::
useColdCCForColdCall() returns true for the function (or if
-enable-coldcc-stress-test is set). On targets where that hook never
returns true, the analysis is wasted work.

Add a cheap pre-scan that asks TTI whether any non-intrinsic function
in the module can use coldcc, and only run the hasOnlyColdCalls() loop
if one can, or if the stress-test flag is set. The pre-scan stops at
the first match.

This is a compile-time improvement only; there is no change in output.
The new loop cannot be fused with the existing one, since the existing
loop must be skipped entirely when the pre-scan finds nothing.
---
 llvm/lib/Transforms/IPO/GlobalOpt.cpp | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index 36563e25cc7f75..23dd5a175c5da1 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1926,9 +1926,22 @@ OptimizeFunctions(Module &M,
 
   ChangeableCCCacheTy ChangeableCCCache;
   std::vector<Function *> AllCallsCold;
-  for (Function &F : llvm::make_early_inc_range(M))
-    if (hasOnlyColdCalls(F, GetBFI, ChangeableCCCache))
-      AllCallsCold.push_back(&F);
+  // This is a preprocessing step to determine if any function in the module
+  // can use Cold calling convention. This is supposed to help compile time
+  // on targets that do not use Cold for any function. Note this loop cannot
+  // be fused with the following loop.
+  bool CanUseColdCCForAnyColdCall = false;
+  for (Function &F : llvm::make_early_inc_range(M)) {
+    if (!F.isIntrinsic() && GetTTI(F).useColdCCForColdCall(F)) {
+      CanUseColdCCForAnyColdCall = true;
+      break;
+    }
+  }
+
+  if (EnableColdCCStressTest || CanUseColdCCForAnyColdCall)
+    for (Function &F : llvm::make_early_inc_range(M))
+      if (hasOnlyColdCalls(F, GetBFI, ChangeableCCCache))
+        AllCallsCold.push_back(&F);
 
   // Optimize functions.
   for (Function &F : llvm::make_early_inc_range(M)) {



More information about the llvm-commits mailing list