9090#define DEBUG_TYPE " ssa-destroy-hoisting"
9191
9292#include " swift/Basic/GraphNodeWorklist.h"
93+ #include " swift/Basic/SmallPtrSetVector.h"
9394#include " swift/SIL/BasicBlockDatastructures.h"
9495#include " swift/SIL/MemAccessUtils.h"
9596#include " swift/SIL/SILBasicBlock.h"
@@ -192,11 +193,11 @@ class DeinitBarriers {
192193public:
193194 // Data flow state: blocks whose beginning is backward reachable from a
194195 // destroy without first reaching a barrier or storage use.
195- BasicBlockSetVector destroyReachesBeginBlocks;
196+ SmallPtrSetVector<SILBasicBlock *, 4 > destroyReachesBeginBlocks;
196197
197198 // Data flow state: blocks whose end is backward reachable from a destroy
198199 // without first reaching a barrier or storage use.
199- BasicBlockSet destroyReachesEndBlocks;
200+ SmallPtrSet<SILBasicBlock *, 4 > destroyReachesEndBlocks;
200201
201202 // Deinit barriers or storage uses within a block, reachable from a destroy.
202203 SmallVector<SILInstruction *, 4 > barriers;
@@ -215,8 +216,7 @@ class DeinitBarriers {
215216 explicit DeinitBarriers (bool ignoreDeinitBarriers,
216217 const KnownStorageUses &knownUses,
217218 SILFunction *function)
218- : destroyReachesBeginBlocks(function), destroyReachesEndBlocks(function),
219- ignoreDeinitBarriers(ignoreDeinitBarriers), knownUses(knownUses) {
219+ : ignoreDeinitBarriers(ignoreDeinitBarriers), knownUses(knownUses) {
220220 auto rootValue = knownUses.getStorage ().getRoot ();
221221 assert (rootValue && " HoistDestroys requires a single storage root" );
222222 // null for function args
@@ -225,6 +225,12 @@ class DeinitBarriers {
225225
226226 void compute () {
227227 FindBarrierAccessScopes (*this ).solveBackward ();
228+ if (barrierAccessScopes.size () == 0 )
229+ return ;
230+ destroyReachesBeginBlocks.clear ();
231+ destroyReachesEndBlocks.clear ();
232+ barriers.clear ();
233+ deadUsers.clear ();
228234 DestroyReachability (*this ).solveBackward ();
229235 }
230236
@@ -289,7 +295,6 @@ class DeinitBarriers {
289295 // open access scopes in the block's predecessors.
290296 class FindBarrierAccessScopes {
291297 DeinitBarriers &result;
292- BasicBlockSetVector destroyReachesBeginBlocks;
293298 llvm::DenseMap<SILBasicBlock *, llvm::SmallPtrSet<BeginAccessInst *, 2 >>
294299 liveInAccessScopes;
295300 llvm::SmallPtrSet<BeginAccessInst *, 2 > runningLiveAccessScopes;
@@ -298,9 +303,7 @@ class DeinitBarriers {
298303
299304 public:
300305 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 ) {
304307 // Seed backward reachability with destroy points.
305308 for (SILInstruction *destroy : result.knownUses .originalDestroys ) {
306309 reachability.initLastUse (destroy);
@@ -314,17 +317,18 @@ class DeinitBarriers {
314317 }
315318
316319 bool hasReachableBegin (SILBasicBlock *block) {
317- return destroyReachesBeginBlocks.contains (block);
320+ return result. destroyReachesBeginBlocks .contains (block);
318321 }
319322
320323 void markReachableBegin (SILBasicBlock *block) {
321- destroyReachesBeginBlocks.insert (block);
324+ result. destroyReachesBeginBlocks .insert (block);
322325 if (!runningLiveAccessScopes.empty ()) {
323326 liveInAccessScopes[block] = runningLiveAccessScopes;
324327 }
325328 }
326329
327330 void markReachableEnd (SILBasicBlock *block) {
331+ result.destroyReachesEndBlocks .insert (block);
328332 runningLiveAccessScopes.clear ();
329333 for (auto *predecessor : block->getPredecessorBlocks ()) {
330334 auto iterator = liveInAccessScopes.find (predecessor);
@@ -347,7 +351,9 @@ class DeinitBarriers {
347351 } else if (auto *bai = dyn_cast<BeginAccessInst>(inst)) {
348352 runningLiveAccessScopes.erase (bai);
349353 }
350- bool isBarrier = result.isBarrier (inst);
354+ auto classification = result.classifyInstruction (inst);
355+ result.visitedInstruction (inst, classification);
356+ auto isBarrier = result.classificationIsBarrier (classification);
351357 if (isBarrier) {
352358 markLiveAccessScopesAsBarriers ();
353359 }
@@ -361,7 +367,7 @@ class DeinitBarriers {
361367 bool checkReachablePhiBarrier (SILBasicBlock *block) {
362368 bool isBarrier =
363369 llvm::any_of (block->getPredecessorBlocks (), [&](auto *predecessor) {
364- return result.isBarrier (block ->getTerminator ());
370+ return result.isBarrier (predecessor ->getTerminator ());
365371 });
366372 if (isBarrier) {
367373 // If there's a barrier preventing us from hoisting out of this block,
@@ -484,8 +490,7 @@ bool DeinitBarriers::DestroyReachability::checkReachablePhiBarrier(
484490 assert (llvm::all_of (block->getArguments (),
485491 [&](auto argument) { return PhiValue (argument); }));
486492 return llvm::any_of (block->getPredecessorBlocks (), [&](auto *predecessor) {
487- return result.classificationIsBarrier (
488- result.classifyInstruction (predecessor->getTerminator ()));
493+ return result.isBarrier (predecessor->getTerminator ());
489494 });
490495}
491496
0 commit comments