Skip to content

Commit 382609e

Browse files
committed
[region-isolation] More consuming -> transferring.
1 parent c9e750b commit 382609e

File tree

2 files changed

+54
-50
lines changed

2 files changed

+54
-50
lines changed

include/swift/SILOptimizer/Utils/PartitionUtils.h

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ enum class PartitionOpKind : uint8_t {
8383
/// non-transferred regions.
8484
Merge,
8585

86-
/// Consume the region of a value if not already transferred, takes one arg.
86+
/// Transfer the region of a value if not already transferred, takes one arg.
8787
Transfer,
8888

8989
/// Require the region of a value to be non-transferred, takes one arg.
@@ -104,7 +104,7 @@ class PartitionOp {
104104
SILInstruction *sourceInst;
105105

106106
/// Record an AST expression corresponding to this PartitionOp, currently
107-
/// populated only for Consume expressions to indicate the value being
107+
/// populated only for Transfer expressions to indicate the value being
108108
/// transferred
109109
Expr *sourceExpr;
110110

@@ -381,17 +381,17 @@ class Partition {
381381
/// `handleFailure` closure can optionally be passed in that will be called if
382382
/// a transferred region is required. The closure is given the PartitionOp
383383
/// that failed, and the index of the SIL value that was required but
384-
/// transferred. Additionally, a list of "nonconsumable" indices can be passed
385-
/// in along with a handleConsumeNonConsumable closure. In the event that a
386-
/// region containing one of the nonconsumable indices is transferred, the
387-
/// closure will be called with the offending transfer.
384+
/// transferred. Additionally, a list of "nontransferrable" indices can be
385+
/// passed in along with a handleTransferNonTransferrable closure. In the
386+
/// event that a region containing one of the nontransferrable indices is
387+
/// transferred, the closure will be called with the offending transfer.
388388
void apply(
389389
PartitionOp op,
390390
llvm::function_ref<void(const PartitionOp &, Element)> handleFailure =
391391
[](const PartitionOp &, Element) {},
392-
ArrayRef<Element> nonconsumables = {},
392+
ArrayRef<Element> nontransferrables = {},
393393
llvm::function_ref<void(const PartitionOp &, Element)>
394-
handleConsumeNonConsumable = [](const PartitionOp &, Element) {},
394+
handleTransferNonTransferrable = [](const PartitionOp &, Element) {},
395395
llvm::function_ref<bool(Element)> isActorDerived = nullptr) {
396396

397397
REGIONBASEDISOLATION_VERBOSE_LOG(llvm::dbgs() << "Applying: ";
@@ -431,36 +431,37 @@ class Partition {
431431
break;
432432
case PartitionOpKind::Transfer: {
433433
assert(op.OpArgs.size() == 1 &&
434-
"Consume PartitionOp should be passed 1 argument");
434+
"Transfer PartitionOp should be passed 1 argument");
435435
assert(labels.count(op.OpArgs[0]) &&
436-
"Consume PartitionOp's argument should already be tracked");
436+
"Transfer PartitionOp's argument should already be tracked");
437437

438-
// check if any nonconsumables are transferred here, and handle the
438+
// check if any nontransferrables are transferred here, and handle the
439439
// failure if so
440-
for (Element nonconsumable : nonconsumables) {
441-
assert(labels.count(nonconsumable) &&
442-
"nonconsumables should be function args and self, and therefore"
443-
"always present in the label map because of initialization at "
444-
"entry");
445-
if (!isTransferred(nonconsumable) &&
446-
labels.at(nonconsumable) == labels.at(op.OpArgs[0])) {
447-
handleConsumeNonConsumable(op, nonconsumable);
440+
for (Element nonTransferrable : nontransferrables) {
441+
assert(
442+
labels.count(nonTransferrable) &&
443+
"nontransferrables should be function args and self, and therefore"
444+
"always present in the label map because of initialization at "
445+
"entry");
446+
if (!isTransferred(nonTransferrable) &&
447+
labels.at(nonTransferrable) == labels.at(op.OpArgs[0])) {
448+
handleTransferNonTransferrable(op, nonTransferrable);
448449
break;
449450
}
450451
}
451452

452453
// If this value is actor derived or if any elements in its region are
453-
// actor derived, we need to treat as non-consumable.
454+
// actor derived, we need to treat as nontransferrable.
454455
if (isActorDerived && isActorDerived(op.OpArgs[0]))
455-
return handleConsumeNonConsumable(op, op.OpArgs[0]);
456+
return handleTransferNonTransferrable(op, op.OpArgs[0]);
456457
Region elementRegion = labels.at(op.OpArgs[0]);
457458
if (llvm::any_of(labels,
458459
[&](const std::pair<Element, Region> &pair) -> bool {
459460
if (pair.second != elementRegion)
460461
return false;
461462
return isActorDerived && isActorDerived(pair.first);
462463
}))
463-
return handleConsumeNonConsumable(op, op.OpArgs[0]);
464+
return handleTransferNonTransferrable(op, op.OpArgs[0]);
464465

465466
// Ensure if the region is transferred...
466467
if (!isTransferred(op.OpArgs[0]))

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ class PartitionOpTranslator {
482482
for (SILArgument *arg : functionArguments) {
483483
if (auto state = tryToTrackValue(arg)) {
484484
// If we have an arg that is an actor, we allow for it to be
485-
// consumed... value ids derived from it though cannot be consumed.
485+
// transfer... value ids derived from it though cannot be transferred.
486486
LLVM_DEBUG(llvm::dbgs() << " %%" << state->getID());
487487
neverTransferredValueIDs.push_back(state->getID());
488488
nonSendableIndices.push_back(state->getID());
@@ -1071,7 +1071,7 @@ class PartitionOpTranslator {
10711071

10721072
// We ignore begin_access since we look through them. We look through them
10731073
// since we want to treat the use of the begin_access as the semantic giving
1074-
// instruction. Otherwise, if we have a store after a consume we will emit
1074+
// instruction. Otherwise, if we have a store after a transfer we will emit
10751075
// an error on the begin_access rather than allowing for the store to
10761076
// overwrite the original value. This would then cause an error.
10771077
//
@@ -1343,7 +1343,7 @@ struct LocalTransferredReason {
13431343
/// causes a target access to be invalid because of merging/joining that spans
13441344
/// many different blocks worth of control flow, it is less likely to be
13451345
/// informative, so distance is used as a heuristic to choose which access sites
1346-
/// to display in diagnostics given a racy consumption.
1346+
/// to display in diagnostics given a racy transfer.
13471347
class TransferredReason {
13481348
std::multimap<unsigned, PartitionOp> transferOps;
13491349

@@ -1437,7 +1437,7 @@ class TransferRequireAccumulator {
14371437
unsigned numDisplayed = numProcessed;
14381438
unsigned numHidden = requireOps.size() - numProcessed;
14391439
if (!tryDiagnoseAsCallSite(transferOp, numDisplayed, numHidden)) {
1440-
assert(false && "no consumptions besides callsites implemented yet");
1440+
assert(false && "no transfers besides callsites implemented yet");
14411441

14421442
// Default to a more generic diagnostic if we can't find the callsite.
14431443
auto expr = getExprForPartitionOp(transferOp);
@@ -1486,16 +1486,17 @@ class TransferRequireAccumulator {
14861486
SILInstruction *sourceInst =
14871487
transferOp.getSourceInst(/*assertNonNull=*/true);
14881488
ApplyExpr *apply = sourceInst->getLoc().getAsASTNode<ApplyExpr>();
1489+
1490+
// If the transfer does not correspond to an apply expression... bail.
14891491
if (!apply)
1490-
// consumption does not correspond to an apply expression
14911492
return false;
1493+
14921494
auto isolationCrossing = apply->getIsolationCrossing();
14931495
assert(isolationCrossing && "ApplyExprs should be transferring only if "
14941496
"they are isolation crossing");
14951497

14961498
auto argExpr = transferOp.getSourceExpr();
1497-
assert(argExpr &&
1498-
"sourceExpr should be populated for ApplyExpr consumptions");
1499+
assert(argExpr && "sourceExpr should be populated for ApplyExpr transfers");
14991500

15001501
sourceInst->getFunction()
15011502
->getASTContext()
@@ -1648,22 +1649,22 @@ class RaceTracer {
16481649
findLocalTransferredReason(SILBasicBlock *SILBlock,
16491650
TrackableValueID transferredVal,
16501651
std::optional<PartitionOp> targetOp = {}) {
1651-
// if this is a query for consumption reason at block exit, check the cache
1652+
// If this is a query for transfer reason at block exit, check the cache.
16521653
if (!targetOp && transferredAtExitReasons.count({SILBlock, transferredVal}))
16531654
return transferredAtExitReasons.at({SILBlock, transferredVal});
16541655

16551656
const BlockPartitionState &block = blockStates[SILBlock];
16561657

1657-
// if targetOp is null, we're checking why the value is transferred at exit,
1658+
// If targetOp is null, we're checking why the value is transferred at exit,
16581659
// so assert that it's actually transferred at exit
16591660
assert(targetOp || block.getExitPartition().isTransferred(transferredVal));
16601661

16611662
std::optional<LocalTransferredReason> transferredReason;
16621663

16631664
Partition workingPartition = block.getEntryPartition();
16641665

1665-
// we're looking for a local reason, so if the value is transferred at
1666-
// entry, revive it for the sake of this search
1666+
// We are looking for a local reason, so if the value is transferred at
1667+
// entry, revive it for the sake of this search.
16671668
if (workingPartition.isTransferred(transferredVal))
16681669
workingPartition.apply(PartitionOp::AssignFresh(transferredVal));
16691670

@@ -1674,35 +1675,35 @@ class RaceTracer {
16741675
workingPartition.apply(partitionOp);
16751676
if (workingPartition.isTransferred(transferredVal) &&
16761677
!transferredReason) {
1677-
// this partitionOp transfers the target value
1678+
// This partitionOp transfers the target value.
16781679
if (partitionOp.getKind() == PartitionOpKind::Transfer)
16791680
transferredReason = LocalTransferredReason::TransferInst(partitionOp);
16801681
else
1681-
// a merge or assignment invalidated this, but that will be a separate
1682-
// failure to diagnose, so we don't worry about it here
1682+
// A merge or assignment invalidated this, but that will be a separate
1683+
// failure to diagnose, so we don't worry about it here.
16831684
transferredReason = LocalTransferredReason::NonTransferInst();
16841685
}
16851686
if (!workingPartition.isTransferred(transferredVal) && transferredReason)
1686-
// value is no longer transferred - e.g. reassigned or assigned fresh
1687+
// Value is no longer transferred - e.g. reassigned or assigned fresh.
16871688
transferredReason = llvm::None;
16881689

16891690
// continue walking block
16901691
i++;
16911692
return true;
16921693
});
16931694

1694-
// if we failed to find a local transfer reason, but the value was
1695-
// transferred at entry to the block, then the reason is "NonLocal"
1695+
// If we failed to find a local transfer reason, but the value was
1696+
// transferred at entry to the block, then the reason is "NonLocal".
16961697
if (!transferredReason &&
16971698
block.getEntryPartition().isTransferred(transferredVal))
16981699
transferredReason = LocalTransferredReason::NonLocal();
16991700

1700-
// if transferredReason is none, then transferredVal was not actually
1701-
// transferred
1701+
// If transferredReason is none, then transferredVal was not actually
1702+
// transferred.
17021703
assert(transferredReason || dumpBlockSearch(SILBlock, transferredVal) &&
1703-
" no consumption was found");
1704+
" no transfer was found");
17041705

1705-
// if this is a query for consumption reason at block exit, update the cache
1706+
// If this is a query for a transfer reason at block exit, update the cache.
17061707
if (!targetOp)
17071708
return transferredAtExitReasons[std::pair{SILBlock, transferredVal}] =
17081709
transferredReason.value();
@@ -1908,7 +1909,7 @@ class PartitionAnalysis {
19081909
[&](const PartitionOp &partitionOp, TrackableValueID transferredVal) {
19091910
auto expr = getExprForPartitionOp(partitionOp);
19101911

1911-
// ensure that multiple consumptions at the same AST node are only
1912+
// ensure that multiple transfers at the same AST node are only
19121913
// entered once into the race tracer
19131914
if (hasBeenEmitted(expr))
19141915
return;
@@ -1923,10 +1924,10 @@ class PartitionAnalysis {
19231924
raceTracer.traceUseOfTransferredValue(partitionOp, transferredVal);
19241925
},
19251926

1926-
/*handleTransferNonConsumable=*/
1927+
/*handleTransferNonTransferrable=*/
19271928
[&](const PartitionOp &partitionOp, TrackableValueID transferredVal) {
19281929
LLVM_DEBUG(llvm::dbgs()
1929-
<< "Emitting ConsumeNonConsume Error!\n"
1930+
<< "Emitting TransferNonTransferrable Error!\n"
19301931
<< "ID: %%" << transferredVal << "\n"
19311932
<< "Rep: "
19321933
<< *translator.getValueForId(transferredVal)
@@ -1940,7 +1941,7 @@ class PartitionAnalysis {
19401941
LLVM_DEBUG(llvm::dbgs() << "Accumulator Complete:\n";
19411942
raceTracer.getAccumulator().print(llvm::dbgs()););
19421943

1943-
// Ask the raceTracer to report diagnostics at the consumption sites for all
1944+
// Ask the raceTracer to report diagnostics at the transfer sites for all
19441945
// the racy requirement sites entered into it above.
19451946
raceTracer.getAccumulator().emitErrorsForTransferRequire(
19461947
NUM_REQUIREMENTS_TO_DIAGNOSE);
@@ -1951,9 +1952,12 @@ class PartitionAnalysis {
19511952
SILInstruction *sourceInst =
19521953
transferOp.getSourceInst(/*assertNonNull=*/true);
19531954
ApplyExpr *apply = sourceInst->getLoc().getAsASTNode<ApplyExpr>();
1955+
1956+
// If the transfer does not correspond to an apply expression... return
1957+
// early.
19541958
if (!apply)
1955-
// consumption does not correspond to an apply expression
19561959
return false;
1960+
19571961
auto isolationCrossing = apply->getIsolationCrossing();
19581962
if (!isolationCrossing) {
19591963
assert(false && "ApplyExprs should be transferring only if"
@@ -1962,8 +1966,7 @@ class PartitionAnalysis {
19621966
}
19631967
auto argExpr = transferOp.getSourceExpr();
19641968
if (!argExpr)
1965-
assert(false &&
1966-
"sourceExpr should be populated for ApplyExpr consumptions");
1969+
assert(false && "sourceExpr should be populated for ApplyExpr transfers");
19671970

19681971
function->getASTContext()
19691972
.Diags

0 commit comments

Comments
 (0)