@@ -127,6 +127,9 @@ class SILValueOwnershipChecker {
127
127
128
128
private:
129
129
bool checkUses ();
130
+ bool isCompatibleDefUse (Operand *op, ValueOwnershipKind ownershipKind,
131
+ bool isGuaranteed);
132
+
130
133
bool gatherUsers (SmallVectorImpl<Operand *> &lifetimeEndingUsers,
131
134
SmallVectorImpl<Operand *> ®ularUsers,
132
135
SmallVectorImpl<Operand *> &implicitRegularUsers);
@@ -184,6 +187,49 @@ bool SILValueOwnershipChecker::check() {
184
187
return result.getValue ();
185
188
}
186
189
190
+ bool SILValueOwnershipChecker::isCompatibleDefUse (
191
+ Operand *op, ValueOwnershipKind ownershipKind, bool isGuaranteed) {
192
+ bool isGuaranteedSubValue = false ;
193
+ if (isGuaranteed && isGuaranteedForwardingInst (op->getUser ())) {
194
+ isGuaranteedSubValue = true ;
195
+ }
196
+ auto *user = op->getUser ();
197
+ auto opOwnershipKindMap = op->getOwnershipKindMap (isGuaranteedSubValue);
198
+ // If our ownership kind doesn't match, track that we found an error, emit
199
+ // an error message optionally and then continue.
200
+ if (opOwnershipKindMap.canAcceptKind (ownershipKind)) {
201
+ return true ;
202
+ }
203
+
204
+ // If we did not support /any/ ownership kind, it means that we found a
205
+ // conflicting answer so the kind map that was returned is the empty
206
+ // map. Put out a more specific error here.
207
+ if (!opOwnershipKindMap.data .any ()) {
208
+ handleError ([&]() {
209
+ llvm::errs () << " Function: '" << user->getFunction ()->getName () << " '\n "
210
+ << " Ill-formed SIL! Unable to compute ownership kind "
211
+ " map for user?!\n "
212
+ << " For terminator users, check that successors have "
213
+ " compatible ownership kinds.\n "
214
+ << " Value: " << op->get () << " User: " << *user
215
+ << " Operand Number: " << op->getOperandNumber () << ' \n '
216
+ << " Conv: " << ownershipKind << " \n\n " ;
217
+ });
218
+ return false ;
219
+ }
220
+
221
+ handleError ([&]() {
222
+ llvm::errs () << " Function: '" << user->getFunction ()->getName () << " '\n "
223
+ << " Have operand with incompatible ownership?!\n "
224
+ << " Value: " << op->get () << " User: " << *user
225
+ << " Operand Number: " << op->getOperandNumber () << ' \n '
226
+ << " Conv: " << ownershipKind << ' \n '
227
+ << " OwnershipMap:\n "
228
+ << opOwnershipKindMap << ' \n ' ;
229
+ });
230
+ return false ;
231
+ }
232
+
187
233
bool SILValueOwnershipChecker::gatherUsers (
188
234
SmallVectorImpl<Operand *> &lifetimeEndingUsers,
189
235
SmallVectorImpl<Operand *> &nonLifetimeEndingUsers,
@@ -214,50 +260,15 @@ bool SILValueOwnershipChecker::gatherUsers(
214
260
if (user->isTypeDependentOperand (*op))
215
261
continue ;
216
262
217
- bool isGuaranteedSubValue = false ;
218
- if (isGuaranteed && isGuaranteedForwardingInst (op->getUser ())) {
219
- isGuaranteedSubValue = true ;
220
- }
221
-
222
- auto opOwnershipKindMap = op->getOwnershipKindMap (isGuaranteedSubValue);
223
- // If our ownership kind doesn't match, track that we found an error, emit
224
- // an error message optionally and then continue.
225
- if (!opOwnershipKindMap.canAcceptKind (ownershipKind)) {
263
+ // First check if this recursive use is compatible with our values ownership
264
+ // kind. If not, flag the error and continue so that we can report more
265
+ // errors.
266
+ if (!isCompatibleDefUse (op, ownershipKind, isGuaranteed)) {
226
267
foundError = true ;
227
-
228
- // If we did not support /any/ ownership kind, it means that we found a
229
- // conflicting answer so the kind map that was returned is the empty
230
- // map. Put out a more specific error here.
231
- if (!opOwnershipKindMap.data .any ()) {
232
- handleError ([&]() {
233
- llvm::errs () << " Function: '" << user->getFunction ()->getName ()
234
- << " '\n "
235
- << " Ill-formed SIL! Unable to compute ownership kind "
236
- " map for user?!\n "
237
- << " For terminator users, check that successors have "
238
- " compatible ownership kinds.\n "
239
- << " Value: " << op->get () << " User: " << *user
240
- << " Operand Number: " << op->getOperandNumber () << ' \n '
241
- << " Conv: " << ownershipKind << " \n\n " ;
242
- });
243
- continue ;
244
- }
245
-
246
- handleError ([&]() {
247
- llvm::errs () << " Function: '" << user->getFunction ()->getName () << " '\n "
248
- << " Have operand with incompatible ownership?!\n "
249
- << " Value: " << op->get () << " User: " << *user
250
- << " Operand Number: " << op->getOperandNumber () << ' \n '
251
- << " Conv: " << ownershipKind << ' \n '
252
- << " OwnershipMap:\n "
253
- << opOwnershipKindMap << ' \n ' ;
254
- });
255
268
continue ;
256
269
}
257
270
258
- auto lifetimeConstraint =
259
- opOwnershipKindMap.getLifetimeConstraint (ownershipKind);
260
- if (lifetimeConstraint == UseLifetimeConstraint::MustBeInvalidated) {
271
+ if (op->isConsumingUse ()) {
261
272
LLVM_DEBUG (llvm::dbgs () << " Lifetime Ending User: " << *user);
262
273
lifetimeEndingUsers.push_back (op);
263
274
} else {
0 commit comments