Skip to content

Commit e6b4e0f

Browse files
authored
Merge pull request #77709 from gottesmm/pr-6feaf0c91a7d95d75b36d32cc91a32150d992162
[region-isolation] Some initial NFCI refactoring commits before adding experimental support for inheriting isolation to nonisolated functions
2 parents 729e3c0 + d94e4c4 commit e6b4e0f

File tree

9 files changed

+211
-124
lines changed

9 files changed

+211
-124
lines changed

include/swift/AST/Types.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5348,6 +5348,18 @@ class SILFunctionType final
53485348
return getParameters().back();
53495349
}
53505350

5351+
/// Return SILParameterInfo for the isolated parameter in this SILFunctionType
5352+
/// if one exists. Returns None otherwise.
5353+
std::optional<SILParameterInfo> maybeGetIsolatedParameter() const {
5354+
for (auto param : getParameters()) {
5355+
if (param.hasOption(SILParameterInfo::Isolated)) {
5356+
return param;
5357+
}
5358+
}
5359+
5360+
return {};
5361+
}
5362+
53515363
struct IndirectMutatingParameterFilter {
53525364
bool operator()(SILParameterInfo param) const {
53535365
return param.isIndirectMutating();

include/swift/SILOptimizer/Utils/PartitionUtils.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ namespace swift {
8888

8989
class Partition;
9090
class SendingOperandToStateMap;
91+
class RegionAnalysisValueMap;
9192

9293
/// The representative value of the equivalence class that makes up a tracked
9394
/// value.
@@ -380,6 +381,7 @@ class IsolationHistory::Factory {
380381
IsolationHistory get() { return IsolationHistory(this); }
381382
};
382383

384+
/// A struct that represents a specific "sending" operand of an ApplySite.
383385
struct SendingOperandState {
384386
/// The dynamic isolation info of the region of value when we sent.
385387
///
@@ -954,6 +956,12 @@ class PartitionOpError {
954956
const PartitionOp *op;
955957

956958
UnknownCodePatternError(const PartitionOp &op) : op(&op) {}
959+
960+
void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;
961+
962+
SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
963+
print(llvm::dbgs(), valueMap);
964+
}
957965
};
958966

959967
struct LocalUseAfterSendError {
@@ -964,6 +972,12 @@ class PartitionOpError {
964972
LocalUseAfterSendError(const PartitionOp &op, Element elt,
965973
Operand *sendingOp)
966974
: op(&op), sentElement(elt), sendingOp(sendingOp) {}
975+
976+
void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;
977+
978+
SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
979+
print(llvm::dbgs(), valueMap);
980+
}
967981
};
968982

969983
struct SentNeverSendableError {
@@ -975,6 +989,12 @@ class PartitionOpError {
975989
SILDynamicMergedIsolationInfo isolationRegionInfo)
976990
: op(&op), sentElement(sentElement),
977991
isolationRegionInfo(isolationRegionInfo) {}
992+
993+
void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;
994+
995+
SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
996+
print(llvm::dbgs(), valueMap);
997+
}
978998
};
979999

9801000
struct AssignNeverSendableIntoSendingResultError {
@@ -992,6 +1012,12 @@ class PartitionOpError {
9921012
: op(&op), destElement(destElement), destValue(destValue),
9931013
srcElement(srcElement), srcValue(srcValue),
9941014
srcIsolationRegionInfo(srcIsolationRegionInfo) {}
1015+
1016+
void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;
1017+
1018+
SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
1019+
print(llvm::dbgs(), valueMap);
1020+
}
9951021
};
9961022

9971023
struct InOutSendingNotInitializedAtExitError {
@@ -1002,6 +1028,12 @@ class PartitionOpError {
10021028
InOutSendingNotInitializedAtExitError(const PartitionOp &op, Element elt,
10031029
Operand *sendingOp)
10041030
: op(&op), sentElement(elt), sendingOp(sendingOp) {}
1031+
1032+
void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;
1033+
1034+
SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
1035+
print(llvm::dbgs(), valueMap);
1036+
}
10051037
};
10061038

10071039
struct InOutSendingNotDisconnectedAtExitError {
@@ -1013,6 +1045,12 @@ class PartitionOpError {
10131045
const PartitionOp &op, Element elt,
10141046
SILDynamicMergedIsolationInfo isolation)
10151047
: op(&op), inoutSendingElement(elt), isolationInfo(isolation) {}
1048+
1049+
void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const;
1050+
1051+
SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
1052+
print(llvm::dbgs(), valueMap);
1053+
}
10161054
};
10171055

10181056
#define PARTITION_OP_ERROR(NAME) \
@@ -1067,6 +1105,20 @@ class PartitionOpError {
10671105

10681106
Kind getKind() const { return kind; }
10691107

1108+
void print(llvm::raw_ostream &os, RegionAnalysisValueMap &valueMap) const {
1109+
switch (getKind()) {
1110+
#define PARTITION_OP_ERROR(NAME) \
1111+
case NAME: \
1112+
return get##NAME##Error().print(os, valueMap);
1113+
#include "PartitionOpError.def"
1114+
}
1115+
llvm_unreachable("Covered switch isn't covered?!");
1116+
}
1117+
1118+
SWIFT_DEBUG_DUMPER(dump(RegionAnalysisValueMap &valueMap)) {
1119+
return print(llvm::dbgs(), valueMap);
1120+
}
1121+
10701122
#define PARTITION_OP_ERROR(NAME) \
10711123
NAME##Error get##NAME##Error() const { \
10721124
assert(getKind() == Kind::NAME); \

include/swift/SILOptimizer/Utils/SILIsolationInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@ class SILDynamicMergedIsolationInfo {
507507
operator bool() const { return bool(innerInfo); }
508508

509509
SILIsolationInfo *operator->() { return &innerInfo; }
510+
const SILIsolationInfo *operator->() const { return &innerInfo; }
510511

511512
SILIsolationInfo getIsolationInfo() const { return innerInfo; }
512513

lib/SILGen/SILGen.cpp

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,25 @@ static bool isEmittedOnDemand(SILModule &M, SILDeclRef constant) {
731731
return false;
732732
}
733733

734+
static ActorIsolation getActorIsolationForFunction(SILFunction &fn) {
735+
if (auto constant = fn.getDeclRef()) {
736+
if (constant.kind == SILDeclRef::Kind::Deallocator) {
737+
// Deallocating destructor is always nonisolated. Isolation of the deinit
738+
// applies only to isolated deallocator and destroyer.
739+
return ActorIsolation::forNonisolated(false);
740+
}
741+
742+
// If we have actor isolation for our constant, put the isolation onto the
743+
// function. If the isolation is unspecified, we do not return it.
744+
if (auto isolation =
745+
getActorIsolationOfContext(constant.getInnermostDeclContext()))
746+
return isolation;
747+
}
748+
749+
// Otherwise, return for unspecified.
750+
return ActorIsolation::forUnspecified();
751+
}
752+
734753
SILFunction *SILGenModule::getFunction(SILDeclRef constant,
735754
ForDefinition_t forDefinition) {
736755
// If we already emitted the function, return it.
@@ -756,16 +775,8 @@ SILFunction *SILGenModule::getFunction(SILDeclRef constant,
756775
return IGM.getFunction(constant, NotForDefinition);
757776
});
758777

759-
if (constant.kind == SILDeclRef::Kind::Deallocator) {
760-
// Deallocating destructor is always nonisolated.
761-
// Isolation of the deinit applies only to isolated deallocator and
762-
// destroyer.
763-
F->setActorIsolation(ActorIsolation::forNonisolated(false));
764-
} else {
765-
// If we have global actor isolation for our constant, put the isolation onto
766-
// the function.
767-
F->setActorIsolation(getActorIsolationOfContext(constant.getInnermostDeclContext()));
768-
}
778+
F->setDeclRef(constant);
779+
F->setActorIsolation(getActorIsolationForFunction(*F));
769780

770781
assert(F && "SILFunction should have been defined");
771782

@@ -1254,23 +1265,15 @@ void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F,
12541265
F->setGenericEnvironment(genericEnv, capturedEnvs, forwardingSubs);
12551266
}
12561267

1257-
if (constant.kind == SILDeclRef::Kind::Deallocator) {
1258-
// Deallocating destructor is always nonisolated.
1259-
// Isolation of the deinit applies only to isolated deallocator and
1260-
// destroyer.
1261-
F->setActorIsolation(ActorIsolation::forNonisolated(false));
1262-
} else {
1263-
// If we have global actor isolation for our constant, put the isolation
1264-
// onto the function.
1265-
F->setActorIsolation(getActorIsolationOfContext(constant.getInnermostDeclContext()));
1266-
}
1267-
12681268
// Create a debug scope for the function using astNode as source location.
12691269
F->setDebugScope(new (M) SILDebugScope(Loc, F));
12701270

12711271
// Initialize F with the constant we created for it.
12721272
F->setDeclRef(constant);
12731273

1274+
// Set our actor isolation.
1275+
F->setActorIsolation(getActorIsolationForFunction(*F));
1276+
12741277
LLVM_DEBUG(llvm::dbgs() << "lowering ";
12751278
F->printName(llvm::dbgs());
12761279
llvm::dbgs() << " : ";

lib/SILGen/SILGenApply.cpp

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3412,11 +3412,18 @@ Expr *ArgumentSource::findStorageReferenceExprForBorrow() && {
34123412
namespace {
34133413

34143414
class ArgEmitter {
3415+
public:
3416+
enum Flag {
3417+
IsYield = 0x1,
3418+
IsForCoroutine = 0x2,
3419+
};
3420+
using OptionSet = OptionSet<Flag>;
3421+
3422+
private:
34153423
SILGenFunction &SGF;
34163424
SILLocation ApplyLoc;
34173425
SILFunctionTypeRepresentation Rep;
3418-
bool IsYield;
3419-
bool IsForCoroutine;
3426+
OptionSet Options;
34203427
ForeignInfo Foreign;
34213428
ClaimedParamsRef ParamInfos;
34223429
SmallVectorImpl<ManagedValue> &Args;
@@ -3427,13 +3434,11 @@ class ArgEmitter {
34273434

34283435
public:
34293436
ArgEmitter(SILGenFunction &SGF, SILLocation applyLoc,
3430-
SILFunctionTypeRepresentation Rep,
3431-
bool isYield, bool isForCoroutine, ClaimedParamsRef paramInfos,
3432-
SmallVectorImpl<ManagedValue> &args,
3437+
SILFunctionTypeRepresentation Rep, OptionSet options,
3438+
ClaimedParamsRef paramInfos, SmallVectorImpl<ManagedValue> &args,
34333439
SmallVectorImpl<DelayedArgument> &delayedArgs,
34343440
const ForeignInfo &foreign)
3435-
: SGF(SGF), ApplyLoc(applyLoc),
3436-
Rep(Rep), IsYield(isYield), IsForCoroutine(isForCoroutine),
3441+
: SGF(SGF), ApplyLoc(applyLoc), Rep(Rep), Options(options),
34373442
Foreign(foreign), ParamInfos(paramInfos), Args(args),
34383443
DelayedArguments(delayedArgs) {}
34393444

@@ -3559,7 +3564,7 @@ class ArgEmitter {
35593564
// If we have a guaranteed +0 parameter...
35603565
if (param.isGuaranteedInCaller() || isShared) {
35613566
// And this is a yield, emit a borrowed r-value.
3562-
if (IsYield) {
3567+
if (Options.contains(Flag::IsYield)) {
35633568
if (tryEmitBorrowed(std::move(arg), loweredSubstArgType,
35643569
loweredSubstParamType, origParamType, paramSlice))
35653570
return;
@@ -3610,7 +3615,7 @@ class ArgEmitter {
36103615

36113616
// Handle yields of storage reference expressions specially so that we
36123617
// don't emit them as +1 r-values and then expand.
3613-
if (IsYield) {
3618+
if (Options.contains(Flag::IsYield)) {
36143619
if (auto result = std::move(arg).findStorageReferenceExprForBorrow()) {
36153620
emitExpandedBorrowed(result, origParamType);
36163621
return;
@@ -3858,7 +3863,8 @@ class ArgEmitter {
38583863

38593864
auto convertOwnershipConvention = [&](ManagedValue value) {
38603865
return convertOwnershipConventionGivenParamInfo(
3861-
SGF, param, origParam, value, loc, IsForCoroutine);
3866+
SGF, param, origParam, value, loc,
3867+
Options.contains(Flag::IsForCoroutine));
38623868
};
38633869

38643870
auto contexts = getRValueEmissionContexts(loweredSubstArgType, param);
@@ -4423,10 +4429,9 @@ void DelayedArgument::emitDefaultArgument(SILGenFunction &SGF,
44234429

44244430
SmallVector<ManagedValue, 4> loweredArgs;
44254431
SmallVector<DelayedArgument, 4> delayedArgs;
4426-
auto emitter = ArgEmitter(SGF, info.loc, info.functionRepresentation,
4427-
/*yield*/ false, /*coroutine*/ false,
4428-
info.paramsToEmit, loweredArgs,
4429-
delayedArgs, ForeignInfo{});
4432+
auto emitter =
4433+
ArgEmitter(SGF, info.loc, info.functionRepresentation, {},
4434+
info.paramsToEmit, loweredArgs, delayedArgs, ForeignInfo{});
44304435

44314436
emitter.emitSingleArg(ArgumentSource(info.loc, std::move(value)),
44324437
info.origResultType);
@@ -4818,9 +4823,11 @@ class CallSite {
48184823
const ForeignInfo &foreign) && {
48194824
auto params = lowering.claimParams(origFormalType, getParams(), foreign);
48204825

4821-
ArgEmitter emitter(SGF, Loc, lowering.Rep, /*yield*/ false,
4822-
/*isForCoroutine*/ substFnType->isCoroutine(), params,
4823-
args, delayedArgs, foreign);
4826+
ArgEmitter::OptionSet options;
4827+
if (substFnType->isCoroutine())
4828+
options |= ArgEmitter::IsForCoroutine;
4829+
ArgEmitter emitter(SGF, Loc, lowering.Rep, options, params, args,
4830+
delayedArgs, foreign);
48244831
emitter.emitPreparedArgs(std::move(Args), origFormalType);
48254832
}
48264833

@@ -6069,8 +6076,8 @@ void SILGenFunction::emitYield(SILLocation loc,
60696076
origYield.getConvention()});
60706077
}
60716078

6072-
ArgEmitter emitter(*this, loc, fnType->getRepresentation(), /*yield*/ true,
6073-
/*isForCoroutine*/ false, ClaimedParamsRef(substYieldTys),
6079+
ArgEmitter emitter(*this, loc, fnType->getRepresentation(),
6080+
ArgEmitter::IsYield, ClaimedParamsRef(substYieldTys),
60746081
yieldArgs, delayedArgs, ForeignInfo{});
60756082

60766083
for (auto i : indices(valueSources)) {
@@ -7077,10 +7084,9 @@ static void emitPseudoFunctionArguments(SILGenFunction &SGF,
70777084
SmallVector<ManagedValue, 4> argValues;
70787085
SmallVector<DelayedArgument, 2> delayedArgs;
70797086

7080-
ArgEmitter emitter(SGF, applyLoc, SILFunctionTypeRepresentation::Thin,
7081-
/*yield*/ false,
7082-
/*isForCoroutine*/ false, ClaimedParamsRef(substParamTys),
7083-
argValues, delayedArgs, ForeignInfo{});
7087+
ArgEmitter emitter(SGF, applyLoc, SILFunctionTypeRepresentation::Thin, {},
7088+
ClaimedParamsRef(substParamTys), argValues, delayedArgs,
7089+
ForeignInfo{});
70847090

70857091
emitter.emitPreparedArgs(std::move(args), origFnType);
70867092

@@ -7765,9 +7771,7 @@ SmallVector<ManagedValue, 4> SILGenFunction::emitKeyPathSubscriptOperands(
77657771

77667772
SmallVector<ManagedValue, 4> argValues;
77677773
SmallVector<DelayedArgument, 2> delayedArgs;
7768-
ArgEmitter emitter(*this, loc, fnType->getRepresentation(),
7769-
/*yield*/ false,
7770-
/*isForCoroutine*/ false,
7774+
ArgEmitter emitter(*this, loc, fnType->getRepresentation(), {},
77717775
ClaimedParamsRef(fnType->getParameters()), argValues,
77727776
delayedArgs, ForeignInfo{});
77737777

0 commit comments

Comments
 (0)