Skip to content

Commit f481919

Browse files
committed
SILOptimizer: use BasicBlockSet instead of SmallPtrSet in various transformations.
It reduces compile time.
1 parent 4d61dad commit f481919

23 files changed

+239
-192
lines changed

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "swift/SIL/OwnershipUtils.h"
3434
#include "swift/SIL/PostOrder.h"
3535
#include "swift/SIL/PrettyStackTrace.h"
36+
#include "swift/SIL/SILBitfield.h"
3637
#include "swift/SIL/SILDebugScope.h"
3738
#include "swift/SIL/SILFunction.h"
3839
#include "swift/SIL/SILModule.h"
@@ -5110,7 +5111,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
51105111
}
51115112

51125113
bool isUnreachableAlongAllPathsStartingAt(
5113-
SILBasicBlock *StartBlock, SmallPtrSetImpl<SILBasicBlock *> &Visited) {
5114+
SILBasicBlock *StartBlock, BasicBlockSet &Visited) {
51145115
if (isa<UnreachableInst>(StartBlock->getTerminator()))
51155116
return true;
51165117
else if (isa<ReturnInst>(StartBlock->getTerminator()))
@@ -5120,7 +5121,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
51205121

51215122
// Recursively check all successors.
51225123
for (auto *SuccBB : StartBlock->getSuccessorBlocks())
5123-
if (!Visited.insert(SuccBB).second)
5124+
if (!Visited.insert(SuccBB))
51245125
if (!isUnreachableAlongAllPathsStartingAt(SuccBB, Visited))
51255126
return false;
51265127

@@ -5304,7 +5305,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
53045305
// this successor bb. (FIXME: Why? Infinite loops should still
53055306
// preserve consistency...)
53065307
auto isUnreachable = [&] {
5307-
SmallPtrSet<SILBasicBlock *, 16> visited;
5308+
BasicBlockSet visited(F);
53085309
return isUnreachableAlongAllPathsStartingAt(succBB, visited);
53095310
};
53105311

@@ -5471,7 +5472,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
54715472
// This ensures that any open_existential instructions, which
54725473
// open archetypes, are seen before the uses of these archetypes.
54735474
llvm::ReversePostOrderTraversal<SILFunction *> RPOT(F);
5474-
llvm::DenseSet<SILBasicBlock *> VisitedBBs;
5475+
BasicBlockSet VisitedBBs(F);
54755476
for (auto Iter = RPOT.begin(), E = RPOT.end(); Iter != E; ++Iter) {
54765477
auto *BB = *Iter;
54775478
VisitedBBs.insert(BB);
@@ -5481,7 +5482,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
54815482
// Visit all basic blocks that were not visited during the RPOT traversal,
54825483
// e.g. unreachable basic blocks.
54835484
for (auto &BB : *F) {
5484-
if (VisitedBBs.count(&BB))
5485+
if (VisitedBBs.contains(&BB))
54855486
continue;
54865487
visitSILBasicBlock(&BB);
54875488
}

lib/SILOptimizer/LoopTransforms/ArrayPropertyOpt.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#include "swift/SIL/InstructionUtils.h"
6363
#include "swift/SIL/Projection.h"
6464
#include "swift/SIL/LoopInfo.h"
65+
#include "swift/SIL/SILBitfield.h"
6566
#include "swift/SIL/SILCloner.h"
6667
#include "llvm/ADT/SmallSet.h"
6768
#include "llvm/Support/CommandLine.h"
@@ -86,18 +87,20 @@ class ArrayPropertiesAnalysis {
8687
llvm::DenseMap<SILFunction *, uint32_t> InstCountCache;
8788
llvm::SmallSet<SILValue, 16> HoistableArray;
8889

89-
SmallPtrSet<SILBasicBlock *, 16> ReachingBlocks;
90-
SmallPtrSet<SILBasicBlock *, 16> CachedExitingBlocks;
90+
BasicBlockSet ReachingBlocks;
91+
SmallVector<SILBasicBlock *, 16> CachedExitingBlocks;
9192

9293
// This controls the max instructions the analysis can scan before giving up
9394
const uint32_t AnalysisThreshold = 5000;
9495
// This controls the max threshold for instruction count in the loop
9596
const uint32_t LoopInstCountThreshold = 500;
9697

98+
bool reachingBlocksComputed = false;
99+
97100
public:
98101
ArrayPropertiesAnalysis(SILLoop *L, DominanceAnalysis *DA)
99102
: Fun(L->getHeader()->getParent()), Loop(L), Preheader(nullptr),
100-
DomTree(DA->get(Fun)) {}
103+
DomTree(DA->get(Fun)), ReachingBlocks(Fun) {}
101104

102105
/// Check if it is profitable to specialize a loop when you see an apply
103106
/// instruction. We consider it is not profitable to specialize the loop when:
@@ -239,18 +242,19 @@ class ArrayPropertiesAnalysis {
239242
return V;
240243
}
241244

242-
SmallPtrSetImpl<SILBasicBlock *> &getReachingBlocks() {
243-
if (ReachingBlocks.empty()) {
245+
BasicBlockSet &getReachingBlocks() {
246+
if (!reachingBlocksComputed) {
244247
SmallVector<SILBasicBlock *, 8> Worklist;
245248
ReachingBlocks.insert(Preheader);
246249
Worklist.push_back(Preheader);
247250
while (!Worklist.empty()) {
248251
SILBasicBlock *BB = Worklist.pop_back_val();
249252
for (auto PI = BB->pred_begin(), PE = BB->pred_end(); PI != PE; ++PI) {
250-
if (ReachingBlocks.insert(*PI).second)
253+
if (ReachingBlocks.insert(*PI))
251254
Worklist.push_back(*PI);
252255
}
253256
}
257+
reachingBlocksComputed = true;
254258
}
255259
return ReachingBlocks;
256260
}
@@ -279,7 +283,7 @@ class ArrayPropertiesAnalysis {
279283

280284
// Check if this escape can reach the current loop.
281285
if (!Loop->contains(UseInst->getParent()) &&
282-
!getReachingBlocks().count(UseInst->getParent())) {
286+
!getReachingBlocks().contains(UseInst->getParent())) {
283287
continue;
284288
}
285289
LLVM_DEBUG(llvm::dbgs()
@@ -356,12 +360,10 @@ class ArrayPropertiesAnalysis {
356360
return false;
357361
}
358362

359-
SmallPtrSetImpl<SILBasicBlock *> &getLoopExitingBlocks() {
363+
SmallVectorImpl<SILBasicBlock *> &getLoopExitingBlocks() {
360364
if (!CachedExitingBlocks.empty())
361365
return CachedExitingBlocks;
362-
SmallVector<SILBasicBlock *, 16> ExitingBlocks;
363-
Loop->getExitingBlocks(ExitingBlocks);
364-
CachedExitingBlocks.insert(ExitingBlocks.begin(), ExitingBlocks.end());
366+
Loop->getExitingBlocks(CachedExitingBlocks);
365367
return CachedExitingBlocks;
366368
}
367369

lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/SIL/SILArgument.h"
2626
#include "swift/SIL/SILBuilder.h"
2727
#include "swift/SIL/SILInstruction.h"
28+
#include "swift/SIL/SILBitfield.h"
2829
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
2930
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
3031
#include "swift/SILOptimizer/Analysis/ArraySemantic.h"
@@ -116,7 +117,9 @@ class COWArrayOpt {
116117
std::pair<bool, bool> CachedSafeLoop;
117118

118119
// Set of all blocks that may reach the loop, not including loop blocks.
119-
llvm::SmallPtrSet<SILBasicBlock*,32> ReachingBlocks;
120+
BasicBlockSet ReachingBlocks;
121+
122+
bool reachingBlocksComputed = false;
120123

121124
/// Transient per-Array user set.
122125
///
@@ -152,13 +155,13 @@ class COWArrayOpt {
152155
COWArrayOpt(RCIdentityFunctionInfo *RCIA, SILLoop *L, DominanceAnalysis *DA)
153156
: RCIA(RCIA), Function(L->getHeader()->getParent()), Loop(L),
154157
Preheader(L->getLoopPreheader()), DomTree(DA->get(Function)),
155-
ColdBlocks(DA), CachedSafeLoop(false, false) {}
158+
ColdBlocks(DA), CachedSafeLoop(false, false), ReachingBlocks(Function) {}
156159

157160
bool run();
158161

159162
private:
160163
bool checkUniqueArrayContainer(SILValue ArrayContainer);
161-
SmallPtrSetImpl<SILBasicBlock*> &getReachingBlocks();
164+
BasicBlockSet &getReachingBlocks();
162165
bool isRetainReleasedBeforeMutate(SILInstruction *RetainInst,
163166
bool IsUniquelyIdentifiedArray = true);
164167
bool checkSafeArrayAddressUses(UserList &AddressUsers);
@@ -268,18 +271,19 @@ bool COWArrayOpt::checkUniqueArrayContainer(SILValue ArrayContainer) {
268271
}
269272

270273
/// Lazily compute blocks that may reach the loop.
271-
SmallPtrSetImpl<SILBasicBlock*> &COWArrayOpt::getReachingBlocks() {
272-
if (ReachingBlocks.empty()) {
274+
BasicBlockSet &COWArrayOpt::getReachingBlocks() {
275+
if (!reachingBlocksComputed) {
273276
SmallVector<SILBasicBlock*, 8> Worklist;
274277
ReachingBlocks.insert(Preheader);
275278
Worklist.push_back(Preheader);
276279
while (!Worklist.empty()) {
277280
SILBasicBlock *BB = Worklist.pop_back_val();
278281
for (auto PI = BB->pred_begin(), PE = BB->pred_end(); PI != PE; ++PI) {
279-
if (ReachingBlocks.insert(*PI).second)
282+
if (ReachingBlocks.insert(*PI))
280283
Worklist.push_back(*PI);
281284
}
282285
}
286+
reachingBlocksComputed = true;
283287
}
284288
return ReachingBlocks;
285289
}
@@ -404,7 +408,7 @@ bool COWArrayOpt::checkSafeArrayAddressUses(UserList &AddressUsers) {
404408

405409
// Check of this escape can reach the current loop.
406410
if (!Loop->contains(UseInst->getParent()) &&
407-
!getReachingBlocks().count(UseInst->getParent())) {
411+
!getReachingBlocks().contains(UseInst->getParent())) {
408412
continue;
409413
}
410414

lib/SILOptimizer/LoopTransforms/LICM.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/SIL/SILArgument.h"
2020
#include "swift/SIL/SILBuilder.h"
2121
#include "swift/SIL/SILInstruction.h"
22+
#include "swift/SIL/SILBitfield.h"
2223
#include "swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h"
2324
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
2425
#include "swift/SILOptimizer/Analysis/Analysis.h"
@@ -1195,7 +1196,7 @@ static bool
11951196
storesCommonlyDominateLoopExits(AccessPath accessPath,
11961197
SILLoop *loop,
11971198
ArrayRef<SILBasicBlock *> exitingBlocks) {
1198-
SmallPtrSet<SILBasicBlock *, 16> stores;
1199+
BasicBlockSet stores(loop->getHeader()->getParent());
11991200
SmallVector<Operand *, 8> uses;
12001201
// Collect as many recognizable stores as possible. It's ok if not all stores
12011202
// are collected.
@@ -1208,7 +1209,7 @@ storesCommonlyDominateLoopExits(AccessPath accessPath,
12081209
SILBasicBlock *header = loop->getHeader();
12091210
// If a store is in the loop header, we already know that it's dominating all
12101211
// loop exits.
1211-
if (stores.count(header) != 0)
1212+
if (stores.contains(header))
12121213
return true;
12131214

12141215
// Also a store in the pre-header dominates all exists. Although the situation
@@ -1243,21 +1244,21 @@ storesCommonlyDominateLoopExits(AccessPath accessPath,
12431244
// exit:
12441245
// store %phi to %addr
12451246
//
1246-
if (stores.count(loop->getLoopPreheader()) != 0)
1247+
if (stores.contains(loop->getLoopPreheader()))
12471248
return true;
12481249

12491250
// Propagate the store-is-not-alive flag through the control flow in the loop,
12501251
// starting at the header.
1251-
SmallPtrSet<SILBasicBlock *, 16> storesNotAlive;
1252+
BasicBlockSet storesNotAlive(loop->getHeader()->getParent());
12521253
storesNotAlive.insert(header);
12531254
bool changed = false;
12541255
do {
12551256
changed = false;
12561257
for (SILBasicBlock *block : loop->blocks()) {
1257-
bool storeAlive = (storesNotAlive.count(block) == 0);
1258-
if (storeAlive && stores.count(block) == 0 &&
1258+
bool storeAlive = !storesNotAlive.contains(block);
1259+
if (storeAlive && !stores.contains(block) &&
12591260
std::any_of(block->pred_begin(), block->pred_end(),
1260-
[&](SILBasicBlock *b) { return storesNotAlive.count(b) != 0; })) {
1261+
[&](SILBasicBlock *b) { return storesNotAlive.contains(b); })) {
12611262
storesNotAlive.insert(block);
12621263
changed = true;
12631264
}
@@ -1272,7 +1273,7 @@ storesCommonlyDominateLoopExits(AccessPath accessPath,
12721273
for (SILBasicBlock *eb : exitingBlocks) {
12731274
// Ignore loop exits to blocks which end in an unreachable.
12741275
if (!std::any_of(eb->succ_begin(), eb->succ_end(), isUnreachableBlock) &&
1275-
storesNotAlive.count(eb) != 0) {
1276+
storesNotAlive.contains(eb)) {
12761277
return false;
12771278
}
12781279
}

lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "swift/SIL/SILFunction.h"
3838
#include "swift/SIL/SILUndef.h"
3939
#include "swift/SIL/InstructionUtils.h"
40+
#include "swift/SIL/SILBitfield.h"
4041
#include "swift/SILOptimizer/Analysis/ClosureScope.h"
4142
#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
4243
#include "swift/SILOptimizer/PassManager/Transforms.h"
@@ -402,7 +403,7 @@ bool SelectEnforcement::hasPotentiallyEscapedAtAnyReachableBlock(
402403
BeginAccessInst *access, BlockSetVector &blocksAccessedAcross) {
403404

404405
assert(Worklist.empty());
405-
SmallPtrSet<SILBasicBlock*, 8> visited;
406+
BasicBlockSet visited(access->getFunction());
406407

407408
// Don't follow any paths that lead to an end_access.
408409
for (auto endAccess : access->getEndAccesses())
@@ -412,22 +413,22 @@ bool SelectEnforcement::hasPotentiallyEscapedAtAnyReachableBlock(
412413
for (SILBasicBlock *bb : blocksAccessedAcross) {
413414
for (SILBasicBlock *succBB : bb->getSuccessorBlocks()) {
414415
if (blocksAccessedAcross.count(succBB)) continue;
415-
if (visited.insert(succBB).second)
416+
if (visited.insert(succBB))
416417
Worklist.push_back(succBB);
417418
}
418419
}
419420

420421
while (!Worklist.empty()) {
421422
SILBasicBlock *bb = Worklist.pop_back_val();
422-
assert(visited.count(bb));
423+
assert(visited.contains(bb));
423424

424425
// If we're tracking information for this block, there's an escape.
425426
if (StateMap.count(bb))
426427
return true;
427428

428429
// Add all reachable successors.
429430
for (SILBasicBlock *succ : bb->getSuccessors()) {
430-
if (visited.insert(succ).second)
431+
if (visited.insert(succ))
431432
Worklist.push_back(succ);
432433
}
433434
}

lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/SIL/SILArgument.h"
1919
#include "swift/SIL/SILBuilder.h"
2020
#include "swift/SIL/SILInstruction.h"
21+
#include "swift/SIL/SILBitfield.h"
2122
#include "swift/SILOptimizer/PassManager/Passes.h"
2223
#include "swift/SILOptimizer/PassManager/Transforms.h"
2324
#include "swift/SILOptimizer/Utils/CFGOptUtils.h"
@@ -103,7 +104,7 @@ static SILInstruction *getDeinitSafeClosureDestructionPoint(SILBasicBlock *bb) {
103104
static void findReachableExitBlocks(SILInstruction *i,
104105
SmallVectorImpl<SILBasicBlock *> &result) {
105106
SmallVector<SILBasicBlock *, 32> worklist;
106-
SmallPtrSet<SILBasicBlock *, 8> visitedBlocks;
107+
BasicBlockSet visitedBlocks(i->getFunction());
107108

108109
visitedBlocks.insert(i->getParent());
109110
worklist.push_back(i->getParent());
@@ -116,7 +117,7 @@ static void findReachableExitBlocks(SILInstruction *i,
116117
}
117118
llvm::copy_if(bb->getSuccessorBlocks(), std::back_inserter(worklist),
118119
[&](SILBasicBlock *bb) {
119-
return visitedBlocks.insert(bb).second;
120+
return visitedBlocks.insert(bb);
120121
});
121122
}
122123
}

0 commit comments

Comments
 (0)