From d3582c02db7ef546f33abd229f5b916b8b0b494c Mon Sep 17 00:00:00 2001 From: "Aman Khalid (from Dev Box)" Date: Thu, 24 Jul 2025 18:16:34 -0400 Subject: [PATCH 1/5] Rework *ComplexityExceeds helpers --- src/coreclr/jit/block.cpp | 76 ----------- src/coreclr/jit/block.h | 7 +- src/coreclr/jit/compiler.h | 11 +- src/coreclr/jit/compiler.hpp | 176 ++++++++++++++++++++++++++ src/coreclr/jit/forwardsub.cpp | 7 +- src/coreclr/jit/gentree.cpp | 59 --------- src/coreclr/jit/loopcloning.cpp | 6 +- src/coreclr/jit/morph.cpp | 11 +- src/coreclr/jit/objectalloc.cpp | 10 +- src/coreclr/jit/optimizer.cpp | 47 +------ src/coreclr/jit/rangecheckcloning.cpp | 9 +- 11 files changed, 222 insertions(+), 197 deletions(-) diff --git a/src/coreclr/jit/block.cpp b/src/coreclr/jit/block.cpp index f26d452e8e2887..17b6734890e2ef 100644 --- a/src/coreclr/jit/block.cpp +++ b/src/coreclr/jit/block.cpp @@ -1735,79 +1735,3 @@ bool BasicBlock::StatementCountExceeds(unsigned limit, unsigned* count /* = null return overLimit; } - -//------------------------------------------------------------------------ -// ComplexityExceeds: check if the number of nodes in the trees in the block -// exceeds some limit -// -// Arguments: -// comp - compiler instance -// limit - limit on the number of nodes -// count - [out, optional] actual number of nodes (if less than or equal to limit) -// -// Returns: -// true if the number of nodes is greater than limit -// -bool BasicBlock::ComplexityExceeds(Compiler* comp, unsigned limit, unsigned* count /* = nullptr */) -{ - unsigned localCount = 0; - bool overLimit = false; - - for (Statement* const stmt : Statements()) - { - unsigned slack = limit - localCount; - unsigned actual = 0; - if (comp->gtComplexityExceeds(stmt->GetRootNode(), slack, &actual)) - { - overLimit = true; - break; - } - - localCount += actual; - } - - if (count != nullptr) - { - *count = localCount; - } - - return overLimit; -} - -//------------------------------------------------------------------------ -// ComplexityExceeds: check if the number of nodes in the trees in the blocks -// in the range exceeds some limit -// -// Arguments: -// comp - compiler instance -// limit - limit on the number of nodes -// count - [out, optional] actual number of nodes (if less than or equal to limit) -// -// Returns: -// true if the number of nodes is greater than limit -// -bool BasicBlockRangeList::ComplexityExceeds(Compiler* comp, unsigned limit, unsigned* count /* = nullptr */) -{ - unsigned localCount = 0; - bool overLimit = false; - - for (BasicBlock* const block : *this) - { - unsigned slack = limit - localCount; - unsigned actual = 0; - if (block->ComplexityExceeds(comp, slack, &actual)) - { - overLimit = true; - break; - } - - localCount += actual; - } - - if (count != nullptr) - { - *count = localCount; - } - - return overLimit; -} diff --git a/src/coreclr/jit/block.h b/src/coreclr/jit/block.h index fd70cf59b00b53..626f1d370b4fdd 100644 --- a/src/coreclr/jit/block.h +++ b/src/coreclr/jit/block.h @@ -1779,7 +1779,9 @@ struct BasicBlock : private LIR::Range // unsigned StatementCount(); bool StatementCountExceeds(unsigned limit, unsigned* count = nullptr); - bool ComplexityExceeds(Compiler* comp, unsigned limit, unsigned* complexity = nullptr); + + template + bool ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTreeComplexity); GenTree* lastNode() const; @@ -2086,7 +2088,8 @@ class BasicBlockRangeList return BasicBlockIterator(m_end->Next()); // walk until we see the block *following* the `m_end` block } - bool ComplexityExceeds(Compiler* comp, unsigned limit, unsigned* count = nullptr); + template + bool ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTreeComplexity); }; // BBJumpTable -- descriptor blocks with N successors diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index cd353b724c0a51..d1c1f3c3fb9687 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3603,11 +3603,11 @@ class Compiler void gtUpdateNodeOperSideEffects(GenTree* tree); - // Returns "true" iff the complexity (not formally defined, but first interpretation - // is #of nodes in subtree) of "tree" is greater than "limit". + // Returns "true" iff the complexity (defined by 'getComplexity') of "tree" is greater than "limit". // (This is somewhat redundant with the "GetCostEx()/GetCostSz()" fields, but can be used - // before they have been set.) - bool gtComplexityExceeds(GenTree* tree, unsigned limit, unsigned* complexity = nullptr); + // before they have been set, if 'getComplexity' is independent of them.) + template + bool gtComplexityExceeds(GenTree* tree, unsigned limit, TFunc getComplexity); GenTree* gtReverseCond(GenTree* tree); @@ -7012,7 +7012,8 @@ class Compiler bool optCanonicalizeExits(FlowGraphNaturalLoop* loop); bool optCanonicalizeExit(FlowGraphNaturalLoop* loop, BasicBlock* exit); - bool optLoopComplexityExceeds(FlowGraphNaturalLoop* loop, unsigned limit); + template + bool optLoopComplexityExceeds(FlowGraphNaturalLoop* loop, unsigned limit, TFunc getTreeComplexity); PhaseStatus optCloneLoops(); PhaseStatus optRangeCheckCloning(); diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 5d271f8c714311..1b2c007a4f34fb 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -5387,6 +5387,182 @@ BasicBlockVisit FlowGraphNaturalLoop::VisitRegularExitBlocks(TFunc func) return BasicBlockVisit::Continue; } +//----------------------------------------------------------- +// gtComplexityExceeds: Check if a tree exceeds a specified complexity limit. +// +// Type parameters: +// TFunc - Callback functor type + +// Arguments: +// comp - compiler instance +// limit - complexity limit +// getTreeComplexity - Callback functor that takes a GenTree* and returns its complexity +// +// Return Value: +// True if 'tree' exceeds the complexity limit, otherwise false. +// +template +bool Compiler::gtComplexityExceeds(GenTree* tree, unsigned limit, TFunc getComplexity) +{ + struct ComplexityVisitor : GenTreeVisitor + { + enum + { + DoPreOrder = true, + }; + + ComplexityVisitor(Compiler* comp, unsigned limit, TFunc getComplexity) + : GenTreeVisitor(comp) + , m_complexity(0) + , m_limit(limit) + , m_getComplexity(getComplexity) + { + } + + fgWalkResult PreOrderVisit(GenTree** use, GenTree* user) + { + m_complexity += m_getComplexity(*use); + return (m_complexity > m_limit) ? WALK_ABORT : WALK_CONTINUE; + } + + private: + unsigned m_complexity; + const unsigned m_limit; + TFunc m_getComplexity; + }; + + assert(tree != nullptr); + + ComplexityVisitor visitor(this, limit, getComplexity); + + fgWalkResult result = visitor.WalkTree(&tree, nullptr); + + return (result == WALK_ABORT); +} + +//------------------------------------------------------------------------ +// ComplexityExceeds: Check if the trees in a block exceed a specified complexity limit. +// +// Type parameters: +// TFunc - Callback functor type +// +// Arguments: +// comp - compiler instance +// limit - complexity limit +// getTreeComplexity - Callback functor that takes a GenTree* and returns its complexity +// +// Returns: +// True if the trees in the block exceed the complexity limit, otherwise false. +// +template +bool BasicBlock::ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTreeComplexity) +{ + assert(comp != nullptr); + + unsigned localCount = 0; + bool overLimit = false; + auto getComplexity = [&](GenTree* tree) -> unsigned { + const unsigned treeComplexity = getTreeComplexity(tree); + localCount += treeComplexity; + return treeComplexity; + }; + + for (Statement* const stmt : Statements()) + { + const unsigned slack = limit - localCount; + if (comp->gtComplexityExceeds(stmt->GetRootNode(), slack, getComplexity)) + { + overLimit = true; + break; + } + } + + return overLimit; +} + +//------------------------------------------------------------------------ +// ComplexityExceeds: Check if the trees in a range of blocks exceed a specified complexity limit. +// +// Type parameters: +// TFunc - Callback functor type +// +// Arguments: +// comp - compiler instance +// limit - complexity limit +// getTreeComplexity - Callback functor that takes a GenTree* and returns its complexity +// +// Returns: +// True if the trees in the block range exceed the complexity limit, otherwise false. +// +template +bool BasicBlockRangeList::ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTreeComplexity) +{ + assert(comp != nullptr); + + unsigned localCount = 0; + bool overLimit = false; + auto getComplexity = [&](GenTree* tree) -> unsigned { + const unsigned treeComplexity = getTreeComplexity(tree); + localCount += treeComplexity; + return treeComplexity; + }; + + for (BasicBlock* const block : *this) + { + const unsigned slack = limit - localCount; + if (block->ComplexityExceeds(comp, slack, getComplexity)) + { + overLimit = true; + break; + } + } + + return overLimit; +} + +//------------------------------------------------------------------------ +// optLoopComplexityExceeds: Check if the trees in a loop exceed a specified complexity limit. +// +// Type parameters: +// TFunc - Callback functor type +// +// Arguments: +// comp - compiler instance +// limit - complexity limit +// getTreeComplexity - Callback functor that takes a GenTree* and returns its complexity +// +// Returns: +// True if the trees in 'loop' exceed the complexity limit, otherwise false. +// +template +bool Compiler::optLoopComplexityExceeds(FlowGraphNaturalLoop* loop, unsigned limit, TFunc getTreeComplexity) +{ + assert(loop != nullptr); + + unsigned loopComplexity = 0; + auto getComplexity = [&](GenTree* tree) -> unsigned { + const unsigned treeComplexity = getTreeComplexity(tree); + loopComplexity += treeComplexity; + return treeComplexity; + }; + + BasicBlockVisit const result = loop->VisitLoopBlocks([&](BasicBlock* block) { + assert(limit >= loopComplexity); + const unsigned slack = limit - loopComplexity; + return block->ComplexityExceeds(this, slack, getComplexity) ? BasicBlockVisit::Abort + : BasicBlockVisit::Continue; + }); + + if (result == BasicBlockVisit::Abort) + { + JITDUMP("Loop " FMT_LP ": exceeds complexity limit %u\n", loop->GetIndex(), limit); + return true; + } + + JITDUMP("Loop " FMT_LP ": complexity %u does not exceed limit %u\n", loop->GetIndex(), loopComplexity, limit); + return false; +} + /*****************************************************************************/ #endif //_COMPILER_HPP_ /*****************************************************************************/ diff --git a/src/coreclr/jit/forwardsub.cpp b/src/coreclr/jit/forwardsub.cpp index 8bfa7af4f245c0..e67959aa7c981f 100644 --- a/src/coreclr/jit/forwardsub.cpp +++ b/src/coreclr/jit/forwardsub.cpp @@ -569,8 +569,11 @@ bool Compiler::fgForwardSubStatement(Statement* stmt) // Consider instead using the height of the fwdSubNode. // unsigned const nodeLimit = 16; + auto countNode = [](GenTree* tree) -> unsigned { + return 1; + }; - if (gtComplexityExceeds(fwdSubNode, nodeLimit)) + if (gtComplexityExceeds(fwdSubNode, nodeLimit, countNode)) { JITDUMP(" tree to sub has more than %u nodes\n", nodeLimit); return false; @@ -633,7 +636,7 @@ bool Compiler::fgForwardSubStatement(Statement* stmt) // height of the fwdSubNode. // unsigned const nextTreeLimit = 200; - if ((fsv.GetComplexity() > nextTreeLimit) && gtComplexityExceeds(fwdSubNode, 1)) + if ((fsv.GetComplexity() > nextTreeLimit) && gtComplexityExceeds(fwdSubNode, 1, countNode)) { JITDUMP(" next stmt tree is too large (%u)\n", fsv.GetComplexity()); return false; diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 3edac296301db0..f1bf95498d4823 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -17825,65 +17825,6 @@ ExceptionSetFlags Compiler::gtCollectExceptions(GenTree* tree) return walker.GetFlags(); } -//----------------------------------------------------------- -// gtComplexityExceeds: Check if a tree exceeds a specified complexity in terms -// of number of sub nodes. -// -// Arguments: -// tree - The tree to check -// limit - The limit in terms of number of nodes -// complexity - [out, optional] the actual node count (if not greater than limit) -// -// Return Value: -// True if there are more than limit nodes in tree; otherwise false. -// -bool Compiler::gtComplexityExceeds(GenTree* tree, unsigned limit, unsigned* complexity) -{ - struct ComplexityVisitor : GenTreeVisitor - { - enum - { - DoPreOrder = true, - }; - - ComplexityVisitor(Compiler* comp, unsigned limit) - : GenTreeVisitor(comp) - , m_limit(limit) - { - } - - fgWalkResult PreOrderVisit(GenTree** use, GenTree* user) - { - if (++m_numNodes > m_limit) - { - return WALK_ABORT; - } - - return WALK_CONTINUE; - } - - unsigned NumNodes() - { - return m_numNodes; - } - - private: - unsigned m_limit; - unsigned m_numNodes = 0; - }; - - ComplexityVisitor visitor(this, limit); - - fgWalkResult result = visitor.WalkTree(&tree, nullptr); - - if (complexity != nullptr) - { - *complexity = visitor.NumNodes(); - } - - return (result == WALK_ABORT); -} - bool GenTree::IsPhiNode() { return (OperGet() == GT_PHI_ARG) || (OperGet() == GT_PHI) || IsPhiDefn(); diff --git a/src/coreclr/jit/loopcloning.cpp b/src/coreclr/jit/loopcloning.cpp index 35d64494cbef2c..6ef535a4cd8e27 100644 --- a/src/coreclr/jit/loopcloning.cpp +++ b/src/coreclr/jit/loopcloning.cpp @@ -3080,6 +3080,10 @@ PhaseStatus Compiler::optCloneLoops() bool allTrue = false; bool anyFalse = false; const int sizeLimit = JitConfig.JitCloneLoopsSizeLimit(); + auto countNode = [](GenTree* tree) -> unsigned { + return 1; + }; + context.EvaluateConditions(loop->GetIndex(), &allTrue, &anyFalse DEBUGARG(verbose)); if (anyFalse) { @@ -3102,7 +3106,7 @@ PhaseStatus Compiler::optCloneLoops() // tree nodes in all statements in all blocks in the loop. // This value is compared to a hard-coded threshold, and if bigger, // then the method returns false. - else if ((sizeLimit >= 0) && optLoopComplexityExceeds(loop, (unsigned)sizeLimit)) + else if ((sizeLimit >= 0) && optLoopComplexityExceeds(loop, (unsigned)sizeLimit, countNode)) { context.CancelLoopOptInfo(loop->GetIndex()); } diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 84a5de5a58f6df..71df5d9c42779e 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -2974,8 +2974,11 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) // If we're doing range checking, introduce a GT_BOUNDS_CHECK node for the address. if (indexAddr->IsBoundsChecked()) { - GenTree* arrRef2 = nullptr; // The second copy will be used in array address expression - GenTree* index2 = nullptr; + GenTree* arrRef2 = nullptr; // The second copy will be used in array address expression + GenTree* index2 = nullptr; + auto countNode = [](GenTree* node) -> unsigned { + return 1; + }; // If the arrRef or index expressions involves a store, a call, or reads from global memory, // then we *must* allocate a temporary in which to "localize" those values, to ensure that the @@ -2987,7 +2990,7 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) // TODO-Bug: GLOB_REF is not yet set for all trees in pre-order morph. // if (((arrRef->gtFlags & (GTF_ASG | GTF_CALL | GTF_GLOB_REF)) != 0) || - gtComplexityExceeds(arrRef, MAX_ARR_COMPLEXITY) || arrRef->OperIs(GT_LCL_FLD) || + gtComplexityExceeds(arrRef, MAX_ARR_COMPLEXITY, countNode) || arrRef->OperIs(GT_LCL_FLD) || (arrRef->OperIs(GT_LCL_VAR) && lvaIsLocalImplicitlyAccessedByRef(arrRef->AsLclVar()->GetLclNum()))) { unsigned arrRefTmpNum = lvaGrabTemp(true DEBUGARG("arr expr")); @@ -3002,7 +3005,7 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) } if (((index->gtFlags & (GTF_ASG | GTF_CALL | GTF_GLOB_REF)) != 0) || - gtComplexityExceeds(index, MAX_INDEX_COMPLEXITY) || index->OperIs(GT_LCL_FLD) || + gtComplexityExceeds(index, MAX_INDEX_COMPLEXITY, countNode) || index->OperIs(GT_LCL_FLD) || (index->OperIs(GT_LCL_VAR) && lvaIsLocalImplicitlyAccessedByRef(index->AsLclVar()->GetLclNum()))) { unsigned indexTmpNum = lvaGrabTemp(true DEBUGARG("index expr")); diff --git a/src/coreclr/jit/objectalloc.cpp b/src/coreclr/jit/objectalloc.cpp index 0b5a62f3400a36..fe885c15b1c09c 100644 --- a/src/coreclr/jit/objectalloc.cpp +++ b/src/coreclr/jit/objectalloc.cpp @@ -3613,22 +3613,24 @@ bool ObjectAllocator::ShouldClone(CloneInfo* info) unsigned const sizeLimit = (sizeConfig >= 0) ? (unsigned)sizeConfig : UINT_MAX; unsigned size = 0; bool shouldClone = true; + auto countNode = [&size](GenTree* tree) -> unsigned { + size++; + return 1; + }; for (BasicBlock* const block : *info->m_blocksToClone) { // Note this overstates the size a bit since we'll resolve GDVs // in the clone and the original... // - unsigned const slack = sizeLimit - size; - unsigned blockSize = 0; - if (block->ComplexityExceeds(comp, slack, &blockSize)) + unsigned const slack = sizeLimit - size; + if (block->ComplexityExceeds(comp, slack, countNode)) { JITDUMP("Rejecting"); JITDUMPEXEC(DumpIndex(info->m_pseudoIndex)); JITDUMP(" cloning: exceeds size limit %u\n", sizeLimit); return false; } - size += blockSize; } // TODO: some kind of profile check... diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index 94e31393dd5b79..b13a80d6a022ef 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -1904,7 +1904,11 @@ bool Compiler::optTryInvertWhileLoop(FlowGraphNaturalLoop* loop) // Check if loop is small enough to consider for inversion. // Large loops are less likely to benefit from inversion. const int sizeLimit = JitConfig.JitLoopInversionSizeLimit(); - if ((sizeLimit >= 0) && optLoopComplexityExceeds(loop, (unsigned)sizeLimit)) + auto countNode = [](GenTree* tree) -> unsigned { + return 1; + }; + + if ((sizeLimit >= 0) && optLoopComplexityExceeds(loop, (unsigned)sizeLimit, countNode)) { return false; } @@ -2864,47 +2868,6 @@ bool Compiler::optCanonicalizeExit(FlowGraphNaturalLoop* loop, BasicBlock* exit) return true; } -//------------------------------------------------------------------------ -// optLoopComplexityExceeds: Check if the number of nodes in the loop exceeds some limit -// -// Arguments: -// loop - the loop to compute the number of nodes in -// limit - limit on the number of nodes -// -// Returns: -// true if the number of nodes exceeds the limit -// -bool Compiler::optLoopComplexityExceeds(FlowGraphNaturalLoop* loop, unsigned limit) -{ - assert(loop != nullptr); - - // See if loop size exceeds the limit. - // - unsigned size = 0; - - BasicBlockVisit const result = loop->VisitLoopBlocks([this, limit, &size](BasicBlock* block) { - assert(limit >= size); - unsigned const slack = limit - size; - unsigned blockSize = 0; - if (block->ComplexityExceeds(this, slack, &blockSize)) - { - return BasicBlockVisit::Abort; - } - - size += blockSize; - return BasicBlockVisit::Continue; - }); - - if (result == BasicBlockVisit::Abort) - { - JITDUMP("Loop " FMT_LP ": exceeds size limit %u\n", loop->GetIndex(), limit); - return true; - } - - JITDUMP("Loop " FMT_LP ": size %u does not exceed size limit %u\n", loop->GetIndex(), size, limit); - return false; -} - //----------------------------------------------------------------------------- // optSetWeightForPreheaderOrExit: Set the weight of a newly created preheader // or exit, after it has been added to the flowgraph. diff --git a/src/coreclr/jit/rangecheckcloning.cpp b/src/coreclr/jit/rangecheckcloning.cpp index 95458ac5703fdf..15b864630f90f0 100644 --- a/src/coreclr/jit/rangecheckcloning.cpp +++ b/src/coreclr/jit/rangecheckcloning.cpp @@ -443,8 +443,13 @@ static bool DoesComplexityExceed(Compiler* comp, ArrayStack* bn GenTree* rootNode = currentStmt->GetRootNode(); if (rootNode != nullptr) { - unsigned actual = 0; - if (comp->gtComplexityExceeds(rootNode, budget, &actual)) + unsigned actual = 0; + auto countNode = [&actual](GenTree* tree) -> unsigned { + actual++; + return 1; + }; + + if (comp->gtComplexityExceeds(rootNode, budget, countNode)) { JITDUMP("\tExceeded budget!"); return true; From 9aa76ae7459a18e11f3582e9e25408003a2e4f1b Mon Sep 17 00:00:00 2001 From: "Aman Khalid (from Dev Box)" Date: Thu, 24 Jul 2025 18:27:36 -0400 Subject: [PATCH 2/5] Fix comment --- src/coreclr/jit/compiler.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 1b2c007a4f34fb..eafa35ce547fa4 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -5394,7 +5394,7 @@ BasicBlockVisit FlowGraphNaturalLoop::VisitRegularExitBlocks(TFunc func) // TFunc - Callback functor type // Arguments: -// comp - compiler instance +// tree - The tree to check // limit - complexity limit // getTreeComplexity - Callback functor that takes a GenTree* and returns its complexity // From a9d390203cfc4ac7da194b5ac3259518d9934435 Mon Sep 17 00:00:00 2001 From: "Aman Khalid (from Dev Box)" Date: Thu, 24 Jul 2025 19:35:15 -0400 Subject: [PATCH 3/5] Fix build --- src/coreclr/jit/compiler.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index eafa35ce547fa4..c535ccaeacba81 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -5412,7 +5412,7 @@ bool Compiler::gtComplexityExceeds(GenTree* tree, unsigned limit, TFunc getCompl }; ComplexityVisitor(Compiler* comp, unsigned limit, TFunc getComplexity) - : GenTreeVisitor(comp) + : GenTreeVisitor(comp) , m_complexity(0) , m_limit(limit) , m_getComplexity(getComplexity) From e73d659cda1b2f4ce41085ab978b4b210ed084c0 Mon Sep 17 00:00:00 2001 From: "Aman Khalid (from Dev Box)" Date: Fri, 25 Jul 2025 10:46:07 -0400 Subject: [PATCH 4/5] Feedback --- src/coreclr/jit/compiler.hpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index c535ccaeacba81..0ceccbf77f58a7 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -5472,8 +5472,7 @@ bool BasicBlock::ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTree const unsigned slack = limit - localCount; if (comp->gtComplexityExceeds(stmt->GetRootNode(), slack, getComplexity)) { - overLimit = true; - break; + return true; } } @@ -5512,8 +5511,7 @@ bool BasicBlockRangeList::ComplexityExceeds(Compiler* comp, unsigned limit, TFun const unsigned slack = limit - localCount; if (block->ComplexityExceeds(comp, slack, getComplexity)) { - overLimit = true; - break; + return true; } } From c5d77bcec4b9c935919ceee921cc2e3e60e40e22 Mon Sep 17 00:00:00 2001 From: "Aman Khalid (from Dev Box)" Date: Fri, 25 Jul 2025 10:47:22 -0400 Subject: [PATCH 5/5] More cleanup --- src/coreclr/jit/compiler.hpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 0ceccbf77f58a7..02fdb3af69d22e 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -5460,7 +5460,6 @@ bool BasicBlock::ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTree assert(comp != nullptr); unsigned localCount = 0; - bool overLimit = false; auto getComplexity = [&](GenTree* tree) -> unsigned { const unsigned treeComplexity = getTreeComplexity(tree); localCount += treeComplexity; @@ -5476,7 +5475,7 @@ bool BasicBlock::ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTree } } - return overLimit; + return false; } //------------------------------------------------------------------------ @@ -5499,7 +5498,6 @@ bool BasicBlockRangeList::ComplexityExceeds(Compiler* comp, unsigned limit, TFun assert(comp != nullptr); unsigned localCount = 0; - bool overLimit = false; auto getComplexity = [&](GenTree* tree) -> unsigned { const unsigned treeComplexity = getTreeComplexity(tree); localCount += treeComplexity; @@ -5515,7 +5513,7 @@ bool BasicBlockRangeList::ComplexityExceeds(Compiler* comp, unsigned limit, TFun } } - return overLimit; + return false; } //------------------------------------------------------------------------