Skip to content

Commit 18b1fbc

Browse files
committed
[sns] Refactor duplicate code into a helper. NFC.
The specific code path is the code used to emit errors if we assign or merge into a sending result. I just left the code in tree in the short term to prevent cherry-picking issues and since there wasn't a strong reason to do it at the time. Now that we have more freedom, lets clean up this code!
1 parent 31f344d commit 18b1fbc

File tree

1 file changed

+47
-51
lines changed

1 file changed

+47
-51
lines changed

include/swift/SILOptimizer/Utils/PartitionUtils.h

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,39 @@ struct PartitionOpEvaluator {
13431343
return asImpl().getRepresentativeValue(element);
13441344
}
13451345

1346+
/// See if we are assigning an a non-disconnected value into a 'out
1347+
/// sending' parameter. In such a case, we emit a diagnostic.
1348+
///
1349+
/// Helper used to handle assignment into sending results in the context of
1350+
/// assigns or merges.
1351+
void handleAssignNonDisconnectedIntoSendingResult(const PartitionOp &op) {
1352+
if (!doesParentFunctionHaveSendingResult(op))
1353+
return;
1354+
1355+
auto instance = getRepresentativeValue(op.getOpArg1());
1356+
if (!instance)
1357+
return;
1358+
1359+
auto *fArg =
1360+
dyn_cast_or_null<SILFunctionArgument>(instance.maybeGetValue());
1361+
if (!fArg || !fArg->getArgumentConvention().isIndirectOutParameter())
1362+
return;
1363+
1364+
auto staticRegionIsolation = getIsolationRegionInfo(op.getOpArg2());
1365+
Region srcRegion = p.getRegion(op.getOpArg2());
1366+
auto dynamicRegionIsolation = getIsolationRegionInfo(srcRegion);
1367+
1368+
// We can unconditionally getValue here since we can never
1369+
// assign an actor introducing inst.
1370+
auto rep = getRepresentativeValue(op.getOpArg2()).getValue();
1371+
if (dynamicRegionIsolation.isDisconnected() ||
1372+
staticRegionIsolation.isUnsafeNonIsolated())
1373+
return;
1374+
1375+
handleError(AssignNeverSendableIntoSendingResultError(
1376+
op, op.getOpArg1(), fArg, op.getOpArg2(), rep, dynamicRegionIsolation));
1377+
}
1378+
13461379
/// Apply \p op to the partition op.
13471380
void apply(const PartitionOp &op) {
13481381
if (shouldEmitVerboseLogging()) {
@@ -1370,33 +1403,14 @@ struct PartitionOpEvaluator {
13701403
assert(p.isTrackingElement(op.getOpArg2()) &&
13711404
"Assign PartitionOp's source argument should be already tracked");
13721405

1373-
// See if we are assigning an a non-disconnected value into a 'out
1374-
// sending' parameter. In such a case, we emit a diagnostic.
1375-
if (doesParentFunctionHaveSendingResult(op)) {
1376-
if (auto instance = getRepresentativeValue(op.getOpArg1())) {
1377-
if (auto value = instance.maybeGetValue()) {
1378-
if (auto *fArg = dyn_cast<SILFunctionArgument>(value)) {
1379-
if (fArg->getArgumentConvention().isIndirectOutParameter()) {
1380-
auto staticRegionIsolation =
1381-
getIsolationRegionInfo(op.getOpArg2());
1382-
Region srcRegion = p.getRegion(op.getOpArg2());
1383-
auto dynamicRegionIsolation = getIsolationRegionInfo(srcRegion);
1384-
1385-
// We can unconditionally getValue here since we can never
1386-
// assign an actor introducing inst.
1387-
auto rep = getRepresentativeValue(op.getOpArg2()).getValue();
1388-
if (!dynamicRegionIsolation.isDisconnected() &&
1389-
!staticRegionIsolation.isUnsafeNonIsolated()) {
1390-
handleError(AssignNeverSendableIntoSendingResultError(
1391-
op, op.getOpArg1(), fArg, op.getOpArg2(), rep,
1392-
dynamicRegionIsolation));
1393-
}
1394-
}
1395-
}
1396-
}
1397-
}
1398-
}
1406+
// First emit any errors if we are assigning a non-disconnected thing into
1407+
// a sending result.
1408+
handleAssignNonDisconnectedIntoSendingResult(op);
13991409

1410+
// Then perform the actual assignment.
1411+
//
1412+
// NOTE: This does not emit any errors on purpose. We rely on requires and
1413+
// other instructions to emit errors.
14001414
p.assignElement(op.getOpArg1(), op.getOpArg2());
14011415
return;
14021416
}
@@ -1491,32 +1505,14 @@ struct PartitionOpEvaluator {
14911505
p.isTrackingElement(op.getOpArg2()) &&
14921506
"Merge PartitionOp's arguments should already be tracked");
14931507

1494-
// See if we are assigning an a non-disconnected value into a 'out
1495-
// sending' parameter. In such a case, we emit a diagnostic.
1496-
if (doesParentFunctionHaveSendingResult(op)) {
1497-
if (auto instance = getRepresentativeValue(op.getOpArg1())) {
1498-
if (auto value = instance.maybeGetValue()) {
1499-
if (auto *fArg = dyn_cast<SILFunctionArgument>(value)) {
1500-
if (fArg->getArgumentConvention().isIndirectOutParameter()) {
1501-
auto staticRegionIsolation =
1502-
getIsolationRegionInfo(op.getOpArg2());
1503-
Region srcRegion = p.getRegion(op.getOpArg2());
1504-
auto dynamicRegionIsolation = getIsolationRegionInfo(srcRegion);
1505-
// We can unconditionally getValue here since we can never
1506-
// assign an actor introducing inst.
1507-
auto rep = getRepresentativeValue(op.getOpArg2()).getValue();
1508-
if (!dynamicRegionIsolation.isDisconnected() &&
1509-
!staticRegionIsolation.isUnsafeNonIsolated()) {
1510-
handleError(AssignNeverSendableIntoSendingResultError(
1511-
op, op.getOpArg1(), fArg, op.getOpArg2(), rep,
1512-
dynamicRegionIsolation));
1513-
}
1514-
}
1515-
}
1516-
}
1517-
}
1518-
}
1508+
// Emit an error if we are assigning a non-disconnected thing into a
1509+
// sending result.
1510+
handleAssignNonDisconnectedIntoSendingResult(op);
15191511

1512+
// Then perform the actual merge.
1513+
//
1514+
// NOTE: This does not emit any errors on purpose. We rely on requires and
1515+
// other instructions to emit errors.
15201516
p.merge(op.getOpArg1(), op.getOpArg2());
15211517
return;
15221518
}

0 commit comments

Comments
 (0)