18
18
19
19
#include " swift/Basic/Defer.h"
20
20
#include " swift/SIL/BasicBlockUtils.h"
21
+ #include " swift/SIL/OSSALifetimeCompletion.h"
22
+ #include " swift/SIL/PrettyStackTrace.h"
23
+ #include " swift/SIL/PrunedLiveness.h"
21
24
#include " swift/SIL/SILInstruction.h"
25
+ #include " swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
22
26
#include " swift/SILOptimizer/PassManager/Transforms.h"
23
27
#include " swift/SILOptimizer/Utils/CanonicalizeInstruction.h"
24
28
#include " swift/SILOptimizer/Utils/InstOptUtils.h"
@@ -96,14 +100,52 @@ namespace {
96
100
// pipeline runs in bottom-up closure order.
97
101
struct SILGenCleanup : SILModuleTransform {
98
102
void run () override ;
103
+
104
+ bool completeOSSALifetimes (SILFunction *function);
99
105
};
100
106
107
+ bool SILGenCleanup::completeOSSALifetimes (SILFunction *function) {
108
+ if (!getModule ()->getOptions ().OSSACompleteLifetimes )
109
+ return false ;
110
+
111
+ bool changed = false ;
112
+
113
+ // Lifetimes must be completed inside out (bottom-up in the CFG).
114
+ PostOrderFunctionInfo *postOrder =
115
+ getAnalysis<PostOrderAnalysis>()->get (function);
116
+ OSSALifetimeCompletion completion (function, /* DomInfo*/ nullptr );
117
+ for (auto *block : postOrder->getPostOrder ()) {
118
+ for (SILInstruction &inst : reverse (*block)) {
119
+ for (auto result : inst.getResults ()) {
120
+ if (completion.completeOSSALifetime (result) ==
121
+ LifetimeCompletion::WasCompleted) {
122
+ changed = true ;
123
+ }
124
+ }
125
+ }
126
+ for (SILArgument *arg : block->getArguments ()) {
127
+ if (completion.completeOSSALifetime (arg) ==
128
+ LifetimeCompletion::WasCompleted) {
129
+ changed = true ;
130
+ }
131
+ }
132
+ }
133
+ function->verifyOwnership (/* deadEndBlocks=*/ nullptr );
134
+ return changed;
135
+ }
136
+
101
137
void SILGenCleanup::run () {
102
138
auto &module = *getModule ();
103
139
for (auto &function : module ) {
140
+ if (!function.isDefinition ())
141
+ continue ;
142
+
143
+ PrettyStackTraceSILFunction stackTrace (" silgen cleanup" , &function);
144
+
104
145
LLVM_DEBUG (llvm::dbgs ()
105
146
<< " \n Running SILGenCleanup on " << function.getName () << " \n " );
106
147
148
+ bool changed = completeOSSALifetimes (&function);
107
149
DeadEndBlocks deadEndBlocks (&function);
108
150
SILGenCanonicalize sgCanonicalize (deadEndBlocks);
109
151
@@ -116,7 +158,8 @@ void SILGenCleanup::run() {
116
158
ii = sgCanonicalize.deleteDeadOperands (ii, ie);
117
159
}
118
160
}
119
- if (sgCanonicalize.changed ) {
161
+ changed |= sgCanonicalize.changed ;
162
+ if (changed) {
120
163
auto invalidKind = SILAnalysis::InvalidationKind::Instructions;
121
164
invalidateAnalysis (&function, invalidKind);
122
165
}
0 commit comments