Skip to content

Commit 8f47439

Browse files
committed
PerformanceInliner: disable shortest-path-analysis for huge functions.
As the complexity of the analysis is more than linear with the number of blocks, disable it for functions with > 2000 basic blocks. In this case inlining will be less aggressive. SR-10209 rdar://problem/49522869
1 parent 4e9a9cc commit 8f47439

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

include/swift/SILOptimizer/Utils/PerformanceInlinerUtils.h

+15-2
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ class ShortestPathAnalysis {
312312
SILLoopInfo *LI;
313313
llvm::DenseMap<const SILBasicBlock *, BlockInfo *> BlockInfos;
314314
std::vector<BlockInfo> BlockInfoStorage;
315+
bool valid = false;
315316

316317
BlockInfo *getBlockInfo(const SILBasicBlock *BB) {
317318
BlockInfo *BI = BlockInfos[BB];
@@ -381,15 +382,22 @@ class ShortestPathAnalysis {
381382
public:
382383
ShortestPathAnalysis(SILFunction *F, SILLoopInfo *LI) : F(F), LI(LI) { }
383384

384-
bool isValid() const { return !BlockInfos.empty(); }
385+
bool isValid() const { return valid; }
385386

386387
/// Compute the distances. The function \p getApplyLength returns the length
387388
/// of a function call.
388389
template <typename Func>
389390
void analyze(ColdBlockInfo &CBI, Func getApplyLength) {
390391
assert(!isValid());
392+
valid = true;
393+
unsigned numBlocks = F->size();
391394

392-
BlockInfoStorage.resize(F->size());
395+
// As the complexity of the analysis is more than linear with the number of blocks,
396+
// disable it for huge functions. In this case inlining will be less aggressive.
397+
if (numBlocks > 2000)
398+
return;
399+
400+
BlockInfoStorage.resize(numBlocks);
393401

394402
// First step: compute the length of the blocks.
395403
unsigned BlockIdx = 0;
@@ -433,6 +441,11 @@ class ShortestPathAnalysis {
433441
/// shortest path in the function.
434442
int getScopeLength(SILBasicBlock *BB, int LoopDepth) {
435443
assert(BB->getParent() == F);
444+
445+
// Return a conservative default if the analysis was not done due to a high number of blocks.
446+
if (BlockInfos.empty())
447+
return ColdBlockLength;
448+
436449
if (LoopDepth >= MaxNumLoopLevels)
437450
LoopDepth = MaxNumLoopLevels - 1;
438451
return getBlockInfo(BB)->getScopeLength(LoopDepth);

lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,10 @@ ShortestPathAnalysis::Weight ShortestPathAnalysis::
418418
getWeight(SILBasicBlock *BB, Weight CallerWeight) {
419419
assert(BB->getParent() == F);
420420

421+
// Return a conservative default if the analysis was not done due to a high number of blocks.
422+
if (BlockInfos.empty())
423+
return Weight(CallerWeight.ScopeLength + ColdBlockLength, CallerWeight.LoopWeight);
424+
421425
SILLoop *Loop = LI->getLoopFor(BB);
422426
if (!Loop) {
423427
// We are not in a loop. So just account the length of our function scope

0 commit comments

Comments
 (0)