Skip to content

Commit 9cfa97b

Browse files
authored
Merge pull request #23950 from eeckstein/fix-compile-time-5.1
[5.1] SILOptimizer: some compile time fixes
2 parents 8f7969b + 554459c commit 9cfa97b

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed

include/swift/SILOptimizer/Utils/PerformanceInlinerUtils.h

Lines changed: 15 additions & 2 deletions
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/Transforms/SimplifyCFG.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ namespace {
8181

8282
ConstantFolder ConstFolder;
8383

84+
// True if the function has a large amount of blocks. In this case we turn off some expensive
85+
// optimizations.
86+
bool isVeryLargeFunction = false;
87+
8488
void constFoldingCallback(SILInstruction *I) {
8589
// If a terminal instruction gets constant folded (like cond_br), it
8690
// enables further simplify-CFG optimizations.
@@ -1226,11 +1230,13 @@ bool SimplifyCFG::simplifyBranchBlock(BranchInst *BI) {
12261230
if (DestBB->getArgument(i) != BI->getArg(i)) {
12271231
SILValue Val = BI->getArg(i);
12281232
DestBB->getArgument(i)->replaceAllUsesWith(Val);
1229-
if (auto *I = dyn_cast<SingleValueInstruction>(Val)) {
1230-
// Replacing operands may trigger constant folding which then could
1231-
// trigger other simplify-CFG optimizations.
1232-
ConstFolder.addToWorklist(I);
1233-
ConstFolder.processWorkList();
1233+
if (!isVeryLargeFunction) {
1234+
if (auto *I = dyn_cast<SingleValueInstruction>(Val)) {
1235+
// Replacing operands may trigger constant folding which then could
1236+
// trigger other simplify-CFG optimizations.
1237+
ConstFolder.addToWorklist(I);
1238+
ConstFolder.processWorkList();
1239+
}
12341240
}
12351241
} else {
12361242
// We must be processing an unreachable part of the cfg with a cycle.
@@ -1290,7 +1296,7 @@ bool SimplifyCFG::simplifyBranchBlock(BranchInst *BI) {
12901296
// If this unconditional branch has BBArgs, check to see if duplicating the
12911297
// destination would allow it to be simplified. This is a simple form of jump
12921298
// threading.
1293-
if (!BI->getArgs().empty() &&
1299+
if (!isVeryLargeFunction && !BI->getArgs().empty() &&
12941300
tryJumpThreading(BI))
12951301
return true;
12961302

@@ -3067,6 +3073,9 @@ bool SimplifyCFG::run() {
30673073

30683074
LLVM_DEBUG(llvm::dbgs() << "### Run SimplifyCFG on " << Fn.getName() << '\n');
30693075

3076+
// Disable some expensive optimizations if the function is huge.
3077+
isVeryLargeFunction = (Fn.size() > 10000);
3078+
30703079
// First remove any block not reachable from the entry.
30713080
bool Changed = removeUnreachableBlocks(Fn);
30723081

lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp

Lines changed: 4 additions & 0 deletions
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)