Merge pull request #74919 from gottesmm/pr-d8b24a45ff257893c8172491f11a617fc00d5589

[region-isolation] Implement support for 'inout sending' diagnostics.
This commit is contained in:
Michael Gottesman
2024-07-02 20:16:25 -07:00
committed by GitHub
8 changed files with 560 additions and 80 deletions

View File

@@ -1205,6 +1205,14 @@ struct PartitionOpBuilder {
PartitionOp::Require(lookupValueID(value), currentInst));
}
void addRequireInOutSendingAtFunctionExit(SILValue value) {
assert(valueHasID(value, /*dumpIfHasNoID=*/true) &&
"required value should already have been encountered");
currentInstPartitionOps.emplace_back(
PartitionOp::RequireInOutSendingAtFunctionExit(lookupValueID(value),
currentInst));
}
void addUnknownPatternError(SILValue value) {
if (shouldAbortOnUnknownPatternMatchError()) {
llvm::report_fatal_error(
@@ -1604,9 +1612,9 @@ public:
// compiler exits successfully, actor merge errors could not have happened.
std::optional<SILDynamicMergedIsolationInfo> mergedInfo;
if (resultIsolationInfoOverride) {
mergedInfo = resultIsolationInfoOverride;
mergedInfo = SILDynamicMergedIsolationInfo(resultIsolationInfoOverride);
} else {
mergedInfo = SILIsolationInfo::getDisconnected(false);
mergedInfo = SILDynamicMergedIsolationInfo::getDisconnected(false);
}
for (SILValue src : sourceValues) {
@@ -2321,6 +2329,22 @@ public:
#define INST(INST, PARENT) TranslationSemantics visit##INST(INST *inst);
#include "swift/SIL/SILNodes.def"
/// Adds requires for all sending inout parameters to make sure that they are
/// properly updated before the end of the function.
void addRequiresForInOutParameters(TermInst *inst) {
assert(inst->isFunctionExiting() && "Must be function exiting term inst?!");
for (auto *arg : inst->getFunction()->getArguments()) {
auto *fArg = cast<SILFunctionArgument>(arg);
if (fArg->getArgumentConvention().isInoutConvention() &&
fArg->getKnownParameterInfo().hasOption(SILParameterInfo::Sending)) {
if (auto ns = tryToTrackValue(arg)) {
auto rep = ns->getRepresentative().getValue();
builder.addRequireInOutSendingAtFunctionExit(rep);
}
}
}
}
/// Top level switch that translates SIL instructions.
void translateSILInstruction(SILInstruction *inst) {
builder.reset(inst);
@@ -2710,12 +2734,8 @@ CONSTANT_TRANSLATION(CondFailInst, Ignored)
// function_ref/class_method which are considered sendable.
CONSTANT_TRANSLATION(SwitchValueInst, Ignored)
CONSTANT_TRANSLATION(UnreachableInst, Ignored)
CONSTANT_TRANSLATION(UnwindInst, Ignored)
// Doesn't take a parameter.
CONSTANT_TRANSLATION(ThrowAddrInst, Ignored)
// Terminators that only need require.
CONSTANT_TRANSLATION(ThrowInst, Require)
CONSTANT_TRANSLATION(SwitchEnumAddrInst, Require)
CONSTANT_TRANSLATION(YieldInst, Require)
@@ -2725,6 +2745,33 @@ CONSTANT_TRANSLATION(CondBranchInst, TerminatorPhi)
CONSTANT_TRANSLATION(CheckedCastBranchInst, TerminatorPhi)
CONSTANT_TRANSLATION(DynamicMethodBranchInst, TerminatorPhi)
// Function exiting terminators.
//
// We handle these especially since we want to make sure that inout parameters
// that are transferred are forced to be reinitialized.
//
// There is an assert in TermInst::isFunctionExiting that makes sure we do this
// correctly.
//
// NOTE: We purposely do not require reinitialization along paths that end in
// unreachable.
#ifdef FUNCTION_EXITING_TERMINATOR_TRANSLATION
#error "FUNCTION_EXITING_TERMINATOR_TRANSLATION already defined?!"
#endif
#define FUNCTION_EXITING_TERMINATOR_CONSTANT(INST, Kind) \
TranslationSemantics PartitionOpTranslator::visit##INST(INST *inst) { \
assert(inst->isFunctionExiting() && "Must be function exiting?!"); \
addRequiresForInOutParameters(inst); \
return TranslationSemantics::Kind; \
}
FUNCTION_EXITING_TERMINATOR_CONSTANT(UnwindInst, Ignored)
FUNCTION_EXITING_TERMINATOR_CONSTANT(ThrowAddrInst, Ignored)
FUNCTION_EXITING_TERMINATOR_CONSTANT(ThrowInst, Require)
#undef FUNCTION_EXITING_TERMINATOR_CONSTANT
// Today, await_async_continuation just takes Sendable values
// (UnsafeContinuation and UnsafeThrowingContinuation).
CONSTANT_TRANSLATION(AwaitAsyncContinuationInst, AssertingIfNonSendable)
@@ -2961,6 +3008,7 @@ PartitionOpTranslator::visitLoadBorrowInst(LoadBorrowInst *lbi) {
}
TranslationSemantics PartitionOpTranslator::visitReturnInst(ReturnInst *ri) {
addRequiresForInOutParameters(ri);
if (ri->getFunction()->getLoweredFunctionType()->hasSendingResult()) {
return TranslationSemantics::TransferringNoResult;
}