4949// /
5050// ===----------------------------------------------------------------------===//
5151
52- #include " swift/Basic/Assertions.h"
5352#include " swift/SIL/OSSALifetimeCompletion.h"
53+ #include " swift/Basic/Assertions.h"
54+ #include " swift/SIL/BasicBlockUtils.h"
5455#include " swift/SIL/SILBuilder.h"
5556#include " swift/SIL/SILFunction.h"
5657#include " swift/SIL/SILInstruction.h"
@@ -61,23 +62,26 @@ using namespace swift;
6162
6263static SILInstruction *endOSSALifetime (SILValue value,
6364 OSSALifetimeCompletion::LifetimeEnd end,
64- SILBuilder &builder) {
65+ SILBuilder &builder,
66+ DeadEndBlocks &deb) {
6567 auto loc =
6668 RegularLocation::getAutoGeneratedLocation (builder.getInsertionPointLoc ());
6769 if (end == OSSALifetimeCompletion::LifetimeEnd::Loop) {
6870 return builder.createExtendLifetime (loc, value);
6971 }
72+ auto isDeadEnd = IsDeadEnd_t (deb.isDeadEnd (builder.getInsertionBB ()));
7073 if (value->getOwnershipKind () == OwnershipKind::Owned) {
7174 if (value->getType ().is <SILBoxType>()) {
72- return builder.createDeallocBox (loc, value);
75+ return builder.createDeallocBox (loc, value, isDeadEnd );
7376 }
74- return builder.createDestroyValue (loc, value);
77+ return builder.createDestroyValue (loc, value, DontPoisonRefs, isDeadEnd );
7578 }
76- return builder.createEndBorrow (loc, value);
79+ return builder.createEndBorrow (loc, value, isDeadEnd );
7780}
7881
7982static bool endLifetimeAtLivenessBoundary (SILValue value,
80- const SSAPrunedLiveness &liveness) {
83+ const SSAPrunedLiveness &liveness,
84+ DeadEndBlocks &deb) {
8185 PrunedLivenessBoundary boundary;
8286 liveness.computeBoundary (boundary);
8387
@@ -86,17 +90,18 @@ static bool endLifetimeAtLivenessBoundary(SILValue value,
8690 if (liveness.isInterestingUser (lastUser)
8791 != PrunedLiveness::LifetimeEndingUse) {
8892 changed = true ;
89- SILBuilderWithScope::insertAfter (lastUser, [value](SILBuilder &builder) {
93+ SILBuilderWithScope::insertAfter (lastUser, [value,
94+ &deb](SILBuilder &builder) {
9095 endOSSALifetime (value, OSSALifetimeCompletion::LifetimeEnd::Boundary,
91- builder);
96+ builder, deb );
9297 });
9398 }
9499 }
95100 for (SILBasicBlock *edge : boundary.boundaryEdges ) {
96101 changed = true ;
97102 SILBuilderWithScope builder (edge->begin ());
98103 endOSSALifetime (value, OSSALifetimeCompletion::LifetimeEnd::Boundary,
99- builder);
104+ builder, deb );
100105 }
101106 for (SILNode *deadDef : boundary.deadDefs ) {
102107 SILInstruction *next = nullptr ;
@@ -108,7 +113,7 @@ static bool endLifetimeAtLivenessBoundary(SILValue value,
108113 changed = true ;
109114 SILBuilderWithScope builder (next);
110115 endOSSALifetime (value, OSSALifetimeCompletion::LifetimeEnd::Boundary,
111- builder);
116+ builder, deb );
112117 }
113118 return changed;
114119}
@@ -395,14 +400,14 @@ void OSSALifetimeCompletion::visitAvailabilityBoundary(
395400 });
396401}
397402
398- static bool
399- endLifetimeAtAvailabilityBoundary (SILValue value ,
400- const SSAPrunedLiveness &liveness ) {
403+ static bool endLifetimeAtAvailabilityBoundary (SILValue value,
404+ const SSAPrunedLiveness &liveness ,
405+ DeadEndBlocks &deb ) {
401406 bool changed = false ;
402407 OSSALifetimeCompletion::visitAvailabilityBoundary (
403408 value, liveness, [&](auto *unreachable, auto end) {
404409 SILBuilderWithScope builder (unreachable);
405- endOSSALifetime (value, end, builder);
410+ endOSSALifetime (value, end, builder, deb );
406411 changed = true ;
407412 });
408413 return changed;
@@ -424,10 +429,12 @@ bool OSSALifetimeCompletion::analyzeAndUpdateLifetime(SILValue value,
424429 bool changed = false ;
425430 switch (boundary) {
426431 case Boundary::Liveness:
427- changed |= endLifetimeAtLivenessBoundary (value, liveness.getLiveness ());
432+ changed |= endLifetimeAtLivenessBoundary (value, liveness.getLiveness (),
433+ deadEndBlocks);
428434 break ;
429435 case Boundary::Availability:
430- changed |= endLifetimeAtAvailabilityBoundary (value, liveness.getLiveness ());
436+ changed |= endLifetimeAtAvailabilityBoundary (value, liveness.getLiveness (),
437+ deadEndBlocks);
431438 break ;
432439 }
433440 // TODO: Rebuild outer adjacent phis on demand (SILGen does not currently
@@ -453,9 +460,10 @@ static FunctionTest OSSALifetimeCompletionTest(
453460 .Case (" liveness" , OSSALifetimeCompletion::Boundary::Liveness)
454461 .Case (" availability" ,
455462 OSSALifetimeCompletion::Boundary::Availability);
463+ auto *deb = test.getDeadEndBlocks ();
456464 llvm::outs () << " OSSA lifetime completion on " << kind
457465 << " boundary: " << value;
458- OSSALifetimeCompletion completion (&function, /* domInfo*/ nullptr );
466+ OSSALifetimeCompletion completion (&function, /* domInfo*/ nullptr , *deb );
459467 completion.completeOSSALifetime (value, kind);
460468 function.print (llvm::outs ());
461469 });
@@ -532,7 +540,7 @@ bool UnreachableLifetimeCompletion::completeLifetimes() {
532540 }
533541 }
534542
535- OSSALifetimeCompletion completion (function, domInfo);
543+ OSSALifetimeCompletion completion (function, domInfo, deadEndBlocks );
536544
537545 bool changed = false ;
538546 for (auto value : incompleteValues) {
0 commit comments