@@ -356,133 +356,7 @@ struct UseState {
356
356
SILFunction *getFunction () const { return address->getFunction (); }
357
357
};
358
358
359
- // / Visit all of the uses of a lexical lifetime, initializing useState as we go.
360
- struct GatherLexicalLifetimeUseVisitor : public AccessUseVisitor {
361
- UseState &useState;
362
-
363
- GatherLexicalLifetimeUseVisitor (UseState &useState)
364
- : AccessUseVisitor(AccessUseType::Overlapping,
365
- NestedAccessType::IgnoreAccessBegin),
366
- useState (useState) {}
367
-
368
- bool visitUse (Operand *op, AccessUseType useTy) override ;
369
- void reset (SILValue address) { useState.address = address; }
370
- void clear () { useState.clear (); }
371
- };
372
-
373
- } // end anonymous namespace
374
-
375
- static void convertMemoryReinitToInitForm (SILInstruction *memInst) {
376
- switch (memInst->getKind ()) {
377
- default :
378
- llvm_unreachable (" unsupported?!" );
379
-
380
- case SILInstructionKind::CopyAddrInst: {
381
- auto *cai = cast<CopyAddrInst>(memInst);
382
- cai->setIsInitializationOfDest (IsInitialization_t::IsInitialization);
383
- return ;
384
- }
385
- case SILInstructionKind::StoreInst: {
386
- auto *si = cast<StoreInst>(memInst);
387
- si->setOwnershipQualifier (StoreOwnershipQualifier::Init);
388
- return ;
389
- }
390
- }
391
- }
392
-
393
- static bool memInstMustReinitialize (Operand *memOper) {
394
- SILValue address = memOper->get ();
395
- auto *memInst = memOper->getUser ();
396
- switch (memInst->getKind ()) {
397
- default :
398
- return false ;
399
-
400
- case SILInstructionKind::CopyAddrInst: {
401
- auto *CAI = cast<CopyAddrInst>(memInst);
402
- return CAI->getDest () == address && !CAI->isInitializationOfDest ();
403
- }
404
- case SILInstructionKind::StoreInst: {
405
- auto *si = cast<StoreInst>(memInst);
406
- return si->getDest () == address &&
407
- si->getOwnershipQualifier () == StoreOwnershipQualifier::Assign;
408
- }
409
- }
410
- }
411
-
412
- // Filter out recognized uses that do not write to memory.
413
- //
414
- // TODO: Ensure that all of the conditional-write logic below is encapsulated in
415
- // mayWriteToMemory and just call that instead. Possibly add additional
416
- // verification that visitAccessPathUses recognizes all instructions that may
417
- // propagate pointers (even though they don't write).
418
- bool GatherLexicalLifetimeUseVisitor::visitUse (Operand *op,
419
- AccessUseType useTy) {
420
- // If this operand is for a dependent type, then it does not actually access
421
- // the operand's address value. It only uses the metatype defined by the
422
- // operation (e.g. open_existential).
423
- if (op->isTypeDependent ()) {
424
- return true ;
425
- }
426
-
427
- // If we have a move from src, this is a mark_move we want to visit.
428
- if (auto *move = dyn_cast<MarkUnresolvedMoveAddrInst>(op->getUser ())) {
429
- if (move->getSrc () == op->get ()) {
430
- LLVM_DEBUG (llvm::dbgs () << " Found move: " << *move);
431
- useState.insertMarkUnresolvedMoveAddr (move);
432
- return true ;
433
- }
434
- }
435
-
436
- if (memInstMustInitialize (op)) {
437
- LLVM_DEBUG (llvm::dbgs () << " Found init: " << *op->getUser ());
438
- useState.inits .insert (op->getUser ());
439
- return true ;
440
- }
441
-
442
- if (memInstMustReinitialize (op)) {
443
- LLVM_DEBUG (llvm::dbgs () << " Found reinit: " << *op->getUser ());
444
- useState.insertReinit (op->getUser ());
445
- return true ;
446
- }
447
-
448
- if (auto *dvi = dyn_cast<DestroyAddrInst>(op->getUser ())) {
449
- // If we see a destroy_addr not on our base address, bail! Just error and
450
- // say that we do not understand the code.
451
- if (dvi->getOperand () != useState.address ) {
452
- LLVM_DEBUG (llvm::dbgs ()
453
- << " !!! Error! Found destroy_addr no on base address: "
454
- << *dvi);
455
- return false ;
456
- }
457
- LLVM_DEBUG (llvm::dbgs () << " Found destroy_addr: " << *dvi);
458
- useState.insertDestroy (dvi);
459
- return true ;
460
- }
461
-
462
- // Then see if we have a inout_aliasable full apply site use. In that case, we
463
- // are going to try and extend move checking into the partial apply using
464
- // cloning to eliminate destroys or reinits.
465
- if (auto fas = FullApplySite::isa (op->getUser ())) {
466
- if (fas.getArgumentOperandConvention (*op) ==
467
- SILArgumentConvention::Indirect_InoutAliasable) {
468
- // If we don't find the function, we can't handle this, so bail.
469
- auto *func = fas.getCalleeFunction ();
470
- if (!func || !func->isDefer ())
471
- return false ;
472
- useState.insertClosureOperand (op);
473
- return true ;
474
- }
475
- }
476
-
477
- // Ignore dealloc_stack.
478
- if (isa<DeallocStackInst>(op->getUser ()))
479
- return true ;
480
-
481
- LLVM_DEBUG (llvm::dbgs () << " Found liveness use: " << *op->getUser ());
482
- useState.livenessUses .insert (op->getUser ());
483
-
484
- return true ;
485
- }
359
+ } // namespace
486
360
487
361
// ===----------------------------------------------------------------------===//
488
362
// Dataflow
@@ -1356,6 +1230,103 @@ void ClosureArgumentInOutToOutCloner::populateCloned() {
1356
1230
});
1357
1231
}
1358
1232
1233
+ // ///////////////////////////////////
1234
+ // Caller Lexical Lifetime Visitor //
1235
+ // ///////////////////////////////////
1236
+
1237
+ namespace {
1238
+
1239
+ // / Visit all of the uses of a lexical lifetime, initializing useState as we go.
1240
+ struct GatherLexicalLifetimeUseVisitor : public AccessUseVisitor {
1241
+ UseState &useState;
1242
+
1243
+ GatherLexicalLifetimeUseVisitor (UseState &useState)
1244
+ : AccessUseVisitor(AccessUseType::Overlapping,
1245
+ NestedAccessType::IgnoreAccessBegin),
1246
+ useState (useState) {}
1247
+
1248
+ bool visitUse (Operand *op, AccessUseType useTy) override ;
1249
+ void reset (SILValue address) { useState.address = address; }
1250
+ void clear () { useState.clear (); }
1251
+ };
1252
+
1253
+ } // end anonymous namespace
1254
+
1255
+ // Filter out recognized uses that do not write to memory.
1256
+ //
1257
+ // TODO: Ensure that all of the conditional-write logic below is encapsulated in
1258
+ // mayWriteToMemory and just call that instead. Possibly add additional
1259
+ // verification that visitAccessPathUses recognizes all instructions that may
1260
+ // propagate pointers (even though they don't write).
1261
+ bool GatherLexicalLifetimeUseVisitor::visitUse (Operand *op,
1262
+ AccessUseType useTy) {
1263
+ // If this operand is for a dependent type, then it does not actually access
1264
+ // the operand's address value. It only uses the metatype defined by the
1265
+ // operation (e.g. open_existential).
1266
+ if (op->isTypeDependent ()) {
1267
+ return true ;
1268
+ }
1269
+
1270
+ // If we have a move from src, this is a mark_move we want to visit.
1271
+ if (auto *move = dyn_cast<MarkUnresolvedMoveAddrInst>(op->getUser ())) {
1272
+ if (move->getSrc () == op->get ()) {
1273
+ LLVM_DEBUG (llvm::dbgs () << " Found move: " << *move);
1274
+ useState.insertMarkUnresolvedMoveAddr (move);
1275
+ return true ;
1276
+ }
1277
+ }
1278
+
1279
+ if (memInstMustInitialize (op)) {
1280
+ LLVM_DEBUG (llvm::dbgs () << " Found init: " << *op->getUser ());
1281
+ useState.inits .insert (op->getUser ());
1282
+ return true ;
1283
+ }
1284
+
1285
+ if (memInstMustReinitialize (op)) {
1286
+ LLVM_DEBUG (llvm::dbgs () << " Found reinit: " << *op->getUser ());
1287
+ useState.insertReinit (op->getUser ());
1288
+ return true ;
1289
+ }
1290
+
1291
+ if (auto *dvi = dyn_cast<DestroyAddrInst>(op->getUser ())) {
1292
+ // If we see a destroy_addr not on our base address, bail! Just error and
1293
+ // say that we do not understand the code.
1294
+ if (dvi->getOperand () != useState.address ) {
1295
+ LLVM_DEBUG (llvm::dbgs ()
1296
+ << " !!! Error! Found destroy_addr no on base address: "
1297
+ << *dvi);
1298
+ return false ;
1299
+ }
1300
+ LLVM_DEBUG (llvm::dbgs () << " Found destroy_addr: " << *dvi);
1301
+ useState.insertDestroy (dvi);
1302
+ return true ;
1303
+ }
1304
+
1305
+ // Then see if we have a inout_aliasable full apply site use. In that case, we
1306
+ // are going to try and extend move checking into the partial apply using
1307
+ // cloning to eliminate destroys or reinits.
1308
+ if (auto fas = FullApplySite::isa (op->getUser ())) {
1309
+ if (fas.getArgumentOperandConvention (*op) ==
1310
+ SILArgumentConvention::Indirect_InoutAliasable) {
1311
+ // If we don't find the function, we can't handle this, so bail.
1312
+ auto *func = fas.getCalleeFunction ();
1313
+ if (!func || !func->isDefer ())
1314
+ return false ;
1315
+ useState.insertClosureOperand (op);
1316
+ return true ;
1317
+ }
1318
+ }
1319
+
1320
+ // Ignore dealloc_stack.
1321
+ if (isa<DeallocStackInst>(op->getUser ()))
1322
+ return true ;
1323
+
1324
+ LLVM_DEBUG (llvm::dbgs () << " Found liveness use: " << *op->getUser ());
1325
+ useState.livenessUses .insert (op->getUser ());
1326
+
1327
+ return true ;
1328
+ }
1329
+
1359
1330
// ===----------------------------------------------------------------------===//
1360
1331
// Global Dataflow
1361
1332
// ===----------------------------------------------------------------------===//
0 commit comments