@@ -200,7 +200,76 @@ bool isOwnershipForwardingInst(SILInstruction *i);
200
200
201
201
bool isGuaranteedForwardingInst (SILInstruction *i);
202
202
203
- struct BorrowScopeIntroducerKind {
203
+ struct BorrowScopeOperandKind {
204
+ using UnderlyingKindTy = std::underlying_type<SILInstructionKind>::type;
205
+
206
+ enum Kind : UnderlyingKindTy {
207
+ BeginBorrow = UnderlyingKindTy (SILInstructionKind::BeginBorrowInst),
208
+ };
209
+
210
+ Kind value;
211
+
212
+ BorrowScopeOperandKind (Kind newValue) : value(newValue) {}
213
+ BorrowScopeOperandKind (const BorrowScopeOperandKind &other)
214
+ : value(other.value) {}
215
+ operator Kind () const { return value; }
216
+
217
+ static Optional<BorrowScopeOperandKind> get (SILInstructionKind kind) {
218
+ switch (kind) {
219
+ default :
220
+ return None;
221
+ case SILInstructionKind::BeginBorrowInst:
222
+ return BorrowScopeOperandKind (BeginBorrow);
223
+ }
224
+ }
225
+
226
+ void print (llvm::raw_ostream &os) const ;
227
+ LLVM_ATTRIBUTE_DEPRECATED (void dump () const , "only for use in the debugger");
228
+ };
229
+
230
+ // / An operand whose user instruction introduces a new borrow scope for the
231
+ // / operand's value. The value of the operand must be considered as implicitly
232
+ // / borrowed until the user's corresponding end scope instruction.
233
+ struct BorrowScopeOperand {
234
+ BorrowScopeOperandKind kind;
235
+ Operand *op;
236
+
237
+ BorrowScopeOperand (Operand *op)
238
+ : kind(*BorrowScopeOperandKind::get (op->getUser ()->getKind())), op(op) {}
239
+
240
+ // / If value is a borrow introducer return it after doing some checks.
241
+ static Optional<BorrowScopeOperand> get (Operand *op) {
242
+ auto *user = op->getUser ();
243
+ auto kind = BorrowScopeOperandKind::get (user->getKind ());
244
+ if (!kind)
245
+ return None;
246
+ return BorrowScopeOperand (*kind, op);
247
+ }
248
+
249
+ void visitEndScopeInstructions (function_ref<void (Operand *)> func) const {
250
+ switch (kind) {
251
+ case BorrowScopeOperandKind::BeginBorrow:
252
+ for (auto *use : cast<BeginBorrowInst>(op->getUser ())->getUses ()) {
253
+ if (isa<EndBorrowInst>(use->getUser ())) {
254
+ func (use);
255
+ }
256
+ }
257
+ return ;
258
+ }
259
+ llvm_unreachable (" Covered switch isn't covered" );
260
+ }
261
+
262
+ private:
263
+ // / Internal constructor for failable static constructor. Please do not expand
264
+ // / its usage since it assumes the code passed in is well formed.
265
+ BorrowScopeOperand (BorrowScopeOperandKind kind, Operand *op)
266
+ : kind(kind), op(op) {}
267
+ };
268
+
269
+ llvm::raw_ostream &operator <<(llvm::raw_ostream &os,
270
+ BorrowScopeOperandKind kind);
271
+
272
+ struct BorrowScopeIntroducingValueKind {
204
273
using UnderlyingKindTy = std::underlying_type<ValueKind>::type;
205
274
206
275
// / Enum we use for exhaustive pattern matching over borrow scope introducers.
@@ -210,23 +279,23 @@ struct BorrowScopeIntroducerKind {
210
279
SILFunctionArgument = UnderlyingKindTy (ValueKind::SILFunctionArgument),
211
280
};
212
281
213
- static Optional<BorrowScopeIntroducerKind > get (ValueKind kind) {
282
+ static Optional<BorrowScopeIntroducingValueKind > get (ValueKind kind) {
214
283
switch (kind) {
215
284
default :
216
285
return None;
217
286
case ValueKind::LoadBorrowInst:
218
- return BorrowScopeIntroducerKind (LoadBorrow);
287
+ return BorrowScopeIntroducingValueKind (LoadBorrow);
219
288
case ValueKind::BeginBorrowInst:
220
- return BorrowScopeIntroducerKind (BeginBorrow);
289
+ return BorrowScopeIntroducingValueKind (BeginBorrow);
221
290
case ValueKind::SILFunctionArgument:
222
- return BorrowScopeIntroducerKind (SILFunctionArgument);
291
+ return BorrowScopeIntroducingValueKind (SILFunctionArgument);
223
292
}
224
293
}
225
294
226
295
Kind value;
227
296
228
- BorrowScopeIntroducerKind (Kind newValue) : value(newValue) {}
229
- BorrowScopeIntroducerKind (const BorrowScopeIntroducerKind &other)
297
+ BorrowScopeIntroducingValueKind (Kind newValue) : value(newValue) {}
298
+ BorrowScopeIntroducingValueKind (const BorrowScopeIntroducingValueKind &other)
230
299
: value(other.value) {}
231
300
operator Kind () const { return value; }
232
301
@@ -238,10 +307,10 @@ struct BorrowScopeIntroducerKind {
238
307
// / of the scope.
239
308
bool isLocalScope () const {
240
309
switch (value) {
241
- case BorrowScopeIntroducerKind ::BeginBorrow:
242
- case BorrowScopeIntroducerKind ::LoadBorrow:
310
+ case BorrowScopeIntroducingValueKind ::BeginBorrow:
311
+ case BorrowScopeIntroducingValueKind ::LoadBorrow:
243
312
return true ;
244
- case BorrowScopeIntroducerKind ::SILFunctionArgument:
313
+ case BorrowScopeIntroducingValueKind ::SILFunctionArgument:
245
314
return false ;
246
315
}
247
316
llvm_unreachable (" Covered switch isnt covered?!" );
@@ -252,7 +321,7 @@ struct BorrowScopeIntroducerKind {
252
321
};
253
322
254
323
llvm::raw_ostream &operator <<(llvm::raw_ostream &os,
255
- BorrowScopeIntroducerKind kind);
324
+ BorrowScopeIntroducingValueKind kind);
256
325
257
326
// / A higher level construct for working with values that represent the
258
327
// / introduction of a new borrow scope.
@@ -271,26 +340,26 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
271
340
// / borrow introducers can not have guaranteed results that are not creating a
272
341
// / new borrow scope. No such instructions exist today.
273
342
struct BorrowScopeIntroducingValue {
274
- BorrowScopeIntroducerKind kind;
343
+ BorrowScopeIntroducingValueKind kind;
275
344
SILValue value;
276
345
277
346
BorrowScopeIntroducingValue (LoadBorrowInst *lbi)
278
- : kind(BorrowScopeIntroducerKind ::LoadBorrow), value(lbi) {}
347
+ : kind(BorrowScopeIntroducingValueKind ::LoadBorrow), value(lbi) {}
279
348
BorrowScopeIntroducingValue (BeginBorrowInst *bbi)
280
- : kind(BorrowScopeIntroducerKind ::BeginBorrow), value(bbi) {}
349
+ : kind(BorrowScopeIntroducingValueKind ::BeginBorrow), value(bbi) {}
281
350
BorrowScopeIntroducingValue (SILFunctionArgument *arg)
282
- : kind(BorrowScopeIntroducerKind ::SILFunctionArgument), value(arg) {
351
+ : kind(BorrowScopeIntroducingValueKind ::SILFunctionArgument), value(arg) {
283
352
assert (arg->getOwnershipKind () == ValueOwnershipKind::Guaranteed);
284
353
}
285
354
286
355
BorrowScopeIntroducingValue (SILValue v)
287
- : kind(*BorrowScopeIntroducerKind ::get (v->getKind ())), value(v) {
356
+ : kind(*BorrowScopeIntroducingValueKind ::get (v->getKind ())), value(v) {
288
357
assert (v.getOwnershipKind () == ValueOwnershipKind::Guaranteed);
289
358
}
290
359
291
360
// / If value is a borrow introducer return it after doing some checks.
292
361
static Optional<BorrowScopeIntroducingValue> get (SILValue value) {
293
- auto kind = BorrowScopeIntroducerKind ::get (value->getKind ());
362
+ auto kind = BorrowScopeIntroducingValueKind ::get (value->getKind ());
294
363
if (!kind || value.getOwnershipKind () != ValueOwnershipKind::Guaranteed)
295
364
return None;
296
365
return BorrowScopeIntroducingValue (*kind, value);
@@ -334,7 +403,8 @@ struct BorrowScopeIntroducingValue {
334
403
private:
335
404
// / Internal constructor for failable static constructor. Please do not expand
336
405
// / its usage since it assumes the code passed in is well formed.
337
- BorrowScopeIntroducingValue (BorrowScopeIntroducerKind kind, SILValue value)
406
+ BorrowScopeIntroducingValue (BorrowScopeIntroducingValueKind kind,
407
+ SILValue value)
338
408
: kind(kind), value(value) {}
339
409
};
340
410
0 commit comments