@@ -426,52 +426,8 @@ bool DIMemoryUse::onlyTouchesTrivialElements(
426
426
// DIElementUseInfo Implementation
427
427
// ===----------------------------------------------------------------------===//
428
428
429
- void DIElementUseInfo::trackFailableInitCall (
430
- const DIMemoryObjectInfo &MemoryInfo, SILInstruction *I) {
431
- // If we have a store to self inside the normal BB, we have a 'real'
432
- // try_apply. Otherwise, this is a 'try? self.init()' or similar,
433
- // and there is a store after.
434
- if (auto *TAI = dyn_cast<TryApplyInst>(I)) {
435
- trackFailureBlock (MemoryInfo, TAI, TAI->getNormalBB ());
436
- return ;
437
- }
438
-
439
- if (auto *AI = dyn_cast<ApplyInst>(I)) {
440
- // See if this is an optional initializer.
441
- for (auto Op : AI->getUses ()) {
442
- SILInstruction *User = Op->getUser ();
443
-
444
- if (!isa<SelectEnumInst>(User) && !isa<SelectEnumAddrInst>(User))
445
- continue ;
446
-
447
- auto value = cast<SingleValueInstruction>(User);
448
-
449
- if (!value->hasOneUse ())
450
- continue ;
451
-
452
- User = value->use_begin ()->getUser ();
453
- if (auto *CBI = dyn_cast<CondBranchInst>(User)) {
454
- trackFailureBlock (MemoryInfo, CBI, CBI->getTrueBB ());
455
- return ;
456
- }
457
- }
458
- }
459
- }
460
-
461
- // / We have to detect if the self box contents were consumed. Do this by
462
- // / checking for a store into the self box in the success branch. Once we rip
463
- // / this out of SILGen, DI will be able to figure this out in a more logical
464
- // / manner.
465
- void DIElementUseInfo::trackFailureBlock (const DIMemoryObjectInfo &TheMemory,
466
- TermInst *TI, SILBasicBlock *BB) {
467
- for (auto &II : *BB) {
468
- if (auto *SI = dyn_cast<StoreInst>(&II)) {
469
- if (SI->getDest () == TheMemory.MemoryInst ) {
470
- FailableInits.push_back (TI);
471
- return ;
472
- }
473
- }
474
- }
429
+ void DIElementUseInfo::trackStoreToSelf (SILInstruction *I) {
430
+ StoresToSelf.push_back (I);
475
431
}
476
432
477
433
// ===----------------------------------------------------------------------===//
@@ -1103,10 +1059,14 @@ void ElementUseCollector::collectClassSelfUses() {
1103
1059
return ;
1104
1060
}
1105
1061
1062
+ // The number of stores of the initial 'self' argument into the self box
1063
+ // that we saw.
1064
+ unsigned StoresOfArgumentToSelf = 0 ;
1065
+
1106
1066
// Okay, given that we have a proper setup, we walk the use chains of the self
1107
1067
// box to find any accesses to it. The possible uses are one of:
1108
1068
//
1109
- // 1) The initialization store (TheStore) .
1069
+ // 1) The initialization store.
1110
1070
// 2) Loads of the box, which have uses of self hanging off of them.
1111
1071
// 3) An assign to the box, which happens at super.init.
1112
1072
// 4) Potential escapes after super.init, if self is closed over.
@@ -1115,10 +1075,29 @@ void ElementUseCollector::collectClassSelfUses() {
1115
1075
for (auto *Op : MUI->getUses ()) {
1116
1076
SILInstruction *User = Op->getUser ();
1117
1077
1118
- // Stores to self are initializations store or the rebind of self as
1119
- // part of the super.init call. Ignore both of these.
1120
- if (isa<StoreInst>(User) && Op->getOperandNumber () == 1 )
1121
- continue ;
1078
+ // Stores to self.
1079
+ if (auto *SI = dyn_cast<StoreInst>(User)) {
1080
+ if (Op->getOperandNumber () == 1 ) {
1081
+ // The initial store of 'self' into the box at the start of the
1082
+ // function. Ignore it.
1083
+ if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc ())) {
1084
+ if (Arg->getParent () == MUI->getParent ()) {
1085
+ StoresOfArgumentToSelf++;
1086
+ continue ;
1087
+ }
1088
+ }
1089
+
1090
+ // A store of a load from the box is ignored.
1091
+ // FIXME: SILGen should not emit these.
1092
+ if (auto *LI = dyn_cast<LoadInst>(SI->getSrc ()))
1093
+ if (LI->getOperand () == MUI)
1094
+ continue ;
1095
+
1096
+ // Any other store needs to be recorded.
1097
+ UseInfo.trackStoreToSelf (SI);
1098
+ continue ;
1099
+ }
1100
+ }
1122
1101
1123
1102
// Ignore end_borrows. These can only come from us being the source of a
1124
1103
// load_borrow.
@@ -1149,6 +1128,9 @@ void ElementUseCollector::collectClassSelfUses() {
1149
1128
// and super.init must be called.
1150
1129
trackUse (DIMemoryUse (User, DIUseKind::Load, 0 , TheMemory.NumElements ));
1151
1130
}
1131
+
1132
+ assert (StoresOfArgumentToSelf == 1 &&
1133
+ " The 'self' argument should have been stored into the box exactly once" );
1152
1134
}
1153
1135
1154
1136
static bool isSuperInitUse (SILInstruction *User) {
@@ -1406,7 +1388,6 @@ void ElementUseCollector::collectClassSelfUses(
1406
1388
(isSelfInitUse (User) || isSuperInitUse (User))) {
1407
1389
if (isSelfOperand (Op, User)) {
1408
1390
Kind = DIUseKind::SelfInit;
1409
- UseInfo.trackFailableInitCall (TheMemory, User);
1410
1391
}
1411
1392
}
1412
1393
@@ -1459,6 +1440,10 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
1459
1440
assert (TheMemory.NumElements == 1 && " delegating inits only have 1 bit" );
1460
1441
auto *MUI = cast<MarkUninitializedInst>(TheMemory.MemoryInst );
1461
1442
1443
+ // The number of stores of the initial 'self' argument into the self box
1444
+ // that we saw.
1445
+ unsigned StoresOfArgumentToSelf = 0 ;
1446
+
1462
1447
// We walk the use chains of the self MUI to find any accesses to it. The
1463
1448
// possible uses are:
1464
1449
// 1) The initialization store.
@@ -1475,14 +1460,33 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
1475
1460
if (isa<EndBorrowInst>(User))
1476
1461
continue ;
1477
1462
1478
- // Stores to self are initializations store or the rebind of self as
1479
- // part of the super.init call. Ignore both of these.
1480
- if (isa<StoreInst>(User) && Op->getOperandNumber () == 1 )
1481
- continue ;
1463
+ // Stores to self.
1464
+ if (auto *SI = dyn_cast<StoreInst>(User)) {
1465
+ if (Op->getOperandNumber () == 1 ) {
1466
+ // The initial store of 'self' into the box at the start of the
1467
+ // function. Ignore it.
1468
+ if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc ())) {
1469
+ if (Arg->getParent () == MUI->getParent ()) {
1470
+ StoresOfArgumentToSelf++;
1471
+ continue ;
1472
+ }
1473
+ }
1474
+
1475
+ // A store of a load from the box is ignored.
1476
+ // FIXME: SILGen should not emit these.
1477
+ if (auto *LI = dyn_cast<LoadInst>(SI->getSrc ()))
1478
+ if (LI->getOperand () == MUI)
1479
+ continue ;
1480
+
1481
+ // Any other store needs to be recorded.
1482
+ UseInfo.trackStoreToSelf (SI);
1483
+ continue ;
1484
+ }
1485
+ }
1482
1486
1483
1487
// For class initializers, the assign into the self box may be
1484
1488
// captured as SelfInit or SuperInit elsewhere.
1485
- if (TheMemory. isClassInitSelf () && isa<AssignInst>(User) &&
1489
+ if (isa<AssignInst>(User) &&
1486
1490
Op->getOperandNumber () == 1 ) {
1487
1491
// If the source of the assignment is an application of a C
1488
1492
// function, there is no metatype argument, so treat the
@@ -1491,6 +1495,7 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
1491
1495
if (auto *Fn = AI->getCalleeFunction ()) {
1492
1496
if (Fn->getRepresentation () ==
1493
1497
SILFunctionTypeRepresentation::CFunctionPointer) {
1498
+ UseInfo.trackStoreToSelf (User);
1494
1499
UseInfo.trackUse (DIMemoryUse (User, DIUseKind::SelfInit, 0 , 1 ));
1495
1500
continue ;
1496
1501
}
@@ -1503,13 +1508,15 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
1503
1508
if (auto *AI = dyn_cast<AssignInst>(User)) {
1504
1509
if (auto *AssignSource = AI->getOperand (0 )->getDefiningInstruction ()) {
1505
1510
if (isSelfInitUse (AssignSource) || isSuperInitUse (AssignSource)) {
1511
+ UseInfo.trackStoreToSelf (User);
1506
1512
UseInfo.trackUse (DIMemoryUse (User, DIUseKind::SelfInit, 0 , 1 ));
1507
1513
continue ;
1508
1514
}
1509
1515
}
1510
1516
if (auto *AssignSource = dyn_cast<SILArgument>(AI->getOperand (0 ))) {
1511
1517
if (AssignSource->getParent () == AI->getParent () &&
1512
1518
(isSelfInitUse (AssignSource) || isSuperInitUse (AssignSource))) {
1519
+ UseInfo.trackStoreToSelf (User);
1513
1520
UseInfo.trackUse (DIMemoryUse (User, DIUseKind::SelfInit, 0 , 1 ));
1514
1521
continue ;
1515
1522
}
@@ -1534,6 +1541,9 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
1534
1541
UseInfo.trackUse (DIMemoryUse (User, DIUseKind::Escape, 0 , 1 ));
1535
1542
}
1536
1543
1544
+ assert (StoresOfArgumentToSelf == 1 &&
1545
+ " The 'self' argument should have been stored into the box exactly once" );
1546
+
1537
1547
// The MUI must be used on an alloc_box or alloc_stack instruction. If we have
1538
1548
// an alloc_stack, there is nothing further to do.
1539
1549
if (isa<AllocStackInst>(MUI->getOperand ()))
@@ -1573,13 +1583,17 @@ void DelegatingInitElementUseCollector::collectValueTypeInitSelfUses(
1573
1583
// Stores *to* the allocation are writes. If the value being stored is a
1574
1584
// call to self.init()... then we have a self.init call.
1575
1585
if (auto *AI = dyn_cast<AssignInst>(User)) {
1576
- if (AI->getDest () == I)
1586
+ if (AI->getDest () == I) {
1587
+ UseInfo.trackStoreToSelf (AI);
1577
1588
Kind = DIUseKind::InitOrAssign;
1589
+ }
1578
1590
}
1579
1591
1580
1592
if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
1581
- if (CAI->getDest () == I)
1593
+ if (CAI->getDest () == I) {
1594
+ UseInfo.trackStoreToSelf (CAI);
1582
1595
Kind = DIUseKind::InitOrAssign;
1596
+ }
1583
1597
}
1584
1598
1585
1599
// Look through begin_access
@@ -1665,7 +1679,6 @@ void DelegatingInitElementUseCollector::collectDelegatingClassInitSelfLoadUses(
1665
1679
(isSelfInitUse (User) || isSuperInitUse (User))) {
1666
1680
if (isSelfOperand (Op, User)) {
1667
1681
Kind = DIUseKind::SelfInit;
1668
- UseInfo.trackFailableInitCall (TheMemory, User);
1669
1682
}
1670
1683
}
1671
1684
@@ -1701,7 +1714,7 @@ void swift::ownership::collectDIElementUsesFrom(
1701
1714
// collector.
1702
1715
if (MemoryInfo.isDelegatingInit ()) {
1703
1716
DelegatingInitElementUseCollector UseCollector (MemoryInfo, UseInfo);
1704
- if (MemoryInfo.getType ()-> hasReferenceSemantics ()) {
1717
+ if (MemoryInfo.isClassInitSelf ()) {
1705
1718
UseCollector.collectClassInitSelfUses ();
1706
1719
} else {
1707
1720
UseCollector.collectValueTypeInitSelfUses ();
0 commit comments