@@ -1262,6 +1262,32 @@ struct PartitionOpEvaluator {
1262
1262
return asImpl ().getIsolationRegionInfo (elt);
1263
1263
}
1264
1264
1265
+ // / Compute the isolation region info for all elements in \p region.
1266
+ // /
1267
+ // / The bool result is if it is captured by a closure element. That only is
1268
+ // / computed if \p sourceOp is non-null.
1269
+ std::pair<IsolationRegionInfo, bool >
1270
+ getIsolationRegionInfo (Region region, Operand *sourceOp) const {
1271
+ bool isClosureCapturedElt = false ;
1272
+ IsolationRegionInfo isolationRegionInfo;
1273
+
1274
+ for (const auto &pair : p.range ()) {
1275
+ if (pair.second == region) {
1276
+ isolationRegionInfo =
1277
+ isolationRegionInfo.merge (getIsolationRegionInfo (pair.first ));
1278
+ if (sourceOp)
1279
+ isClosureCapturedElt |= isClosureCaptured (pair.first , sourceOp);
1280
+ }
1281
+ }
1282
+
1283
+ return {isolationRegionInfo, isClosureCapturedElt};
1284
+ }
1285
+
1286
+ // / Overload of \p getIsolationRegionInfo without an Operand.
1287
+ IsolationRegionInfo getIsolationRegionInfo (Region region) const {
1288
+ return getIsolationRegionInfo (region, nullptr ).first ;
1289
+ }
1290
+
1265
1291
bool isTaskIsolatedDerived (Element elt) const {
1266
1292
return asImpl ().isTaskIsolatedDerived (elt);
1267
1293
}
@@ -1320,35 +1346,23 @@ struct PartitionOpEvaluator {
1320
1346
assert (p.isTrackingElement (op.getOpArgs ()[0 ]) &&
1321
1347
" Transfer PartitionOp's argument should already be tracked" );
1322
1348
1323
- IsolationRegionInfo isolationRegionInfo =
1324
- getIsolationRegionInfo (op.getOpArgs ()[0 ]);
1325
-
1326
- // If we know our direct value is actor derived... immediately emit an
1327
- // error.
1328
- if (isolationRegionInfo.hasActorIsolation ()) {
1329
- return handleTransferNonTransferrable (op, op.getOpArgs ()[0 ],
1330
- isolationRegionInfo);
1331
- }
1332
-
1333
1349
// Otherwise, we need to merge our isolation region info with the
1334
1350
// isolation region info of everything else in our region. This is the
1335
1351
// dynamic isolation region info found by the dataflow.
1336
- bool isClosureCapturedElt =
1337
- isClosureCaptured (op.getOpArgs ()[0 ], op.getSourceOp ());
1338
- Region elementRegion = p.getRegion (op.getOpArgs ()[0 ]);
1339
- for (const auto &pair : p.range ()) {
1340
- if (pair.second == elementRegion) {
1341
- isolationRegionInfo =
1342
- isolationRegionInfo.merge (getIsolationRegionInfo (pair.first ));
1343
- isClosureCapturedElt |=
1344
- isClosureCaptured (pair.first , op.getSourceOp ());
1345
- }
1346
- }
1347
-
1348
- // If we merged anything, we need to handle a transfer non-transferrable.
1349
- if (bool (isolationRegionInfo) && !isolationRegionInfo.isDisconnected ()) {
1352
+ Element transferredElement = op.getOpArgs ()[0 ];
1353
+ Region transferredRegion = p.getRegion (transferredElement);
1354
+ bool isClosureCapturedElt = false ;
1355
+ IsolationRegionInfo transferredRegionIsolation;
1356
+ std::tie (transferredRegionIsolation, isClosureCapturedElt) =
1357
+ getIsolationRegionInfo (transferredRegion, op.getSourceOp ());
1358
+
1359
+ // If we merged anything, we need to handle a transfer
1360
+ // non-transferrable. We pass in the dynamic isolation region info of our
1361
+ // region.
1362
+ if (bool (transferredRegionIsolation) &&
1363
+ !transferredRegionIsolation.isDisconnected ()) {
1350
1364
return handleTransferNonTransferrable (op, op.getOpArgs ()[0 ],
1351
- isolationRegionInfo );
1365
+ transferredRegionIsolation );
1352
1366
}
1353
1367
1354
1368
// Mark op.getOpArgs()[0] as transferred.
0 commit comments