@@ -27,15 +27,14 @@ void ValueLifetimeAnalysis::propagateLiveness() {
27
27
// Compute the def block only if we have a SILInstruction. If we have a
28
28
// SILArgument, this will be nullptr.
29
29
auto *defBB = getDefValueParentBlock ();
30
- SmallVector<SILBasicBlock *, 64 > worklist;
31
30
int numUsersBeforeDef = 0 ;
32
31
33
32
// Find the initial set of blocks where the value is live, because
34
33
// it is used in those blocks.
35
34
for (SILInstruction *user : userSet) {
36
35
SILBasicBlock *userBlock = user->getParent ();
37
- if (liveBlocks. insert (userBlock))
38
- worklist .push_back (userBlock);
36
+ if (!inLiveBlocks. testAndSet (userBlock))
37
+ liveBlocks .push_back (userBlock);
39
38
40
39
// A user in the defBB could potentially be located before the defValue. If
41
40
// we had a SILArgument, defBB will be nullptr, so we should always have
@@ -62,8 +61,9 @@ void ValueLifetimeAnalysis::propagateLiveness() {
62
61
63
62
// Now propagate liveness backwards until we hit the block that defines the
64
63
// value.
65
- while (!worklist.empty ()) {
66
- auto *bb = worklist.pop_back_val ();
64
+ unsigned workIdx = 0 ;
65
+ while (workIdx < liveBlocks.size ()) {
66
+ auto *bb = liveBlocks[workIdx++];
67
67
68
68
// Don't go beyond the definition.
69
69
if (bb == defBB && !hasUsersBeforeDef)
@@ -72,8 +72,8 @@ void ValueLifetimeAnalysis::propagateLiveness() {
72
72
for (auto *predBB : bb->getPredecessorBlocks ()) {
73
73
// If it's already in the set, then we've already queued and/or
74
74
// processed the predecessors.
75
- if (liveBlocks. insert (predBB))
76
- worklist .push_back (predBB);
75
+ if (!inLiveBlocks. testAndSet (predBB))
76
+ liveBlocks .push_back (predBB);
77
77
}
78
78
}
79
79
}
@@ -186,7 +186,8 @@ bool ValueLifetimeAnalysis::computeFrontier(FrontierImpl &frontier, Mode mode,
186
186
}
187
187
}
188
188
// Handle "exit" edges from the lifetime region.
189
- llvm::SmallPtrSet<SILBasicBlock *, 16 > unhandledFrontierBlocks;
189
+ BasicBlockSet unhandledFrontierBlocks (getFunction ());
190
+ bool unhandledFrontierBlocksFound = false ;
190
191
for (SILBasicBlock *frontierBB : frontierBlocks) {
191
192
assert (mode != UsersMustPostDomDef);
192
193
bool needSplit = false ;
@@ -201,12 +202,13 @@ bool ValueLifetimeAnalysis::computeFrontier(FrontierImpl &frontier, Mode mode,
201
202
if (needSplit) {
202
203
// We need to split the critical edge to create a frontier instruction.
203
204
unhandledFrontierBlocks.insert (frontierBB);
205
+ unhandledFrontierBlocksFound = true ;
204
206
} else {
205
207
// The first instruction of the exit-block is part of the frontier.
206
208
frontier.push_back (&*frontierBB->begin ());
207
209
}
208
210
}
209
- if (unhandledFrontierBlocks. size () == 0 ) {
211
+ if (!unhandledFrontierBlocksFound ) {
210
212
return true ;
211
213
}
212
214
@@ -222,7 +224,7 @@ bool ValueLifetimeAnalysis::computeFrontier(FrontierImpl &frontier, Mode mode,
222
224
succBlocks.push_back (succ);
223
225
224
226
for (unsigned i = 0 , e = succBlocks.size (); i != e; ++i) {
225
- if (unhandledFrontierBlocks.count (succBlocks[i])) {
227
+ if (unhandledFrontierBlocks.contains (succBlocks[i])) {
226
228
assert ((isCriticalEdge (term, i) || userSet.count (term)) &&
227
229
" actually not a critical edge?" );
228
230
noCriticalEdges = false ;
@@ -244,7 +246,7 @@ bool ValueLifetimeAnalysis::computeFrontier(FrontierImpl &frontier, Mode mode,
244
246
bool ValueLifetimeAnalysis::isWithinLifetime (SILInstruction *inst) {
245
247
SILBasicBlock *bb = inst->getParent ();
246
248
// Check if the value is not live anywhere in inst's block.
247
- if (!liveBlocks. count (bb))
249
+ if (!inLiveBlocks. get (bb))
248
250
return false ;
249
251
for (const SILSuccessor &succ : bb->getSuccessors ()) {
250
252
// If the value is live at the beginning of any successor block it is also
@@ -288,7 +290,7 @@ blockContainsDeallocRef(SILBasicBlock *bb,
288
290
}
289
291
290
292
bool ValueLifetimeAnalysis::containsDeallocRef (const FrontierImpl &frontier) {
291
- SmallPtrSet<SILBasicBlock *, 8 > frontierBlocks;
293
+ BasicBlockSet frontierBlocks ( getFunction ()) ;
292
294
// Search in live blocks where the value is not alive until the end of the
293
295
// block, i.e. the live range is terminated by a frontier instruction.
294
296
for (SILInstruction *frontierInst : frontier) {
@@ -300,7 +302,7 @@ bool ValueLifetimeAnalysis::containsDeallocRef(const FrontierImpl &frontier) {
300
302
// Search in all other live blocks where the value is alive until the end of
301
303
// the block.
302
304
for (SILBasicBlock *bb : liveBlocks) {
303
- if (frontierBlocks.count (bb) == 0 ) {
305
+ if (frontierBlocks.contains (bb) == 0 ) {
304
306
if (blockContainsDeallocRef (bb, defValue, bb->getTerminator ()))
305
307
return true ;
306
308
}
0 commit comments