@@ -1262,6 +1262,32 @@ struct PartitionOpEvaluator {
12621262 return asImpl ().getIsolationRegionInfo (elt);
12631263 }
12641264
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+
12651291 bool isTaskIsolatedDerived (Element elt) const {
12661292 return asImpl ().isTaskIsolatedDerived (elt);
12671293 }
@@ -1320,35 +1346,23 @@ struct PartitionOpEvaluator {
13201346 assert (p.isTrackingElement (op.getOpArgs ()[0 ]) &&
13211347 " Transfer PartitionOp's argument should already be tracked" );
13221348
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-
13331349 // Otherwise, we need to merge our isolation region info with the
13341350 // isolation region info of everything else in our region. This is the
13351351 // 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 ()) {
13501364 return handleTransferNonTransferrable (op, op.getOpArgs ()[0 ],
1351- isolationRegionInfo );
1365+ transferredRegionIsolation );
13521366 }
13531367
13541368 // Mark op.getOpArgs()[0] as transferred.
0 commit comments