@@ -348,9 +348,9 @@ void RequireLiveness::process(Collection requireInstList) {
348
348
349
349
// Then put all of our requires into our allRequires set.
350
350
BasicBlockWorklist initializingWorklist (transferInst->getFunction ());
351
- for (auto * require : requireInstList) {
352
- LLVM_DEBUG (llvm::dbgs () << " Require Inst: " << *require);
353
- allRequires.insert (require);
351
+ for (auto require : requireInstList) {
352
+ LLVM_DEBUG (llvm::dbgs () << " Require Inst: " << ** require);
353
+ allRequires.insert (* require);
354
354
initializingWorklist.pushIfNotVisited (require->getParent ());
355
355
}
356
356
@@ -455,9 +455,38 @@ struct TransferredNonTransferrableInfo {
455
455
isolationRegionInfo(isolationRegionInfo) {}
456
456
};
457
457
458
+ // / Wrapper around a SILInstruction that internally specifies whether we are
459
+ // / dealing with an inout reinitialization needed or if it is just a normal
460
+ // / use after transfer.
461
+ class RequireInst {
462
+ enum Kind {
463
+ UseAfterTransfer,
464
+ InOutReinitializationNeeded,
465
+ };
466
+
467
+ llvm::PointerIntPair<SILInstruction *, 1 > instAndKind;
468
+
469
+ RequireInst (SILInstruction *inst, Kind kind) : instAndKind(inst, kind) {}
470
+
471
+ public:
472
+ static RequireInst forUseAfterTransfer (SILInstruction *inst) {
473
+ return {inst, Kind::UseAfterTransfer};
474
+ }
475
+
476
+ static RequireInst forInOutReinitializationNeeded (SILInstruction *inst) {
477
+ return {inst, Kind::InOutReinitializationNeeded};
478
+ }
479
+
480
+ SILInstruction *getInst () const { return instAndKind.getPointer (); }
481
+ Kind getKind () const { return Kind (instAndKind.getInt ()); }
482
+
483
+ SILInstruction *operator *() const { return getInst (); }
484
+ SILInstruction *operator ->() const { return getInst (); }
485
+ };
486
+
458
487
class TransferNonSendableImpl {
459
488
RegionAnalysisFunctionInfo *regionInfo;
460
- SmallFrozenMultiMap<Operand *, SILInstruction * , 8 >
489
+ SmallFrozenMultiMap<Operand *, RequireInst , 8 >
461
490
transferOpToRequireInstMultiMap;
462
491
SmallVector<TransferredNonTransferrableInfo, 8 >
463
492
transferredNonTransferrableInfoList;
@@ -485,12 +514,12 @@ namespace {
485
514
486
515
class UseAfterTransferDiagnosticEmitter {
487
516
Operand *transferOp;
488
- SmallVectorImpl<SILInstruction * > &requireInsts;
517
+ SmallVectorImpl<RequireInst > &requireInsts;
489
518
bool emittedErrorDiagnostic = false ;
490
519
491
520
public:
492
- UseAfterTransferDiagnosticEmitter (
493
- Operand *transferOp, SmallVectorImpl<SILInstruction * > &requireInsts)
521
+ UseAfterTransferDiagnosticEmitter (Operand *transferOp,
522
+ SmallVectorImpl<RequireInst > &requireInsts)
494
523
: transferOp(transferOp), requireInsts(requireInsts) {}
495
524
496
525
~UseAfterTransferDiagnosticEmitter () {
@@ -734,8 +763,8 @@ class UseAfterTransferDiagnosticEmitter {
734
763
void emitRequireInstDiagnostics () {
735
764
// Now actually emit the require notes.
736
765
while (!requireInsts.empty ()) {
737
- auto * require = requireInsts.pop_back_val ();
738
- diagnoseNote (require, diag::regionbasedisolation_maybe_race)
766
+ auto require = requireInsts.pop_back_val ();
767
+ diagnoseNote (* require, diag::regionbasedisolation_maybe_race)
739
768
.highlight (require->getLoc ().getSourceRange ());
740
769
}
741
770
}
@@ -753,7 +782,7 @@ class UseAfterTransferDiagnosticInferrer {
753
782
754
783
public:
755
784
UseAfterTransferDiagnosticInferrer (
756
- Operand *transferOp, SmallVectorImpl<SILInstruction * > &requireInsts,
785
+ Operand *transferOp, SmallVectorImpl<RequireInst > &requireInsts,
757
786
RegionAnalysisValueMap &valueMap,
758
787
TransferringOperandToStateMap &transferringOpToStateMap)
759
788
: transferOp(transferOp), diagnosticEmitter(transferOp, requireInsts),
@@ -1074,17 +1103,17 @@ void TransferNonSendableImpl::emitUseAfterTransferDiagnostics() {
1074
1103
++blockLivenessInfoGeneration;
1075
1104
liveness.process (requireInsts);
1076
1105
1077
- SmallVector<SILInstruction * , 8 > requireInstsForError;
1078
- for (auto * require : requireInsts) {
1106
+ SmallVector<RequireInst , 8 > requireInstsForError;
1107
+ for (auto require : requireInsts) {
1079
1108
// We can have multiple of the same require insts if we had a require
1080
1109
// and an assign from the same instruction. Our liveness checking
1081
1110
// above doesn't care about that, but we still need to make sure we do
1082
1111
// not emit twice.
1083
- if (!requireInstsUnique.insert (require))
1112
+ if (!requireInstsUnique.insert (* require))
1084
1113
continue ;
1085
1114
1086
1115
// If this was not a last require, do not emit an error.
1087
- if (!liveness.finalRequires .contains (require))
1116
+ if (!liveness.finalRequires .contains (* require))
1088
1117
continue ;
1089
1118
1090
1119
requireInstsForError.push_back (require);
@@ -1532,7 +1561,7 @@ namespace {
1532
1561
struct DiagnosticEvaluator final
1533
1562
: PartitionOpEvaluatorBaseImpl<DiagnosticEvaluator> {
1534
1563
RegionAnalysisFunctionInfo *info;
1535
- SmallFrozenMultiMap<Operand *, SILInstruction * , 8 >
1564
+ SmallFrozenMultiMap<Operand *, RequireInst , 8 >
1536
1565
&transferOpToRequireInstMultiMap;
1537
1566
1538
1567
// / First value is the operand that was transferred... second value is the
@@ -1542,7 +1571,7 @@ struct DiagnosticEvaluator final
1542
1571
1543
1572
DiagnosticEvaluator (Partition &workingPartition,
1544
1573
RegionAnalysisFunctionInfo *info,
1545
- SmallFrozenMultiMap<Operand *, SILInstruction * , 8 >
1574
+ SmallFrozenMultiMap<Operand *, RequireInst , 8 >
1546
1575
&transferOpToRequireInstMultiMap,
1547
1576
SmallVectorImpl<TransferredNonTransferrableInfo>
1548
1577
&transferredNonTransferrable,
@@ -1581,8 +1610,9 @@ struct DiagnosticEvaluator final
1581
1610
<< " ID: %%" << transferredVal << " \n "
1582
1611
<< " Rep: " << *rep << " Transferring Op Num: "
1583
1612
<< transferringOp->getOperandNumber () << ' \n ' );
1584
- transferOpToRequireInstMultiMap.insert (transferringOp,
1585
- partitionOp.getSourceInst ());
1613
+ transferOpToRequireInstMultiMap.insert (
1614
+ transferringOp,
1615
+ RequireInst::forUseAfterTransfer (partitionOp.getSourceInst ()));
1586
1616
}
1587
1617
1588
1618
void handleTransferNonTransferrable (
0 commit comments