@@ -347,9 +347,9 @@ void RequireLiveness::process(Collection requireInstList) {
347
347
348
348
// Then put all of our requires into our allRequires set.
349
349
BasicBlockWorklist initializingWorklist (transferInst->getFunction ());
350
- for (auto * require : requireInstList) {
351
- LLVM_DEBUG (llvm::dbgs () << " Require Inst: " << *require);
352
- allRequires.insert (require);
350
+ for (auto require : requireInstList) {
351
+ LLVM_DEBUG (llvm::dbgs () << " Require Inst: " << ** require);
352
+ allRequires.insert (* require);
353
353
initializingWorklist.pushIfNotVisited (require->getParent ());
354
354
}
355
355
@@ -454,9 +454,38 @@ struct TransferredNonTransferrableInfo {
454
454
isolationRegionInfo(isolationRegionInfo) {}
455
455
};
456
456
457
+ // / Wrapper around a SILInstruction that internally specifies whether we are
458
+ // / dealing with an inout reinitialization needed or if it is just a normal
459
+ // / use after transfer.
460
+ class RequireInst {
461
+ enum Kind {
462
+ UseAfterTransfer,
463
+ InOutReinitializationNeeded,
464
+ };
465
+
466
+ llvm::PointerIntPair<SILInstruction *, 1 > instAndKind;
467
+
468
+ RequireInst (SILInstruction *inst, Kind kind) : instAndKind(inst, kind) {}
469
+
470
+ public:
471
+ static RequireInst forUseAfterTransfer (SILInstruction *inst) {
472
+ return {inst, Kind::UseAfterTransfer};
473
+ }
474
+
475
+ static RequireInst forInOutReinitializationNeeded (SILInstruction *inst) {
476
+ return {inst, Kind::InOutReinitializationNeeded};
477
+ }
478
+
479
+ SILInstruction *getInst () const { return instAndKind.getPointer (); }
480
+ Kind getKind () const { return Kind (instAndKind.getInt ()); }
481
+
482
+ SILInstruction *operator *() const { return getInst (); }
483
+ SILInstruction *operator ->() const { return getInst (); }
484
+ };
485
+
457
486
class TransferNonSendableImpl {
458
487
RegionAnalysisFunctionInfo *regionInfo;
459
- SmallFrozenMultiMap<Operand *, SILInstruction * , 8 >
488
+ SmallFrozenMultiMap<Operand *, RequireInst , 8 >
460
489
transferOpToRequireInstMultiMap;
461
490
SmallVector<TransferredNonTransferrableInfo, 8 >
462
491
transferredNonTransferrableInfoList;
@@ -484,12 +513,12 @@ namespace {
484
513
485
514
class UseAfterTransferDiagnosticEmitter {
486
515
Operand *transferOp;
487
- SmallVectorImpl<SILInstruction * > &requireInsts;
516
+ SmallVectorImpl<RequireInst > &requireInsts;
488
517
bool emittedErrorDiagnostic = false ;
489
518
490
519
public:
491
- UseAfterTransferDiagnosticEmitter (
492
- Operand *transferOp, SmallVectorImpl<SILInstruction * > &requireInsts)
520
+ UseAfterTransferDiagnosticEmitter (Operand *transferOp,
521
+ SmallVectorImpl<RequireInst > &requireInsts)
493
522
: transferOp(transferOp), requireInsts(requireInsts) {}
494
523
495
524
~UseAfterTransferDiagnosticEmitter () {
@@ -715,8 +744,8 @@ class UseAfterTransferDiagnosticEmitter {
715
744
void emitRequireInstDiagnostics () {
716
745
// Now actually emit the require notes.
717
746
while (!requireInsts.empty ()) {
718
- auto * require = requireInsts.pop_back_val ();
719
- diagnoseNote (require, diag::regionbasedisolation_maybe_race)
747
+ auto require = requireInsts.pop_back_val ();
748
+ diagnoseNote (* require, diag::regionbasedisolation_maybe_race)
720
749
.highlight (require->getLoc ().getSourceRange ());
721
750
}
722
751
}
@@ -734,7 +763,7 @@ class UseAfterTransferDiagnosticInferrer {
734
763
735
764
public:
736
765
UseAfterTransferDiagnosticInferrer (
737
- Operand *transferOp, SmallVectorImpl<SILInstruction * > &requireInsts,
766
+ Operand *transferOp, SmallVectorImpl<RequireInst > &requireInsts,
738
767
RegionAnalysisValueMap &valueMap,
739
768
TransferringOperandToStateMap &transferringOpToStateMap)
740
769
: transferOp(transferOp), diagnosticEmitter(transferOp, requireInsts),
@@ -1037,17 +1066,17 @@ void TransferNonSendableImpl::emitUseAfterTransferDiagnostics() {
1037
1066
++blockLivenessInfoGeneration;
1038
1067
liveness.process (requireInsts);
1039
1068
1040
- SmallVector<SILInstruction * , 8 > requireInstsForError;
1041
- for (auto * require : requireInsts) {
1069
+ SmallVector<RequireInst , 8 > requireInstsForError;
1070
+ for (auto require : requireInsts) {
1042
1071
// We can have multiple of the same require insts if we had a require
1043
1072
// and an assign from the same instruction. Our liveness checking
1044
1073
// above doesn't care about that, but we still need to make sure we do
1045
1074
// not emit twice.
1046
- if (!requireInstsUnique.insert (require))
1075
+ if (!requireInstsUnique.insert (* require))
1047
1076
continue ;
1048
1077
1049
1078
// If this was not a last require, do not emit an error.
1050
- if (!liveness.finalRequires .contains (require))
1079
+ if (!liveness.finalRequires .contains (* require))
1051
1080
continue ;
1052
1081
1053
1082
requireInstsForError.push_back (require);
@@ -1485,7 +1514,7 @@ namespace {
1485
1514
struct DiagnosticEvaluator final
1486
1515
: PartitionOpEvaluatorBaseImpl<DiagnosticEvaluator> {
1487
1516
RegionAnalysisFunctionInfo *info;
1488
- SmallFrozenMultiMap<Operand *, SILInstruction * , 8 >
1517
+ SmallFrozenMultiMap<Operand *, RequireInst , 8 >
1489
1518
&transferOpToRequireInstMultiMap;
1490
1519
1491
1520
// / First value is the operand that was transferred... second value is the
@@ -1495,7 +1524,7 @@ struct DiagnosticEvaluator final
1495
1524
1496
1525
DiagnosticEvaluator (Partition &workingPartition,
1497
1526
RegionAnalysisFunctionInfo *info,
1498
- SmallFrozenMultiMap<Operand *, SILInstruction * , 8 >
1527
+ SmallFrozenMultiMap<Operand *, RequireInst , 8 >
1499
1528
&transferOpToRequireInstMultiMap,
1500
1529
SmallVectorImpl<TransferredNonTransferrableInfo>
1501
1530
&transferredNonTransferrable,
@@ -1534,8 +1563,9 @@ struct DiagnosticEvaluator final
1534
1563
<< " ID: %%" << transferredVal << " \n "
1535
1564
<< " Rep: " << *rep << " Transferring Op Num: "
1536
1565
<< transferringOp->getOperandNumber () << ' \n ' );
1537
- transferOpToRequireInstMultiMap.insert (transferringOp,
1538
- partitionOp.getSourceInst ());
1566
+ transferOpToRequireInstMultiMap.insert (
1567
+ transferringOp,
1568
+ RequireInst::forUseAfterTransfer (partitionOp.getSourceInst ()));
1539
1569
}
1540
1570
1541
1571
void handleTransferNonTransferrable (
0 commit comments