30
30
#include " swift/SIL/FieldSensitivePrunedLiveness.h"
31
31
#include " swift/SIL/InstructionUtils.h"
32
32
#include " swift/SIL/MemAccessUtils.h"
33
+ #include " swift/SIL/OSSALifetimeCompletion.h"
33
34
#include " swift/SIL/OwnershipUtils.h"
34
35
#include " swift/SIL/PrunedLiveness.h"
35
36
#include " swift/SIL/SILArgument.h"
@@ -86,6 +87,7 @@ struct MoveOnlyChecker {
86
87
}
87
88
88
89
void checkObjects ();
90
+ void completeObjectLifetimes (ArrayRef<MarkUnresolvedNonCopyableValueInst *>);
89
91
void checkAddresses ();
90
92
};
91
93
@@ -110,10 +112,66 @@ void MoveOnlyChecker::checkObjects() {
110
112
return ;
111
113
}
112
114
115
+ completeObjectLifetimes (moveIntroducersToProcess.getArrayRef ());
116
+
113
117
MoveOnlyObjectChecker checker{diagnosticEmitter, domTree, poa, allocator};
114
118
madeChange |= checker.check (moveIntroducersToProcess);
115
119
}
116
120
121
+ void MoveOnlyChecker::completeObjectLifetimes (
122
+ ArrayRef<MarkUnresolvedNonCopyableValueInst *> insts) {
123
+ // TODO: Delete once OSSALifetimeCompletion is run as part of SILGenCleanup.
124
+ OSSALifetimeCompletion completion (fn, domTree);
125
+
126
+ // Collect all values derived from each mark_unresolved_non_copyable_value
127
+ // instruction via ownership instructions and phis.
128
+ ValueWorklist transitiveValues (fn);
129
+ for (auto *inst : insts) {
130
+ transitiveValues.push (inst);
131
+ }
132
+ while (auto value = transitiveValues.pop ()) {
133
+ for (auto *use : value->getUses ()) {
134
+ auto *user = use->getUser ();
135
+ switch (user->getKind ()) {
136
+ case SILInstructionKind::BeginBorrowInst:
137
+ case SILInstructionKind::CopyValueInst:
138
+ case SILInstructionKind::MoveValueInst:
139
+ transitiveValues.pushIfNotVisited (cast<SingleValueInstruction>(user));
140
+ break ;
141
+ case SILInstructionKind::BranchInst: {
142
+ PhiOperand po (use);
143
+ transitiveValues.pushIfNotVisited (po.getValue ());
144
+ break ;
145
+ }
146
+ default :
147
+ break ;
148
+ }
149
+ }
150
+ }
151
+ // Complete the lifetime of each collected value. This is a subset of the
152
+ // work that SILGenCleanup wil do.
153
+ for (auto *block : poa->get (fn)->getPostOrder ()) {
154
+ for (SILInstruction &inst : reverse (*block)) {
155
+ for (auto result : inst.getResults ()) {
156
+ if (!transitiveValues.isVisited (result))
157
+ continue ;
158
+ if (completion.completeOSSALifetime (result) ==
159
+ LifetimeCompletion::WasCompleted) {
160
+ madeChange = true ;
161
+ }
162
+ }
163
+ }
164
+ for (SILArgument *arg : block->getArguments ()) {
165
+ if (!transitiveValues.isVisited (arg))
166
+ continue ;
167
+ if (completion.completeOSSALifetime (arg) ==
168
+ LifetimeCompletion::WasCompleted) {
169
+ madeChange = true ;
170
+ }
171
+ }
172
+ }
173
+ }
174
+
117
175
void MoveOnlyChecker::checkAddresses () {
118
176
unsigned diagCount = diagnosticEmitter.getDiagnosticCount ();
119
177
SmallSetVector<MarkUnresolvedNonCopyableValueInst *, 32 >
0 commit comments