22
22
#include " swift/SIL/SILBuilder.h"
23
23
#include " swift/SIL/SILFunction.h"
24
24
#include " swift/SIL/SILUndef.h"
25
+ #include " swift/SIL/OSSALifetimeCompletion.h"
25
26
#include " swift/SILOptimizer/Analysis/DominanceAnalysis.h"
27
+ #include " swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
26
28
#include " swift/SILOptimizer/PassManager/Passes.h"
27
29
#include " swift/SILOptimizer/PassManager/Transforms.h"
28
30
#include " swift/SILOptimizer/Utils/BasicBlockOptUtils.h"
@@ -126,7 +128,10 @@ class DCE {
126
128
BasicBlockSet LiveBlocks;
127
129
llvm::SmallVector<SILInstruction *, 64 > Worklist;
128
130
PostDominanceInfo *PDT;
131
+ DominanceInfo *DT;
132
+ DeadEndBlocks *deadEndBlocks;
129
133
llvm::DenseMap<SILBasicBlock *, ControllingInfo> ControllingInfoMap;
134
+ llvm::SmallVector<SILValue> valuesToComplete;
130
135
131
136
// Maps instructions which produce a failing condition (like overflow
132
137
// builtins) to the actual cond_fail instructions which handle the failure.
@@ -194,8 +199,10 @@ class DCE {
194
199
void endLifetimeOfLiveValue (Operand *op, SILInstruction *insertPt);
195
200
196
201
public:
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) {}
199
206
200
207
// / The entry point to the transformation.
201
208
bool run () {
@@ -626,6 +633,14 @@ void DCE::endLifetimeOfLiveValue(Operand *op, SILInstruction *insertPt) {
626
633
}
627
634
628
635
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
+
629
644
SILBuilderWithScope builder (insertPt);
630
645
if (value->getOwnershipKind () == OwnershipKind::Owned) {
631
646
builder.createDestroyValue (RegularLocation::getAutoGeneratedLocation (),
@@ -772,6 +787,12 @@ bool DCE::removeDead() {
772
787
}
773
788
}
774
789
790
+ OSSALifetimeCompletion completion (F, DT, *deadEndBlocks);
791
+ for (auto value : valuesToComplete) {
792
+ completion.completeOSSALifetime (value,
793
+ OSSALifetimeCompletion::Boundary::Liveness);
794
+ }
795
+
775
796
return Changed;
776
797
}
777
798
@@ -977,8 +998,11 @@ class DCEPass : public SILFunctionTransform {
977
998
LLVM_DEBUG (llvm::dbgs () << " *** DCE on function: " << F->getName ()
978
999
<< " ***\n " );
979
1000
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>();
982
1006
983
1007
// If we have a function that consists of nothing but a
984
1008
// structurally infinite loop like:
@@ -987,7 +1011,7 @@ class DCEPass : public SILFunctionTransform {
987
1011
if (!PDT->getRootNode ())
988
1012
return ;
989
1013
990
- DCE dce (F, PDT);
1014
+ DCE dce (F, PDT, DA-> get (F), DEA-> get (F) );
991
1015
if (dce.run ()) {
992
1016
using InvalidationKind = SILAnalysis::InvalidationKind;
993
1017
unsigned Inv = InvalidationKind::Instructions;
0 commit comments