From e76d79ac8284854f4f994c7a265d2529f26db408 Mon Sep 17 00:00:00 2001 From: Vasileios Porpodas Date: Thu, 27 Feb 2025 07:57:14 -0800 Subject: [PATCH] [InlineCost] Don't call collectEphemeralValues() if too many assumptions CallAnalyzer::analyze() can take several hours to run if the function contains thousands of @llvm.assume() calls. The time is spent in collectEphemeralvalues(). This patch adds a check that will disables the collection of ephemeral values if there are more assumptions than a limit controlled by the `-inline-ephval-assumptions-limit` flag. --- llvm/lib/Analysis/InlineCost.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp index c6b927c8eee2f..3c5cf984861de 100644 --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -173,6 +173,12 @@ static cl::opt DisableGEPConstOperand( "disable-gep-const-evaluation", cl::Hidden, cl::init(false), cl::desc("Disables evaluation of GetElementPtr with constant operands")); +static cl::opt EphValAssumptionsSzLimit( + "inline-ephval-assumptions-limit", cl::Hidden, cl::init(5000), + cl::desc("Collection of ephemeral values can be very expensive " + "compile-time wise, so don't collect them if the function " + "contains more than this many assumptions")); + namespace llvm { std::optional getStringFnAttrAsInt(const Attribute &Attr) { if (Attr.isValid()) { @@ -2785,7 +2791,15 @@ InlineResult CallAnalyzer::analyze() { // the ephemeral values multiple times (and they're completely determined by // the callee, so this is purely duplicate work). SmallPtrSet EphValues; - CodeMetrics::collectEphemeralValues(&F, &GetAssumptionCache(F), EphValues); + auto &AC = GetAssumptionCache(F); + // Don't collect ephemeral values if we have too many assumptions because the + // collection can be very expensive. Note that this will increase the cost of + // the function, making it less likely to be inlined. But if the function + // contains thousands of assumptions, then the chances are that it's too large + // to inline anyway. + bool TooExpensive = AC.assumptions().size() > EphValAssumptionsSzLimit; + if (!TooExpensive) + CodeMetrics::collectEphemeralValues(&F, &AC, EphValues); // The worklist of live basic blocks in the callee *after* inlining. We avoid // adding basic blocks of the callee which can be proven to be dead for this