Skip to content

Commit 3e93a21

Browse files
committed
ColdBlockInfo: stop early if no coldness
There's no reason to do further stages of analysis to propagate coldness if there wasn't any found in Stage 1.
1 parent 7203a4f commit 3e93a21

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed

include/swift/SILOptimizer/Analysis/ColdBlockInfo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,16 @@ class ColdBlockInfo {
5454
PostDominanceAnalysis *PDA;
5555

5656
/// Each block in this map has been determined to be cold and/or warm.
57+
/// Make sure to always use the set/resetToCold methods to update this!
5758
llvm::DenseMap<const SILBasicBlock*, Energy> EnergyMap;
58-
bool changedMap = false;
5959

6060
// This is a cache and shouldn't be copied around.
6161
ColdBlockInfo(const ColdBlockInfo &) = delete;
6262
ColdBlockInfo &operator=(const ColdBlockInfo &) = delete;
6363
LLVM_DUMP_METHOD void dump() const;
6464

65+
/// Tracks whether any information was changed in the energy map.
66+
bool changedMap = false;
6567
void resetToCold(const SILBasicBlock *BB);
6668
void set(const SILBasicBlock *BB, State::Temperature temp);
6769

lib/SILOptimizer/Analysis/ColdBlockInfo.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/AST/SemanticAttrs.h"
14+
#include "swift/Basic/Defer.h"
1415
#include "swift/SIL/BasicBlockBits.h"
1516
#include "swift/SIL/SILArgument.h"
1617
#include "swift/SIL/SILModule.h"
@@ -266,12 +267,17 @@ bool ColdBlockInfo::inferFromEdgeProfile(SILBasicBlock *BB) {
266267
}
267268

268269
void ColdBlockInfo::analyze(SILFunction *fn) {
270+
SWIFT_DEFER { changedMap = false; };
271+
272+
LLVM_DEBUG(llvm::dbgs()
273+
<< "ColdBlockInfo::analyze on " << fn->getName() << "\n");
269274
LLVM_DEBUG(llvm::dbgs() << "--> Before Stage 1\n");
270275
LLVM_DEBUG(dump());
271276

272277
BasicBlockSet foundExpectedCond(fn);
273278

274279
// Stage 1: Seed the graph with warm/cold blocks.
280+
changedMap = false;
275281
for (auto &BB : *fn) {
276282
auto *term = BB.getTerminator();
277283

@@ -304,9 +310,20 @@ void ColdBlockInfo::analyze(SILFunction *fn) {
304310

305311
LLVM_DEBUG(llvm::dbgs() << "--> After Stage 1; changedMap = "
306312
<< changedMap << "\n");
307-
LLVM_DEBUG(dump(); changedMap = false);
313+
LLVM_DEBUG(dump());
314+
315+
/// Latter stages are only for propagating coldness from other cold blocks.
316+
///
317+
/// If we haven't changed the energy map at all in Stage 1, then we didn't
318+
/// find any new coldness, so stop early.
319+
if (!changedMap) {
320+
LLVM_DEBUG(llvm::dbgs()
321+
<< "--> Stopping early in "<< fn->getName() << "\n");
322+
return;
323+
}
308324

309325
// Stage 2: Propagate via dominators
326+
changedMap = false;
310327
SmallVector<SILBasicBlock *, 8> scratch;
311328
for (auto &BB : *fn) {
312329
scratch.clear();
@@ -354,9 +371,10 @@ void ColdBlockInfo::analyze(SILFunction *fn) {
354371

355372
LLVM_DEBUG(llvm::dbgs() << "--> After Stage 2; changedMap = "
356373
<< changedMap << "\n");
357-
LLVM_DEBUG(dump(); changedMap = false);
374+
LLVM_DEBUG(dump());
358375

359376
/// Stage 3: Backwards propagate coldness from successors.
377+
changedMap = false;
360378
auto isColdBlock = [&](auto *bb) { return isCold(bb); };
361379

362380
unsigned completedIters = 0;
@@ -398,7 +416,7 @@ void ColdBlockInfo::analyze(SILFunction *fn) {
398416
" | converged after " << completedIters << " iters"
399417
<< " over " << fn->size() << " blocks; "
400418
<< " changedMap = " << changedMap << "\n");
401-
LLVM_DEBUG(dump(); changedMap = false);
419+
LLVM_DEBUG(dump());
402420
}
403421

404422
inline bool isColdEnergy(ColdBlockInfo::Energy e) {
@@ -416,15 +434,21 @@ bool ColdBlockInfo::isCold(const SILBasicBlock *BB) const {
416434

417435
void ColdBlockInfo::resetToCold(const SILBasicBlock *BB) {
418436
auto &entry = EnergyMap.getOrInsertDefault(BB);
419-
LLVM_DEBUG(isColdEnergy(entry) ? false : changedMap = true);
437+
if (isColdEnergy(entry))
438+
return;
439+
420440
entry.removeAll();
421441
entry.insert(State::Cold);
442+
changedMap = true;
422443
}
423444

424445
void ColdBlockInfo::set(const SILBasicBlock *BB, State::Temperature temp) {
425446
auto &entry = EnergyMap.getOrInsertDefault(BB);
426-
LLVM_DEBUG(entry.contains(temp) ? false : changedMap = true);
447+
if (entry.contains(temp))
448+
return;
449+
427450
entry.insert(temp);
451+
changedMap = true;
428452
}
429453

430454
void ColdBlockInfo::setExpectedCondition(CondBranchInst *CBI, ExpectedValue value) {

test/SILOptimizer/cold_block_info.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,23 @@ public func goBoom(_ i: Int?) -> Int {
4141
}
4242

4343

44-
// CHECK-LABEL: --> Final for $s4main19goBoom_preconditionyySbF
45-
// CHECK: {
46-
// CHECK-NEXT: STATISTICS: warm 0 | cold 0
47-
// CHECK-NEXT: }
44+
// CHECK-LABEL: --> Stopping early in $s4main19goBoom_preconditionyySbF
4845
public func goBoom_precondition(_ b: Bool) {
49-
// NOTE: cond_fail instructions aren't terminators, so there's nothing cold.
46+
// NOTE: cond_fail instructions from preconditions aren't terminators,
47+
// so there's nothing cold in this function!
5048
precondition(b)
49+
50+
var x = random()
51+
precondition(x >= 0)
52+
53+
if (x > 100) {
54+
x = 0
55+
}
56+
57+
for i in 0..<x {
58+
precondition(i <= 100)
59+
dump(i)
60+
}
5161
}
5262

5363
// CHECK-LABEL: --> Final for $s4main17goBoom_fatalErroryySiF

0 commit comments

Comments
 (0)