Skip to content

Commit d6a7e9b

Browse files
authored
Merge pull request swiftlang#35935 from eeckstein/basicblock-worklist
SIL: A utility for processing basic blocks in a worklist.
2 parents ee0e69b + 214b7a9 commit d6a7e9b

32 files changed

+141
-167
lines changed

include/swift/SIL/SILBitfield.h renamed to include/swift/SIL/BasicBlockBits.h

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- SILBitField.h - Defines the bitfield utilities ---------*- C++ -*-===//
1+
//===--- BasicBlockBits.h - SILBasicBlock bit utilities ---------*- C++ -*-===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
//
13-
// This file defines the BasicBlockBitfield and BasicBlockFlag utilities.
13+
// This file defines utilities for BasicBlock bit fields and sets.
1414
//
1515
//===----------------------------------------------------------------------===//
1616

@@ -211,6 +211,63 @@ template <unsigned N> class BasicBlockSetVector {
211211
}
212212
};
213213

214+
/// A utility for processing basic blocks in a worklist.
215+
///
216+
/// It is basically a combination of a block vector and a block set. It can be
217+
/// used for typical worklist-processing algorithms.
218+
template <unsigned N> class BasicBlockWorklist {
219+
llvm::SmallVector<SILBasicBlock *, N> worklist;
220+
BasicBlockSet visited;
221+
222+
public:
223+
/// Construct an empty worklist.
224+
BasicBlockWorklist(SILFunction *function) : visited(function) {}
225+
226+
/// Initialize the worklist with \p initialBlock.
227+
BasicBlockWorklist(SILBasicBlock *initialBlock)
228+
: visited(initialBlock->getParent()) {
229+
push(initialBlock);
230+
}
231+
232+
/// Pops the last added element from the worklist or returns null, if the
233+
/// worklist is empty.
234+
SILBasicBlock *pop() {
235+
if (worklist.empty())
236+
return nullptr;
237+
return worklist.pop_back_val();
238+
}
239+
240+
/// Pushes \p block onto the worklist if \p block has never been push before.
241+
bool pushIfNotVisited(SILBasicBlock *block) {
242+
if (visited.insert(block)) {
243+
worklist.push_back(block);
244+
return true;
245+
}
246+
return false;
247+
}
248+
249+
/// Like `pushIfNotVisited`, but requires that \p block has never been on the
250+
/// worklist before.
251+
void push(SILBasicBlock *block) {
252+
assert(!visited.contains(block));
253+
visited.insert(block);
254+
worklist.push_back(block);
255+
}
256+
257+
/// Like `pop`, but marks the returned block as "unvisited". This means, that
258+
/// the block can be pushed onto the worklist again.
259+
SILBasicBlock *popAndForget() {
260+
if (worklist.empty())
261+
return nullptr;
262+
SILBasicBlock *block = worklist.pop_back_val();
263+
visited.erase(block);
264+
return block;
265+
}
266+
267+
/// Returns true if \p block was visited, i.e. has been added to the worklist.
268+
bool isVisited(SILBasicBlock *block) const { return visited.contains(block); }
269+
};
270+
214271
} // namespace swift
215272

216273
#endif

include/swift/SIL/BasicBlockUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#define SWIFT_SIL_BASICBLOCKUTILS_H
1515

1616
#include "swift/SIL/SILValue.h"
17-
#include "swift/SIL/SILBitfield.h"
17+
#include "swift/SIL/BasicBlockBits.h"
1818
#include "llvm/ADT/SetVector.h"
1919
#include "llvm/ADT/SmallPtrSet.h"
2020
#include "llvm/ADT/SmallVector.h"

include/swift/SIL/LinearLifetimeChecker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "swift/SIL/SILFunction.h"
2222
#include "swift/SIL/SILValue.h"
2323
#include "swift/SIL/BasicBlockUtils.h"
24-
#include "swift/SIL/SILBitfield.h"
24+
#include "swift/SIL/BasicBlockBits.h"
2525
#include "llvm/ADT/SmallPtrSet.h"
2626

2727
namespace swift {

include/swift/SILOptimizer/Utils/BasicBlockOptUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#define SWIFT_SILOPTIMIZER_UTILS_BASICBLOCKOPTUTILS_H
2424

2525
#include "swift/SIL/SILBasicBlock.h"
26-
#include "swift/SIL/SILBitfield.h"
26+
#include "swift/SIL/BasicBlockBits.h"
2727
#include "swift/SIL/SILCloner.h"
2828
#include "swift/SIL/SILInstruction.h"
2929
#include "swift/SILOptimizer/Utils/InstOptUtils.h"

include/swift/SILOptimizer/Utils/ValueLifetime.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "swift/Basic/STLExtras.h"
2121
#include "swift/SIL/SILBuilder.h"
2222
#include "swift/SIL/SILInstruction.h"
23-
#include "swift/SIL/SILBitfield.h"
23+
#include "swift/SIL/BasicBlockBits.h"
2424
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
2525

2626
namespace swift {

lib/IRGen/IRGenSIL.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
#include "swift/SIL/InstructionUtils.h"
3333
#include "swift/SIL/MemAccessUtils.h"
3434
#include "swift/SIL/PrettyStackTrace.h"
35-
#include "swift/SIL/SILBitfield.h"
35+
#include "swift/SIL/BasicBlockBits.h"
3636
#include "swift/SIL/SILDebugScope.h"
3737
#include "swift/SIL/SILDeclRef.h"
3838
#include "swift/SIL/SILLinkage.h"
@@ -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/SIL/Verifier/SILVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +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"
36+
#include "swift/SIL/BasicBlockBits.h"
3737
#include "swift/SIL/SILDebugScope.h"
3838
#include "swift/SIL/SILFunction.h"
3939
#include "swift/SIL/SILModule.h"

lib/SILOptimizer/LoopTransforms/ArrayPropertyOpt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +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"
65+
#include "swift/SIL/BasicBlockBits.h"
6666
#include "swift/SIL/SILCloner.h"
6767
#include "llvm/ADT/SmallSet.h"
6868
#include "llvm/Support/CommandLine.h"

lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +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"
28+
#include "swift/SIL/BasicBlockBits.h"
2929
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
3030
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
3131
#include "swift/SILOptimizer/Analysis/ArraySemantic.h"

lib/SILOptimizer/LoopTransforms/LICM.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +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"
22+
#include "swift/SIL/BasicBlockBits.h"
2323
#include "swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h"
2424
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
2525
#include "swift/SILOptimizer/Analysis/Analysis.h"

0 commit comments

Comments
 (0)