@@ -512,14 +512,21 @@ class TransferringOperand {
512
512
os << " \n User: " << *getUser ();
513
513
}
514
514
515
+ void merge (bool newIsClosureCaptured, SILIsolationInfo newIsolationRegionInfo,
516
+ IsolationHistory newIsolationHistory) {
517
+ value.setInt (value.getInt () | newIsClosureCaptured);
518
+ isolationInfo = isolationInfo.merge (newIsolationRegionInfo);
519
+ isolationHistory.pushCFGHistoryJoin (newIsolationHistory.getHead ());
520
+ }
521
+
515
522
static void Profile (llvm::FoldingSetNodeID &id, Operand *op,
516
523
bool isClosureCaptured,
517
524
SILIsolationInfo isolationRegionInfo,
518
525
IsolationHistory isolationHistory) {
519
526
id.AddPointer (op);
520
527
id.AddBoolean (isClosureCaptured);
521
528
isolationRegionInfo.Profile (id);
522
- id. AddPointer (isolationHistory. getHead ());
529
+ // We purposely do not track if isolation history changed.
523
530
}
524
531
525
532
void Profile (llvm::FoldingSetNodeID &id) const {
@@ -737,6 +744,17 @@ class Partition {
737
744
fst.canonicalize ();
738
745
snd.canonicalize ();
739
746
747
+ if (fst.regionToTransferredOpMap .size () !=
748
+ snd.regionToTransferredOpMap .size ())
749
+ return false ;
750
+ for (auto pair : fst.regionToTransferredOpMap ) {
751
+ auto iter = snd.regionToTransferredOpMap .find (pair.first );
752
+ if (iter == snd.regionToTransferredOpMap .end () ||
753
+ iter->second != pair.second ) {
754
+ return false ;
755
+ }
756
+ }
757
+
740
758
return fst.elementToRegionMap == snd.elementToRegionMap ;
741
759
}
742
760
@@ -1011,16 +1029,21 @@ struct PartitionOpEvaluator {
1011
1029
using Region = PartitionPrimitives::Region;
1012
1030
using TransferringOperandSetFactory =
1013
1031
Partition::TransferringOperandSetFactory;
1032
+ using OperandToTransferringOpMap =
1033
+ llvm::SmallDenseMap<Operand *, TransferringOperand *, 1 >;
1014
1034
1015
1035
protected:
1016
1036
TransferringOperandSetFactory &ptrSetFactory;
1037
+ OperandToTransferringOpMap &operandToTransferringOpMap;
1017
1038
1018
1039
Partition &p;
1019
1040
1020
1041
public:
1021
1042
PartitionOpEvaluator (Partition &p,
1022
- TransferringOperandSetFactory &ptrSetFactory)
1023
- : ptrSetFactory(ptrSetFactory), p(p) {}
1043
+ TransferringOperandSetFactory &ptrSetFactory,
1044
+ OperandToTransferringOpMap &operandToTransferringOpMap)
1045
+ : ptrSetFactory(ptrSetFactory),
1046
+ operandToTransferringOpMap (operandToTransferringOpMap), p(p) {}
1024
1047
1025
1048
// / Call shouldEmitVerboseLogging on our CRTP subclass.
1026
1049
bool shouldEmitVerboseLogging () const {
@@ -1194,9 +1217,21 @@ struct PartitionOpEvaluator {
1194
1217
}
1195
1218
1196
1219
// Mark op.getOpArgs()[0] as transferred.
1220
+ auto iter = operandToTransferringOpMap.find (op.getSourceOp ());
1221
+ if (iter != operandToTransferringOpMap.end ()) {
1222
+ iter->getSecond ()->merge (isClosureCapturedElt,
1223
+ transferredRegionIsolation,
1224
+ p.getIsolationHistory ());
1225
+ auto *ptrSet = ptrSetFactory.get (iter->second );
1226
+ p.markTransferred (op.getOpArgs ()[0 ], ptrSet);
1227
+ return ;
1228
+ }
1229
+
1197
1230
auto *ptrSet = ptrSetFactory.emplace (
1198
1231
op.getSourceOp (), isClosureCapturedElt, transferredRegionIsolation,
1199
1232
p.getIsolationHistory ());
1233
+ TransferringOperand *top = ptrSet->data ()[0 ];
1234
+ operandToTransferringOpMap.insert ({op.getSourceOp (), top});
1200
1235
p.markTransferred (op.getOpArgs ()[0 ], ptrSet);
1201
1236
return ;
1202
1237
}
@@ -1305,9 +1340,10 @@ struct PartitionOpEvaluatorBaseImpl : PartitionOpEvaluator<Subclass> {
1305
1340
Partition::TransferringOperandSetFactory;
1306
1341
using Super = PartitionOpEvaluator<Subclass>;
1307
1342
1308
- PartitionOpEvaluatorBaseImpl (Partition &workingPartition,
1309
- TransferringOperandSetFactory &ptrSetFactory)
1310
- : Super(workingPartition, ptrSetFactory) {}
1343
+ PartitionOpEvaluatorBaseImpl (
1344
+ Partition &workingPartition, TransferringOperandSetFactory &ptrSetFactory,
1345
+ typename Super::OperandToTransferringOpMap &operandToTransferringOpMap)
1346
+ : Super(workingPartition, ptrSetFactory, operandToTransferringOpMap) {}
1311
1347
1312
1348
// / Should we emit extra verbose logging statements when evaluating
1313
1349
// / PartitionOps.
@@ -1373,9 +1409,12 @@ struct PartitionOpEvaluatorBaseImpl : PartitionOpEvaluator<Subclass> {
1373
1409
// / behavior.
1374
1410
struct PartitionOpEvaluatorBasic final
1375
1411
: PartitionOpEvaluatorBaseImpl<PartitionOpEvaluatorBasic> {
1376
- PartitionOpEvaluatorBasic (Partition &workingPartition,
1377
- TransferringOperandSetFactory &ptrSetFactory)
1378
- : PartitionOpEvaluatorBaseImpl(workingPartition, ptrSetFactory) {}
1412
+ using Super = PartitionOpEvaluatorBaseImpl<PartitionOpEvaluatorBasic>;
1413
+ PartitionOpEvaluatorBasic (
1414
+ Partition &workingPartition, TransferringOperandSetFactory &ptrSetFactory,
1415
+ Super::OperandToTransferringOpMap &operandToTransferringOpMap)
1416
+ : PartitionOpEvaluatorBaseImpl(workingPartition, ptrSetFactory,
1417
+ operandToTransferringOpMap) {}
1379
1418
};
1380
1419
1381
1420
} // namespace swift
0 commit comments