2222#include " swift/SIL/SILBuilder.h"
2323#include " swift/SIL/SILFunction.h"
2424#include " swift/SIL/SILUndef.h"
25+ #include " swift/SIL/OSSALifetimeCompletion.h"
2526#include " swift/SILOptimizer/Analysis/DominanceAnalysis.h"
27+ #include " swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
2628#include " swift/SILOptimizer/PassManager/Passes.h"
2729#include " swift/SILOptimizer/PassManager/Transforms.h"
2830#include " swift/SILOptimizer/Utils/BasicBlockOptUtils.h"
@@ -126,7 +128,10 @@ class DCE {
126128 BasicBlockSet LiveBlocks;
127129 llvm::SmallVector<SILInstruction *, 64 > Worklist;
128130 PostDominanceInfo *PDT;
131+ DominanceInfo *DT;
132+ DeadEndBlocks *deadEndBlocks;
129133 llvm::DenseMap<SILBasicBlock *, ControllingInfo> ControllingInfoMap;
134+ llvm::SmallVector<SILValue> valuesToComplete;
130135
131136 // Maps instructions which produce a failing condition (like overflow
132137 // builtins) to the actual cond_fail instructions which handle the failure.
@@ -194,8 +199,10 @@ class DCE {
194199 void endLifetimeOfLiveValue (Operand *op, SILInstruction *insertPt);
195200
196201public:
197- DCE (SILFunction *F, PostDominanceInfo *PDT)
198- : F(F), LiveArguments(F), LiveInstructions(F), LiveBlocks(F), PDT(PDT) {}
202+ DCE (SILFunction *F, PostDominanceInfo *PDT, DominanceInfo *DT,
203+ DeadEndBlocks *deadEndBlocks)
204+ : F(F), LiveArguments(F), LiveInstructions(F), LiveBlocks(F), PDT(PDT),
205+ DT (DT), deadEndBlocks(deadEndBlocks) {}
199206
200207 // / The entry point to the transformation.
201208 bool run () {
@@ -626,6 +633,14 @@ void DCE::endLifetimeOfLiveValue(Operand *op, SILInstruction *insertPt) {
626633 }
627634
628635 assert (op->isLifetimeEnding ());
636+
637+ // If DCE is going to delete the block in which we have to insert a
638+ // compensating lifetime end, let complete lifetimes utility handle it.
639+ if (!LiveBlocks.contains (insertPt->getParent ())) {
640+ valuesToComplete.push_back (value);
641+ return ;
642+ }
643+
629644 SILBuilderWithScope builder (insertPt);
630645 if (value->getOwnershipKind () == OwnershipKind::Owned) {
631646 builder.createDestroyValue (RegularLocation::getAutoGeneratedLocation (),
@@ -772,6 +787,12 @@ bool DCE::removeDead() {
772787 }
773788 }
774789
790+ OSSALifetimeCompletion completion (F, DT, *deadEndBlocks);
791+ for (auto value : valuesToComplete) {
792+ completion.completeOSSALifetime (value,
793+ OSSALifetimeCompletion::Boundary::Liveness);
794+ }
795+
775796 return Changed;
776797}
777798
@@ -977,8 +998,11 @@ class DCEPass : public SILFunctionTransform {
977998 LLVM_DEBUG (llvm::dbgs () << " *** DCE on function: " << F->getName ()
978999 << " ***\n " );
9791000
980- auto *DA = PM->getAnalysis <PostDominanceAnalysis>();
981- PostDominanceInfo *PDT = DA->get (F);
1001+ auto *PDA = PM->getAnalysis <PostDominanceAnalysis>();
1002+ PostDominanceInfo *PDT = PDA->get (F);
1003+
1004+ auto *DA = PM->getAnalysis <DominanceAnalysis>();
1005+ auto *DEA = getAnalysis<DeadEndBlocksAnalysis>();
9821006
9831007 // If we have a function that consists of nothing but a
9841008 // structurally infinite loop like:
@@ -987,7 +1011,7 @@ class DCEPass : public SILFunctionTransform {
9871011 if (!PDT->getRootNode ())
9881012 return ;
9891013
990- DCE dce (F, PDT);
1014+ DCE dce (F, PDT, DA-> get (F), DEA-> get (F) );
9911015 if (dce.run ()) {
9921016 using InvalidationKind = SILAnalysis::InvalidationKind;
9931017 unsigned Inv = InvalidationKind::Instructions;
0 commit comments