Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5573,14 +5573,7 @@ bool Compiler::optLoopComplexityExceeds(FlowGraphNaturalLoop* loop, unsigned lim
: 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;
return (result == BasicBlockVisit::Abort);
}

/*****************************************************************************/
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/loopcloning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3108,6 +3108,7 @@ PhaseStatus Compiler::optCloneLoops()
// then the method returns false.
else if ((sizeLimit >= 0) && optLoopComplexityExceeds(loop, (unsigned)sizeLimit, countNode))
{
JITDUMP(FMT_LP " exceeds cloning size limit %d\n", loop->GetIndex(), sizeLimit);
context.CancelLoopOptInfo(loop->GetIndex());
}
}
Expand Down
45 changes: 38 additions & 7 deletions src/coreclr/jit/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1903,14 +1903,45 @@ 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();
auto countNode = [](GenTree* tree) -> unsigned {
return 1;
};
const int invertSizeLimit = JitConfig.JitLoopInversionSizeLimit();
if (invertSizeLimit >= 0)
{
const int cloneSizeLimit = JitConfig.JitCloneLoopsSizeLimit();
bool mightBenefitFromCloning = false;
unsigned loopSize = 0;

// Loops with bounds checks can benefit from cloning, which depends on inversion running.
// Thus, we will try to proceed with inversion for slightly oversize loops if they show potential for cloning.
auto countNode = [&mightBenefitFromCloning, &loopSize](GenTree* tree) -> unsigned {
mightBenefitFromCloning |= tree->OperIs(GT_BOUNDS_CHECK);
loopSize++;
return 1;
};

if ((sizeLimit >= 0) && optLoopComplexityExceeds(loop, (unsigned)sizeLimit, countNode))
{
return false;
optLoopComplexityExceeds(loop, (unsigned)max(invertSizeLimit, cloneSizeLimit), countNode);
if (loopSize > (unsigned)invertSizeLimit)
{
// Don't try to invert oversize loops if they don't show cloning potential,
// or if they're too big to be cloned anyway.
JITDUMP(FMT_LP " exceeds inversion size limit of %d\n", loop->GetIndex(), invertSizeLimit);
const bool tooBigToClone = (cloneSizeLimit >= 0) && (loopSize > (unsigned)cloneSizeLimit);
if (!mightBenefitFromCloning || tooBigToClone)
{
JITDUMP("No inversion for " FMT_LP ": %s\n", loop->GetIndex(),
tooBigToClone ? "too big to clone" : "unlikely to benefit from cloning");
return false;
}

// If the loop shows cloning potential, tolerate some excess size.
const unsigned liberalInvertSizeLimit = (unsigned)(invertSizeLimit * 1.25);
if (loopSize > liberalInvertSizeLimit)
{
JITDUMP(FMT_LP " might benefit from cloning, but is too large to invert.\n", loop->GetIndex());
return false;
}

JITDUMP(FMT_LP " might benefit from cloning. Continuing.\n", loop->GetIndex());
}
}

unsigned estDupCostSz = 0;
Expand Down
Loading