90
90
#define DEBUG_TYPE " ssa-destroy-hoisting"
91
91
92
92
#include " swift/Basic/GraphNodeWorklist.h"
93
+ #include " swift/Basic/SmallPtrSetVector.h"
93
94
#include " swift/SIL/BasicBlockDatastructures.h"
94
95
#include " swift/SIL/MemAccessUtils.h"
95
96
#include " swift/SIL/SILBasicBlock.h"
@@ -192,11 +193,11 @@ class DeinitBarriers {
192
193
public:
193
194
// Data flow state: blocks whose beginning is backward reachable from a
194
195
// destroy without first reaching a barrier or storage use.
195
- BasicBlockSetVector destroyReachesBeginBlocks;
196
+ SmallPtrSetVector<SILBasicBlock *, 4 > destroyReachesBeginBlocks;
196
197
197
198
// Data flow state: blocks whose end is backward reachable from a destroy
198
199
// without first reaching a barrier or storage use.
199
- BasicBlockSet destroyReachesEndBlocks;
200
+ SmallPtrSet<SILBasicBlock *, 4 > destroyReachesEndBlocks;
200
201
201
202
// Deinit barriers or storage uses within a block, reachable from a destroy.
202
203
SmallVector<SILInstruction *, 4 > barriers;
@@ -215,8 +216,7 @@ class DeinitBarriers {
215
216
explicit DeinitBarriers (bool ignoreDeinitBarriers,
216
217
const KnownStorageUses &knownUses,
217
218
SILFunction *function)
218
- : destroyReachesBeginBlocks(function), destroyReachesEndBlocks(function),
219
- ignoreDeinitBarriers(ignoreDeinitBarriers), knownUses(knownUses) {
219
+ : ignoreDeinitBarriers(ignoreDeinitBarriers), knownUses(knownUses) {
220
220
auto rootValue = knownUses.getStorage ().getRoot ();
221
221
assert (rootValue && " HoistDestroys requires a single storage root" );
222
222
// null for function args
@@ -225,6 +225,12 @@ class DeinitBarriers {
225
225
226
226
void compute () {
227
227
FindBarrierAccessScopes (*this ).solveBackward ();
228
+ if (barrierAccessScopes.size () == 0 )
229
+ return ;
230
+ destroyReachesBeginBlocks.clear ();
231
+ destroyReachesEndBlocks.clear ();
232
+ barriers.clear ();
233
+ deadUsers.clear ();
228
234
DestroyReachability (*this ).solveBackward ();
229
235
}
230
236
@@ -289,7 +295,6 @@ class DeinitBarriers {
289
295
// open access scopes in the block's predecessors.
290
296
class FindBarrierAccessScopes {
291
297
DeinitBarriers &result;
292
- BasicBlockSetVector destroyReachesBeginBlocks;
293
298
llvm::DenseMap<SILBasicBlock *, llvm::SmallPtrSet<BeginAccessInst *, 2 >>
294
299
liveInAccessScopes;
295
300
llvm::SmallPtrSet<BeginAccessInst *, 2 > runningLiveAccessScopes;
@@ -298,9 +303,7 @@ class DeinitBarriers {
298
303
299
304
public:
300
305
FindBarrierAccessScopes (DeinitBarriers &result)
301
- : result(result),
302
- destroyReachesBeginBlocks (result.knownUses.getFunction()),
303
- reachability(result.knownUses.getFunction(), *this) {
306
+ : result(result), reachability(result.knownUses.getFunction(), *this ) {
304
307
// Seed backward reachability with destroy points.
305
308
for (SILInstruction *destroy : result.knownUses .originalDestroys ) {
306
309
reachability.initLastUse (destroy);
@@ -314,17 +317,18 @@ class DeinitBarriers {
314
317
}
315
318
316
319
bool hasReachableBegin (SILBasicBlock *block) {
317
- return destroyReachesBeginBlocks.contains (block);
320
+ return result. destroyReachesBeginBlocks .contains (block);
318
321
}
319
322
320
323
void markReachableBegin (SILBasicBlock *block) {
321
- destroyReachesBeginBlocks.insert (block);
324
+ result. destroyReachesBeginBlocks .insert (block);
322
325
if (!runningLiveAccessScopes.empty ()) {
323
326
liveInAccessScopes[block] = runningLiveAccessScopes;
324
327
}
325
328
}
326
329
327
330
void markReachableEnd (SILBasicBlock *block) {
331
+ result.destroyReachesEndBlocks .insert (block);
328
332
runningLiveAccessScopes.clear ();
329
333
for (auto *predecessor : block->getPredecessorBlocks ()) {
330
334
auto iterator = liveInAccessScopes.find (predecessor);
@@ -347,7 +351,9 @@ class DeinitBarriers {
347
351
} else if (auto *bai = dyn_cast<BeginAccessInst>(inst)) {
348
352
runningLiveAccessScopes.erase (bai);
349
353
}
350
- bool isBarrier = result.isBarrier (inst);
354
+ auto classification = result.classifyInstruction (inst);
355
+ result.visitedInstruction (inst, classification);
356
+ auto isBarrier = result.classificationIsBarrier (classification);
351
357
if (isBarrier) {
352
358
markLiveAccessScopesAsBarriers ();
353
359
}
@@ -361,7 +367,7 @@ class DeinitBarriers {
361
367
bool checkReachablePhiBarrier (SILBasicBlock *block) {
362
368
bool isBarrier =
363
369
llvm::any_of (block->getPredecessorBlocks (), [&](auto *predecessor) {
364
- return result.isBarrier (block ->getTerminator ());
370
+ return result.isBarrier (predecessor ->getTerminator ());
365
371
});
366
372
if (isBarrier) {
367
373
// If there's a barrier preventing us from hoisting out of this block,
@@ -484,8 +490,7 @@ bool DeinitBarriers::DestroyReachability::checkReachablePhiBarrier(
484
490
assert (llvm::all_of (block->getArguments (),
485
491
[&](auto argument) { return PhiValue (argument); }));
486
492
return llvm::any_of (block->getPredecessorBlocks (), [&](auto *predecessor) {
487
- return result.classificationIsBarrier (
488
- result.classifyInstruction (predecessor->getTerminator ()));
493
+ return result.isBarrier (predecessor->getTerminator ());
489
494
});
490
495
}
491
496
0 commit comments