Skip to content

Commit 214b7a9

Browse files
committed
Use the new BasicBlockWorklist utility in various places in the compiler.
It's a refactoring which simplifies the code. NFC.
1 parent 85884e4 commit 214b7a9

File tree

9 files changed

+51
-134
lines changed

9 files changed

+51
-134
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,16 +2017,10 @@ void IRGenSILFunction::emitSILFunction() {
20172017

20182018
// Invariant: for every block in the work queue, we have visited all
20192019
// of its dominators.
2020-
BasicBlockSet visitedBlocks(CurSILFn);
2021-
SmallVector<SILBasicBlock*, 8> workQueue; // really a stack
2022-
2023-
// Queue up the entry block, for which the invariant trivially holds.
2024-
visitedBlocks.insert(&*CurSILFn->begin());
2025-
workQueue.push_back(&*CurSILFn->begin());
2026-
2027-
while (!workQueue.empty()) {
2028-
auto bb = workQueue.pop_back_val();
2020+
// Start with the entry block, for which the invariant trivially holds.
2021+
BasicBlockWorklist<32> workQueue(&*CurSILFn->getEntryBlock());
20292022

2023+
while (SILBasicBlock *bb = workQueue.pop()) {
20302024
// Emit the block.
20312025
visitSILBasicBlock(bb);
20322026

@@ -2052,15 +2046,14 @@ void IRGenSILFunction::emitSILFunction() {
20522046
// Therefore the invariant holds of all the successors, and we can
20532047
// queue them up if we haven't already visited them.
20542048
for (auto *succBB : bb->getSuccessorBlocks()) {
2055-
if (visitedBlocks.insert(succBB))
2056-
workQueue.push_back(succBB);
2049+
workQueue.pushIfNotVisited(succBB);
20572050
}
20582051
}
20592052

20602053
// If there are dead blocks in the SIL function, we might have left
20612054
// invalid blocks in the IR. Do another pass and kill them off.
20622055
for (SILBasicBlock &bb : *CurSILFn)
2063-
if (!visitedBlocks.contains(&bb))
2056+
if (!workQueue.isVisited(&bb))
20642057
LoweredBBs[&bb].bb->eraseFromParent();
20652058

20662059
}

lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,22 +103,16 @@ static SILInstruction *getDeinitSafeClosureDestructionPoint(SILBasicBlock *bb) {
103103

104104
static void findReachableExitBlocks(SILInstruction *i,
105105
SmallVectorImpl<SILBasicBlock *> &result) {
106-
SmallVector<SILBasicBlock *, 32> worklist;
107-
BasicBlockSet visitedBlocks(i->getFunction());
106+
BasicBlockWorklist<32> worklist(i->getParent());
108107

109-
visitedBlocks.insert(i->getParent());
110-
worklist.push_back(i->getParent());
111-
112-
while (!worklist.empty()) {
113-
auto *bb = worklist.pop_back_val();
108+
while (SILBasicBlock *bb = worklist.pop()) {
114109
if (bb->getTerminator()->isFunctionExiting()) {
115110
result.push_back(bb);
116111
continue;
117112
}
118-
llvm::copy_if(bb->getSuccessorBlocks(), std::back_inserter(worklist),
119-
[&](SILBasicBlock *bb) {
120-
return visitedBlocks.insert(bb);
121-
});
113+
for (SILBasicBlock *succ : bb->getSuccessors()) {
114+
worklist.pushIfNotVisited(succ);
115+
}
122116
}
123117
}
124118

lib/SILOptimizer/Mandatory/MandatoryCombine.cpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -206,19 +206,10 @@ static llvm::cl::opt<bool> EnableCanonicalizationAndTrivialDCE(
206206
"dead code and canonicalizing SIL"));
207207

208208
void MandatoryCombiner::addReachableCodeToWorklist(SILFunction &function) {
209-
SmallVector<SILBasicBlock *, 32> blockWorklist;
210-
BasicBlockSet blockAlreadyAddedToWorklist(&function);
209+
BasicBlockWorklist<32> blockWorklist(function.getEntryBlock());
211210
SmallVector<SILInstruction *, 128> initialInstructionWorklist;
212211

213-
{
214-
auto *firstBlock = &*function.begin();
215-
blockWorklist.push_back(firstBlock);
216-
blockAlreadyAddedToWorklist.insert(firstBlock);
217-
}
218-
219-
while (!blockWorklist.empty()) {
220-
auto *block = blockWorklist.pop_back_val();
221-
212+
while (SILBasicBlock *block = blockWorklist.pop()) {
222213
for (auto iterator = block->begin(), end = block->end(); iterator != end;) {
223214
auto *instruction = &*iterator;
224215
++iterator;
@@ -236,11 +227,9 @@ void MandatoryCombiner::addReachableCodeToWorklist(SILFunction &function) {
236227
initialInstructionWorklist.push_back(instruction);
237228
}
238229

239-
llvm::copy_if(block->getSuccessorBlocks(),
240-
std::back_inserter(blockWorklist),
241-
[&](SILBasicBlock *block) -> bool {
242-
return blockAlreadyAddedToWorklist.insert(block);
243-
});
230+
for (SILBasicBlock *succ : block->getSuccessors()) {
231+
blockWorklist.pushIfNotVisited(succ);
232+
}
244233
}
245234

246235
worklist.addInitialGroup(initialInstructionWorklist);

lib/SILOptimizer/SILCombiner/SILCombine.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,10 @@ static llvm::cl::opt<bool> EnableSinkingOwnedForwardingInstToUses(
6161
/// worklist (this significantly speeds up SILCombine on code where many
6262
/// instructions are dead or constant).
6363
void SILCombiner::addReachableCodeToWorklist(SILBasicBlock *BB) {
64-
llvm::SmallVector<SILBasicBlock *, 256> Worklist;
64+
BasicBlockWorklist<256> Worklist(BB);
6565
llvm::SmallVector<SILInstruction *, 128> InstrsForSILCombineWorklist;
66-
BasicBlockSet Visited(BB->getParent());
67-
68-
Worklist.push_back(BB);
69-
do {
70-
BB = Worklist.pop_back_val();
71-
72-
// We have now visited this block! If we've already been here, ignore it.
73-
if (!Visited.insert(BB)) continue;
7466

67+
while (SILBasicBlock *BB = Worklist.pop()) {
7568
for (SILBasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {
7669
SILInstruction *Inst = &*BBI;
7770
++BBI;
@@ -98,9 +91,10 @@ void SILCombiner::addReachableCodeToWorklist(SILBasicBlock *BB) {
9891
}
9992

10093
// Recursively visit successors.
101-
for (auto SI = BB->succ_begin(), SE = BB->succ_end(); SI != SE; ++SI)
102-
Worklist.push_back(*SI);
103-
} while (!Worklist.empty());
94+
for (SILBasicBlock *Succ : BB->getSuccessors()) {
95+
Worklist.pushIfNotVisited(Succ);
96+
}
97+
}
10498

10599
// Once we've found all of the instructions to add to the worklist, add them
106100
// in reverse order. This way SILCombine will visit from the top of the

lib/SILOptimizer/Transforms/ARCCodeMotion.cpp

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -554,24 +554,16 @@ void RetainCodeMotionContext::convergeCodeMotionDataFlow() {
554554
// Process each basic block with the genset and killset. Every time the
555555
// BBSetOut of a basic block changes, the optimization is rerun on its
556556
// successors.
557-
llvm::SmallVector<SILBasicBlock *, 16> WorkList;
558-
BasicBlockSet HandledBBs(BlockStates.getFunction());
557+
BasicBlockWorklist<16> WorkList(BlockStates.getFunction());
559558
// Push into reverse post order so that we can pop from the back and get
560559
// post order.
561560
for (SILBasicBlock *B : PO->getReversePostOrder()) {
562-
WorkList.push_back(B);
563-
HandledBBs.insert(B);
561+
WorkList.push(B);
564562
}
565-
while (!WorkList.empty()) {
566-
SILBasicBlock *BB = WorkList.pop_back_val();
567-
HandledBBs.erase(BB);
563+
while (SILBasicBlock *BB = WorkList.popAndForget()) {
568564
if (processBBWithGenKillSet(BB)) {
569565
for (SILBasicBlock *succ : BB->getSuccessors()) {
570-
// We do not push basic block into the worklist if its already
571-
// in the worklist.
572-
if (HandledBBs.contains(succ))
573-
continue;
574-
WorkList.push_back(succ);
566+
WorkList.pushIfNotVisited(succ);
575567
}
576568
}
577569
}
@@ -974,24 +966,16 @@ void ReleaseCodeMotionContext::convergeCodeMotionDataFlow() {
974966
// Process each basic block with the gen and kill set. Every time the
975967
// BBSetIn of a basic block changes, the optimization is rerun on its
976968
// predecessors.
977-
llvm::SmallVector<SILBasicBlock *, 16> WorkList;
978-
BasicBlockSet HandledBBs(BlockStates.getFunction());
969+
BasicBlockWorklist<16> WorkList(BlockStates.getFunction());
979970
// Push into reverse post order so that we can pop from the back and get
980971
// post order.
981972
for (SILBasicBlock *B : PO->getPostOrder()) {
982-
WorkList.push_back(B);
983-
HandledBBs.insert(B);
973+
WorkList.push(B);
984974
}
985-
while (!WorkList.empty()) {
986-
SILBasicBlock *BB = WorkList.pop_back_val();
987-
HandledBBs.erase(BB);
975+
while (SILBasicBlock *BB = WorkList.popAndForget()) {
988976
if (processBBWithGenKillSet(BB)) {
989977
for (auto X : BB->getPredecessorBlocks()) {
990-
// We do not push basic block into the worklist if its already
991-
// in the worklist.
992-
if (HandledBBs.contains(X))
993-
continue;
994-
WorkList.push_back(X);
978+
WorkList.pushIfNotVisited(X);
995979
}
996980
}
997981
}

lib/SILOptimizer/Transforms/DeadStoreElimination.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,24 +1165,16 @@ void DSEContext::runIterativeDSE() {
11651165
// Process each basic block with the gen and kill set. Every time the
11661166
// BBWriteSetIn of a basic block changes, the optimization is rerun on its
11671167
// predecessors.
1168-
llvm::SmallVector<SILBasicBlock *, 16> WorkList;
1169-
BasicBlockSet HandledBBs(F);
1168+
BasicBlockWorklist<16> WorkList(F);
11701169
// Push into reverse post order so that we can pop from the back and get
11711170
// post order.
11721171
for (SILBasicBlock *B : PO->getReversePostOrder()) {
1173-
WorkList.push_back(B);
1174-
HandledBBs.insert(B);
1172+
WorkList.push(B);
11751173
}
1176-
while (!WorkList.empty()) {
1177-
SILBasicBlock *BB = WorkList.pop_back_val();
1178-
HandledBBs.erase(BB);
1174+
while (SILBasicBlock *BB = WorkList.popAndForget()) {
11791175
if (processBasicBlockWithGenKillSet(BB)) {
11801176
for (SILBasicBlock *pred : BB->getPredecessorBlocks()) {
1181-
// We do not push basic block into the worklist if its already
1182-
// in the worklist.
1183-
if (HandledBBs.contains(pred))
1184-
continue;
1185-
WorkList.push_back(pred);
1177+
WorkList.pushIfNotVisited(pred);
11861178
}
11871179
}
11881180
}

lib/SILOptimizer/Transforms/Outliner.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,18 +1234,12 @@ class OutlinePatterns {
12341234
/// functions.
12351235
bool tryOutline(SILOptFunctionBuilder &FuncBuilder, SILFunction *Fun,
12361236
SmallVectorImpl<SILFunction *> &FunctionsAdded) {
1237-
BasicBlockSet Visited(Fun);
1238-
SmallVector<SILBasicBlock *, 128> Worklist;
1237+
BasicBlockWorklist<128> Worklist(Fun->getEntryBlock());
12391238
OutlinePatterns patterns(FuncBuilder);
12401239
bool changed = false;
12411240

12421241
// Traverse the function.
1243-
Worklist.push_back(&*Fun->begin());
1244-
while (!Worklist.empty()) {
1245-
1246-
SILBasicBlock *CurBlock = Worklist.pop_back_val();
1247-
if (!Visited.insert(CurBlock)) continue;
1248-
1242+
while (SILBasicBlock *CurBlock = Worklist.pop()) {
12491243
SILBasicBlock::iterator CurInst = CurBlock->begin();
12501244

12511245
// Go over the instructions trying to match and replace patterns.
@@ -1260,8 +1254,9 @@ bool tryOutline(SILOptFunctionBuilder &FuncBuilder, SILFunction *Fun,
12601254
assert(LastInst->getParent() == CurBlock);
12611255
changed = true;
12621256
} else if (isa<TermInst>(CurInst)) {
1263-
std::copy(CurBlock->succ_begin(), CurBlock->succ_end(),
1264-
std::back_inserter(Worklist));
1257+
for (SILBasicBlock *succ : CurBlock->getSuccessors()) {
1258+
Worklist.pushIfNotVisited(succ);
1259+
}
12651260
++CurInst;
12661261
} else {
12671262
++CurInst;

lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,21 +1280,16 @@ BlockState::ValueState BlockState::getValueStateAtEndOfBlock(RLEContext &Ctx,
12801280
SILValue RLEContext::computePredecessorLocationValue(SILBasicBlock *BB,
12811281
LSLocation &L) {
12821282
llvm::SmallVector<std::pair<SILBasicBlock *, SILValue>, 8> Values;
1283-
BasicBlockSet HandledBBs(Fn);
1284-
llvm::SmallVector<SILBasicBlock *, 8> WorkList;
1283+
BasicBlockWorklist<16> WorkList(Fn);
12851284

12861285
// Push in all the predecessors to get started.
12871286
for (auto Pred : BB->getPredecessorBlocks()) {
1288-
WorkList.push_back(Pred);
1287+
WorkList.pushIfNotVisited(Pred);
12891288
}
12901289

1291-
while (!WorkList.empty()) {
1292-
auto *CurBB = WorkList.pop_back_val();
1290+
while (SILBasicBlock *CurBB = WorkList.pop()) {
12931291
BlockState &Forwarder = getBlockState(CurBB);
12941292

1295-
// Mark this basic block as processed.
1296-
HandledBBs.insert(CurBB);
1297-
12981293
// There are 3 cases that can happen here.
12991294
//
13001295
// 1. The current basic block contains concrete values for the entire
@@ -1316,9 +1311,7 @@ SILValue RLEContext::computePredecessorLocationValue(SILBasicBlock *BB,
13161311
// locations, collect in this block's predecessors.
13171312
if (Forwarder.isCoverValues(*this, L)) {
13181313
for (auto Pred : CurBB->getPredecessorBlocks()) {
1319-
if (HandledBBs.contains(Pred))
1320-
continue;
1321-
WorkList.push_back(Pred);
1314+
WorkList.pushIfNotVisited(Pred);
13221315
}
13231316
continue;
13241317
}
@@ -1450,33 +1443,24 @@ void RLEContext::processBasicBlocksWithGenKillSet() {
14501443
// Process each basic block with the gen and kill set. Every time the
14511444
// ForwardSetOut of a basic block changes, the optimization is rerun on its
14521445
// successors.
1453-
llvm::SmallVector<SILBasicBlock *, 16> WorkList;
1454-
BasicBlockSet HandledBBs(Fn);
1446+
BasicBlockWorklist<16> WorkList(Fn);
14551447

14561448
// Push into the worklist in post order so that we can pop from the back and
14571449
// get reverse post order.
14581450
for (SILBasicBlock *BB : PO->getPostOrder()) {
1459-
WorkList.push_back(BB);
1460-
HandledBBs.insert(BB);
1451+
WorkList.push(BB);
14611452
}
1462-
while (!WorkList.empty()) {
1463-
SILBasicBlock *BB = WorkList.pop_back_val();
1453+
while (SILBasicBlock *BB = WorkList.popAndForget()) {
14641454
LLVM_DEBUG(llvm::dbgs() << "PROCESS " << printCtx.getID(BB)
14651455
<< " with Gen/Kill.\n");
1466-
HandledBBs.erase(BB);
1467-
14681456
// Intersection.
14691457
BlockState &Forwarder = getBlockState(BB);
14701458
// Compute the ForwardSetIn at the beginning of the basic block.
14711459
Forwarder.mergePredecessorAvailSet(*this);
14721460

14731461
if (Forwarder.processBasicBlockWithGenKillSet()) {
14741462
for (SILBasicBlock *succ : BB->getSuccessors()) {
1475-
// We do not push basic block into the worklist if its already
1476-
// in the worklist.
1477-
if (HandledBBs.contains(succ))
1478-
continue;
1479-
WorkList.push_back(succ);
1463+
WorkList.pushIfNotVisited(succ);
14801464
}
14811465
}
14821466
LLVM_DEBUG(Forwarder.dump(*this));

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,23 +1262,15 @@ TrampolineDest::TrampolineDest(SILBasicBlock *sourceBB,
12621262
#ifndef NDEBUG
12631263
/// Is the block reachable from the entry.
12641264
static bool isReachable(SILBasicBlock *Block) {
1265-
BasicBlockSet Visited(Block->getParent());
1266-
llvm::SmallVector<SILBasicBlock *, 16> Worklist;
1267-
SILBasicBlock *EntryBB = &*Block->getParent()->begin();
1268-
Worklist.push_back(EntryBB);
1269-
Visited.insert(EntryBB);
1270-
1271-
while (!Worklist.empty()) {
1272-
auto *CurBB = Worklist.back();
1273-
Worklist.pop_back();
1265+
BasicBlockWorklist<16> Worklist(Block->getParent()->getEntryBlock());
12741266

1267+
while (SILBasicBlock *CurBB = Worklist.pop()) {
12751268
if (CurBB == Block)
12761269
return true;
12771270

1278-
for (auto &Succ : CurBB->getSuccessors())
1279-
// Second is true if the insertion took place.
1280-
if (Visited.insert(Succ))
1281-
Worklist.push_back(Succ);
1271+
for (SILBasicBlock *Succ : CurBB->getSuccessors()) {
1272+
Worklist.pushIfNotVisited(Succ);
1273+
}
12821274
}
12831275

12841276
return false;

0 commit comments

Comments
 (0)