Skip to content

Commit df24fc4

Browse files
committed
[region-isolation] Convert AssignIsolatedIntoSendingResult to be emitted as a verbatim error.
1 parent 4265aa1 commit df24fc4

File tree

1 file changed

+64
-102
lines changed

1 file changed

+64
-102
lines changed

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 64 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -494,33 +494,6 @@ void RequireLiveness::process(Collection requireInstList) {
494494

495495
namespace {
496496

497-
struct AssignIsolatedIntoOutSendingParameterInfo {
498-
/// The user that actually caused the transfer.
499-
Operand *srcOperand;
500-
501-
/// The specific out sending result.
502-
SILFunctionArgument *outSendingResult;
503-
504-
/// The non-transferrable value that is in the same region as \p
505-
/// outSendingResult.
506-
SILValue nonTransferrableValue;
507-
508-
/// The region info that describes the dynamic dataflow derived isolation
509-
/// region info for the non-transferrable value.
510-
///
511-
/// This is equal to the merge of the IsolationRegionInfo from all elements in
512-
/// nonTransferrable's region when the error was diagnosed.
513-
SILDynamicMergedIsolationInfo isolatedValueIsolationRegionInfo;
514-
515-
AssignIsolatedIntoOutSendingParameterInfo(
516-
Operand *transferringOperand, SILFunctionArgument *outSendingResult,
517-
SILValue nonTransferrableValue,
518-
SILDynamicMergedIsolationInfo isolationRegionInfo)
519-
: srcOperand(transferringOperand), outSendingResult(outSendingResult),
520-
nonTransferrableValue(nonTransferrableValue),
521-
isolatedValueIsolationRegionInfo(isolationRegionInfo) {}
522-
};
523-
524497
/// Wrapper around a SILInstruction that internally specifies whether we are
525498
/// dealing with an inout reinitialization needed or if it is just a normal
526499
/// use after transfer.
@@ -557,8 +530,6 @@ class TransferNonSendableImpl {
557530
SmallFrozenMultiMap<Operand *, RequireInst, 8>
558531
transferOpToRequireInstMultiMap;
559532
SmallVector<PartitionOpError, 8> foundVerbatimErrors;
560-
SmallVector<AssignIsolatedIntoOutSendingParameterInfo, 8>
561-
assignIsolatedIntoOutSendingParameterInfoList;
562533

563534
public:
564535
TransferNonSendableImpl(RegionAnalysisFunctionInfo *info) : info(info) {}
@@ -569,7 +540,6 @@ class TransferNonSendableImpl {
569540
void runDiagnosticEvaluator();
570541

571542
void emitUseAfterTransferDiagnostics();
572-
void emitAssignIsolatedIntoSendingResultDiagnostics();
573543
void emitVerbatimErrors();
574544
};
575545

@@ -2126,13 +2096,33 @@ void InOutSendingNotDisconnectedDiagnosticEmitter::emit() {
21262096
namespace {
21272097

21282098
class AssignIsolatedIntoSendingResultDiagnosticEmitter {
2129-
AssignIsolatedIntoOutSendingParameterInfo info;
2099+
/// The user that actually caused the transfer.
2100+
Operand *srcOperand;
2101+
2102+
/// The specific out sending result.
2103+
SILFunctionArgument *outSendingResult;
2104+
2105+
/// The non-transferrable value that is in the same region as \p
2106+
/// outSendingResult.
2107+
SILValue nonTransferrableValue;
2108+
2109+
/// The region info that describes the dynamic dataflow derived isolation
2110+
/// region info for the non-transferrable value.
2111+
///
2112+
/// This is equal to the merge of the IsolationRegionInfo from all elements in
2113+
/// nonTransferrable's region when the error was diagnosed.
2114+
SILDynamicMergedIsolationInfo isolatedValueIsolationRegionInfo;
2115+
21302116
bool emittedErrorDiagnostic = false;
21312117

21322118
public:
21332119
AssignIsolatedIntoSendingResultDiagnosticEmitter(
2134-
AssignIsolatedIntoOutSendingParameterInfo info)
2135-
: info(info) {}
2120+
Operand *srcOperand, SILFunctionArgument *outSendingResult,
2121+
SILValue nonTransferrableValue,
2122+
SILDynamicMergedIsolationInfo isolatedValueIsolationRegionInfo)
2123+
: srcOperand(srcOperand), outSendingResult(outSendingResult),
2124+
nonTransferrableValue(nonTransferrableValue),
2125+
isolatedValueIsolationRegionInfo(isolatedValueIsolationRegionInfo) {}
21362126

21372127
~AssignIsolatedIntoSendingResultDiagnosticEmitter() {
21382128
// If we were supposed to emit a diagnostic and didn't emit an unknown
@@ -2141,10 +2131,10 @@ class AssignIsolatedIntoSendingResultDiagnosticEmitter {
21412131
emitUnknownPatternError();
21422132
}
21432133

2144-
SILFunction *getFunction() const { return info.srcOperand->getFunction(); }
2134+
SILFunction *getFunction() const { return srcOperand->getFunction(); }
21452135

21462136
std::optional<DiagnosticBehavior> getConcurrencyDiagnosticBehavior() const {
2147-
return info.outSendingResult->getType().getConcurrencyDiagnosticBehavior(
2137+
return outSendingResult->getType().getConcurrencyDiagnosticBehavior(
21482138
getFunction());
21492139
}
21502140

@@ -2154,15 +2144,15 @@ class AssignIsolatedIntoSendingResultDiagnosticEmitter {
21542144
"RegionIsolation: Aborting on unknown pattern match error");
21552145
}
21562146

2157-
diagnoseError(info.srcOperand->getUser(),
2147+
diagnoseError(srcOperand->getUser(),
21582148
diag::regionbasedisolation_unknown_pattern)
21592149
.limitBehaviorIf(getConcurrencyDiagnosticBehavior());
21602150
}
21612151

21622152
void emit();
21632153

21642154
ASTContext &getASTContext() const {
2165-
return info.srcOperand->getFunction()->getASTContext();
2155+
return srcOperand->getFunction()->getASTContext();
21662156
}
21672157

21682158
template <typename... T, typename... U>
@@ -2243,32 +2233,31 @@ void AssignIsolatedIntoSendingResultDiagnosticEmitter::emit() {
22432233
SmallString<64> descriptiveKindStr;
22442234
{
22452235
llvm::raw_svector_ostream os(descriptiveKindStr);
2246-
info.isolatedValueIsolationRegionInfo.printForDiagnostics(os);
2236+
isolatedValueIsolationRegionInfo.printForDiagnostics(os);
22472237
}
22482238

22492239
// Grab the var name if we can find it.
2250-
if (auto varName = VariableNameInferrer::inferName(info.srcOperand->get())) {
2240+
if (auto varName = VariableNameInferrer::inferName(srcOperand->get())) {
22512241
// In general, when we do an assignment like this, we assume that srcOperand
22522242
// and our outSendingResult have the same type. This doesn't always happen
22532243
// though especially if our outSendingResult is used as an out parameter of
22542244
// a class_method. Check for such a case and if so, add to the end of our
22552245
// string a path component for that class_method.
2256-
if (info.srcOperand->get()->getType() != info.outSendingResult->getType()) {
2257-
if (auto fas = FullApplySite::isa(info.srcOperand->getUser())) {
2246+
if (srcOperand->get()->getType() != outSendingResult->getType()) {
2247+
if (auto fas = FullApplySite::isa(srcOperand->getUser())) {
22582248
if (fas.hasSelfArgument() &&
2259-
fas.getSelfArgument() == info.srcOperand->get() &&
2249+
fas.getSelfArgument() == srcOperand->get() &&
22602250
fas.getNumIndirectSILResults() == 1) {
22612251
// First check if our function argument is exactly our out parameter.
2262-
bool canEmit =
2263-
info.outSendingResult == fas.getIndirectSILResults()[0];
2252+
bool canEmit = outSendingResult == fas.getIndirectSILResults()[0];
22642253

22652254
// If that fails, see if we are storing into a temporary
22662255
// alloc_stack. In such a case, find the root value that the temporary
22672256
// is initialized to and see if that is our target function
22682257
// argument. In such a case, we also want to add the decl name to our
22692258
// type.
22702259
if (!canEmit) {
2271-
canEmit = info.outSendingResult ==
2260+
canEmit = outSendingResult ==
22722261
findOutParameter(fas.getIndirectSILResults()[0]);
22732262
}
22742263

@@ -2289,42 +2278,35 @@ void AssignIsolatedIntoSendingResultDiagnosticEmitter::emit() {
22892278
}
22902279

22912280
diagnoseError(
2292-
info.srcOperand,
2281+
srcOperand,
22932282
diag::regionbasedisolation_out_sending_cannot_be_actor_isolated_named,
22942283
*varName, descriptiveKindStr)
22952284
.limitBehaviorIf(getConcurrencyDiagnosticBehavior());
22962285

22972286
diagnoseNote(
2298-
info.srcOperand,
2287+
srcOperand,
22992288
diag::
23002289
regionbasedisolation_out_sending_cannot_be_actor_isolated_note_named,
23012290
*varName, descriptiveKindStr);
23022291
return;
23032292
}
23042293

2305-
Type type = info.nonTransferrableValue->getType().getASTType();
2294+
Type type = nonTransferrableValue->getType().getASTType();
23062295

23072296
diagnoseError(
2308-
info.srcOperand,
2297+
srcOperand,
23092298
diag::regionbasedisolation_out_sending_cannot_be_actor_isolated_type,
23102299
type, descriptiveKindStr)
23112300
.limitBehaviorIf(getConcurrencyDiagnosticBehavior());
23122301

23132302
diagnoseNote(
2314-
info.srcOperand,
2303+
srcOperand,
23152304
diag::regionbasedisolation_out_sending_cannot_be_actor_isolated_note_type,
23162305
type, descriptiveKindStr);
2317-
diagnoseNote(info.srcOperand, diag::regionbasedisolation_type_is_non_sendable,
2306+
diagnoseNote(srcOperand, diag::regionbasedisolation_type_is_non_sendable,
23182307
type);
23192308
}
23202309

2321-
void TransferNonSendableImpl::emitAssignIsolatedIntoSendingResultDiagnostics() {
2322-
for (auto &info : assignIsolatedIntoOutSendingParameterInfoList) {
2323-
AssignIsolatedIntoSendingResultDiagnosticEmitter emitter(info);
2324-
emitter.emit();
2325-
}
2326-
}
2327-
23282310
//===----------------------------------------------------------------------===//
23292311
// MARK: Diagnostic Evaluator
23302312
//===----------------------------------------------------------------------===//
@@ -2343,27 +2325,17 @@ struct DiagnosticEvaluator final
23432325
/// sending operands to require insts.
23442326
SmallVectorImpl<PartitionOpError> &foundVerbatimErrors;
23452327

2346-
/// A list of state that tracks specific 'inout sending' parameters that were
2347-
/// actor isolated on function exit with the necessary state to emit the
2348-
/// error.
2349-
SmallVectorImpl<AssignIsolatedIntoOutSendingParameterInfo>
2350-
&assignIsolatedIntoOutSendingParameterInfoList;
2351-
23522328
DiagnosticEvaluator(Partition &workingPartition,
23532329
RegionAnalysisFunctionInfo *info,
23542330
SmallFrozenMultiMap<Operand *, RequireInst, 8>
23552331
&transferOpToRequireInstMultiMap,
23562332
SmallVectorImpl<PartitionOpError> &foundVerbatimErrors,
2357-
SmallVectorImpl<AssignIsolatedIntoOutSendingParameterInfo>
2358-
&assignIsolatedIntoOutSendingParameterInfo,
23592333
TransferringOperandToStateMap &operandToStateMap)
23602334
: PartitionOpEvaluatorBaseImpl(
23612335
workingPartition, info->getOperandSetFactory(), operandToStateMap),
23622336
info(info),
23632337
transferOpToRequireInstMultiMap(transferOpToRequireInstMultiMap),
2364-
foundVerbatimErrors(foundVerbatimErrors),
2365-
assignIsolatedIntoOutSendingParameterInfoList(
2366-
assignIsolatedIntoOutSendingParameterInfo) {}
2338+
foundVerbatimErrors(foundVerbatimErrors) {}
23672339

23682340
void handleLocalUseAfterTransfer(LocalUseAfterSendError error) const {
23692341
const auto &partitionOp = *error.op;
@@ -2401,29 +2373,6 @@ struct DiagnosticEvaluator final
24012373
RequireInst::forUseAfterTransfer(partitionOp.getSourceInst()));
24022374
}
24032375

2404-
void handleAssignTransferNonTransferrableIntoSendingResult(
2405-
AssignNeverSendableIntoSendingResultError error) const {
2406-
const PartitionOp &partitionOp = *error.op;
2407-
Element destElement = error.destElement;
2408-
SILFunctionArgument *destValue = error.destValue;
2409-
Element srcElement = error.srcElement;
2410-
SILValue srcValue = error.srcValue;
2411-
auto srcIsolationRegionInfo = error.srcIsolationRegionInfo;
2412-
auto srcRep = info->getValueMap().getRepresentativeValue(srcElement);
2413-
REGIONBASEDISOLATION_LOG(
2414-
llvm::dbgs()
2415-
<< " Emitting Error. Kind: Assign Isolated Into Sending Result!\n"
2416-
<< " Assign Inst: " << *partitionOp.getSourceInst()
2417-
<< " Dest Value: " << *destValue
2418-
<< " Dest Element: " << destElement << '\n'
2419-
<< " Src Value: " << srcValue
2420-
<< " Src Element: " << srcElement << '\n'
2421-
<< " Src Rep: " << srcRep
2422-
<< " Src Isolation: " << srcIsolationRegionInfo << '\n');
2423-
assignIsolatedIntoOutSendingParameterInfoList.emplace_back(
2424-
partitionOp.getSourceOp(), destValue, srcValue, srcIsolationRegionInfo);
2425-
}
2426-
24272376
void handleInOutSendingNotInitializedAtExitError(
24282377
InOutSendingNotInitializedAtExitError error) const {
24292378
const PartitionOp &partitionOp = *error.op;
@@ -2465,12 +2414,9 @@ struct DiagnosticEvaluator final
24652414
}
24662415
case PartitionOpError::InOutSendingNotDisconnectedAtExit:
24672416
case PartitionOpError::SentNeverSendable:
2417+
case PartitionOpError::AssignNeverSendableIntoSendingResult:
24682418
foundVerbatimErrors.emplace_back(error);
24692419
return;
2470-
case PartitionOpError::AssignNeverSendableIntoSendingResult: {
2471-
return handleAssignTransferNonTransferrableIntoSendingResult(
2472-
error.getAssignNeverSendableIntoSendingResultError());
2473-
}
24742420
case PartitionOpError::InOutSendingNotInitializedAtExit: {
24752421
return handleInOutSendingNotInitializedAtExitError(
24762422
error.getInOutSendingNotInitializedAtExitError());
@@ -2544,8 +2490,7 @@ void TransferNonSendableImpl::runDiagnosticEvaluator() {
25442490
Partition workingPartition = blockState.getEntryPartition();
25452491
DiagnosticEvaluator eval(
25462492
workingPartition, info, transferOpToRequireInstMultiMap,
2547-
foundVerbatimErrors, assignIsolatedIntoOutSendingParameterInfoList,
2548-
info->getTransferringOpToStateMap());
2493+
foundVerbatimErrors, info->getTransferringOpToStateMap());
25492494

25502495
// And then evaluate all of our partition ops on the entry partition.
25512496
for (auto &partitionOp : blockState.getPartitionOps()) {
@@ -2572,10 +2517,28 @@ void TransferNonSendableImpl::emitVerbatimErrors() {
25722517
switch (erasedError.getKind()) {
25732518
case PartitionOpError::UnknownCodePattern:
25742519
case PartitionOpError::LocalUseAfterSend:
2575-
llvm_unreachable("Handled elsewhere");
2576-
case PartitionOpError::AssignNeverSendableIntoSendingResult:
25772520
case PartitionOpError::InOutSendingNotInitializedAtExit:
2578-
llvm_unreachable("Not implemented yet");
2521+
llvm_unreachable("Handled elsewhere");
2522+
case PartitionOpError::AssignNeverSendableIntoSendingResult: {
2523+
auto error = erasedError.getAssignNeverSendableIntoSendingResultError();
2524+
auto srcRep =
2525+
info->getValueMap().getRepresentativeValue(error.srcElement);
2526+
REGIONBASEDISOLATION_LOG(
2527+
llvm::dbgs()
2528+
<< " Emitting Error. Kind: Assign Isolated Into Sending Result!\n"
2529+
<< " Assign Inst: " << *error.op->getSourceInst()
2530+
<< " Dest Value: " << *error.destValue
2531+
<< " Dest Element: " << error.destElement << '\n'
2532+
<< " Src Value: " << error.srcValue
2533+
<< " Src Element: " << error.srcElement << '\n'
2534+
<< " Src Rep: " << srcRep
2535+
<< " Src Isolation: " << error.srcIsolationRegionInfo << '\n');
2536+
AssignIsolatedIntoSendingResultDiagnosticEmitter emitter(
2537+
error.op->getSourceOp(), error.destValue, error.srcValue,
2538+
error.srcIsolationRegionInfo);
2539+
emitter.emit();
2540+
continue;
2541+
}
25792542
case PartitionOpError::InOutSendingNotDisconnectedAtExit: {
25802543
auto error = erasedError.getInOutSendingNotDisconnectedAtExitError();
25812544
auto inoutSendingVal =
@@ -2641,7 +2604,6 @@ void TransferNonSendableImpl::emitDiagnostics() {
26412604

26422605
runDiagnosticEvaluator();
26432606
emitUseAfterTransferDiagnostics();
2644-
emitAssignIsolatedIntoSendingResultDiagnostics();
26452607
emitVerbatimErrors();
26462608
}
26472609

0 commit comments

Comments
 (0)