@@ -255,6 +255,9 @@ struct BorrowedValue;
255
255
// / borrowed and thus the incoming value must implicitly be borrowed until the
256
256
// / user's corresponding end scope instruction.
257
257
// /
258
+ // / Invariant: For a given operand, BorrowingOperand is valid iff
259
+ // / it has OperandOwnership::Borrow or OperandOwnership::Reborrow.
260
+ // /
258
261
// / NOTE: We do not require that the guaranteed scope be represented by a
259
262
// / guaranteed value in the same function: see begin_apply. In such cases, we
260
263
// / require instead an end_* instruction to mark the end of the scope's region.
@@ -264,10 +267,14 @@ struct BorrowingOperand {
264
267
265
268
BorrowingOperand (Operand *op)
266
269
: op(op), kind(BorrowingOperandKind::get(op->getUser ()->getKind())) {
267
- if (kind == BorrowingOperandKind::Branch
268
- && op->get ().getOwnershipKind () != OwnershipKind::Guaranteed) {
270
+ auto ownership = op->getOperandOwnership ();
271
+ if (ownership != OperandOwnership::Borrow
272
+ && ownership != OperandOwnership::Reborrow) {
273
+ // consuming applies and branch arguments are not borrowing operands.
269
274
kind = BorrowingOperandKind::Invalid;
275
+ return ;
270
276
}
277
+ assert (kind != BorrowingOperandKind::Invalid && " missing case" );
271
278
}
272
279
BorrowingOperand (const BorrowingOperand &other)
273
280
: op(other.op), kind(other.kind) {}
@@ -284,28 +291,7 @@ struct BorrowingOperand {
284
291
const Operand *operator ->() const { return op; }
285
292
Operand *operator ->() { return op; }
286
293
287
- operator bool () const { return kind != BorrowingOperandKind::Invalid && op; }
288
-
289
- // / If \p op is a borrow introducing operand return it after doing some
290
- // / checks.
291
- static BorrowingOperand get (Operand *op) {
292
- auto *user = op->getUser ();
293
- auto kind = BorrowingOperandKind::get (user->getKind ());
294
- if (!kind)
295
- return {nullptr , kind};
296
-
297
- if (kind == BorrowingOperandKind::Branch
298
- && op->get ().getOwnershipKind () != OwnershipKind::Guaranteed) {
299
- return {nullptr , BorrowingOperandKind::Invalid};
300
- }
301
- return {op, kind};
302
- }
303
-
304
- // / If \p op is a borrow introducing operand return it after doing some
305
- // / checks.
306
- static BorrowingOperand get (const Operand *op) {
307
- return get (const_cast <Operand *>(op));
308
- }
294
+ operator bool () const { return kind != BorrowingOperandKind::Invalid; }
309
295
310
296
// / If this borrowing operand results in the underlying value being borrowed
311
297
// / over a region of code instead of just for a single instruction, visit
@@ -347,8 +333,14 @@ struct BorrowingOperand {
347
333
llvm_unreachable (" Covered switch isn't covered?!" );
348
334
}
349
335
350
- // / Return true if the user instruction introduces a borrow scope? This is
351
- // / true for both reborrows and nested borrows.
336
+ // / Return true if the user instruction defines a borrowed value that
337
+ // / introduces a borrow scope and therefore may be reborrowed. This is true
338
+ // / for both reborrows and nested borrows.
339
+ // /
340
+ // / Note that begin_apply does create a borrow scope, and may define
341
+ // / guaranteed value within that scope. The difference is that those yielded
342
+ // / values do not themselves introduce a borrow scope. In other words, they
343
+ // / cannot be reborrowed.
352
344
// /
353
345
// / If true, the visitBorrowIntroducingUserResults() can be called to acquire
354
346
// / each BorrowedValue that introduces a new borrow scopes.
@@ -599,7 +591,7 @@ struct BorrowedValue {
599
591
&foundReborrows) const {
600
592
bool foundAnyReborrows = false ;
601
593
for (auto *op : value->getUses ()) {
602
- if (auto borrowingOperand = BorrowingOperand::get (op)) {
594
+ if (auto borrowingOperand = BorrowingOperand (op)) {
603
595
if (borrowingOperand.isReborrow ()) {
604
596
foundReborrows.push_back (
605
597
{value->getParentBlock (), op->getOperandNumber ()});
0 commit comments