Skip to content

Commit 78804c4

Browse files
committed
[region-isolation] Move computation of SILIsolationInfo for FunctionRefInst/ClassMethodInst into SILIsolationInfo::get instead of handrolling in RegionAnalysis.
(cherry picked from commit 2a7714a)
1 parent e336f0c commit 78804c4

File tree

2 files changed

+52
-55
lines changed

2 files changed

+52
-55
lines changed

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3298,64 +3298,17 @@ TrackableValue RegionAnalysisValueMap::getTrackableValue(
32983298
}
32993299
}
33003300

3301-
if (auto *defInst = value.getDefiningInstruction()) {
3302-
// Treat function ref as either actor isolated or sendable.
3303-
if (auto *fri = dyn_cast<FunctionRefInst>(defInst)) {
3304-
auto isolation = fri->getReferencedFunction()->getActorIsolation();
3305-
if (isolation.isActorIsolated()) {
3306-
iter.first->getSecond().mergeIsolationRegionInfo(
3307-
SILIsolationInfo::getActorIsolated(value, isolation));
3308-
return {iter.first->first, iter.first->second};
3309-
}
3310-
3311-
// Otherwise, lets look at the AST and see if our function ref is from an
3312-
// autoclosure.
3313-
if (auto *autoclosure = fri->getLoc().getAsASTNode<AutoClosureExpr>()) {
3314-
if (auto *funcType = autoclosure->getType()->getAs<AnyFunctionType>()) {
3315-
if (funcType->hasGlobalActor()) {
3316-
if (funcType->hasGlobalActor()) {
3317-
iter.first->getSecond().mergeIsolationRegionInfo(
3318-
SILIsolationInfo::getActorIsolated(
3319-
fri, ActorIsolation::forGlobalActor(
3320-
funcType->getGlobalActor())));
3321-
return {iter.first->first, iter.first->second};
3322-
}
3323-
}
3324-
3325-
if (auto *resultFType =
3326-
funcType->getResult()->getAs<AnyFunctionType>()) {
3327-
if (resultFType->hasGlobalActor()) {
3328-
iter.first->getSecond().mergeIsolationRegionInfo(
3329-
SILIsolationInfo::getActorIsolated(
3330-
fri, ActorIsolation::forGlobalActor(
3331-
resultFType->getGlobalActor())));
3332-
return {iter.first->first, iter.first->second};
3333-
}
3334-
}
3335-
}
3336-
}
3337-
3338-
iter.first->getSecond().addFlag(TrackableValueFlag::isSendable);
3301+
// Treat function ref and class method as either actor isolated or
3302+
// sendable. Formally they are non-Sendable, so we do the check before we
3303+
// check the oracle.
3304+
if (isa<FunctionRefInst, ClassMethodInst>(value)) {
3305+
if (auto isolation = SILIsolationInfo::get(value)) {
3306+
iter.first->getSecond().mergeIsolationRegionInfo(isolation);
33393307
return {iter.first->first, iter.first->second};
33403308
}
33413309

3342-
if (auto *cmi = dyn_cast<ClassMethodInst>(defInst)) {
3343-
if (auto *declRefExpr = cmi->getLoc().getAsASTNode<DeclRefExpr>()) {
3344-
// See if we are actor isolated. If so, treat this as non-Sendable so we
3345-
// propagate actor isolation.
3346-
if (auto isolation = getActorIsolation(declRefExpr->getDecl())) {
3347-
if (isolation.isActorIsolated()) {
3348-
iter.first->getSecond().mergeIsolationRegionInfo(
3349-
SILIsolationInfo::getActorIsolated(cmi->getOperand(),
3350-
isolation));
3351-
return {iter.first->first, iter.first->second};
3352-
}
3353-
}
3354-
}
3355-
3356-
iter.first->getSecond().addFlag(TrackableValueFlag::isSendable);
3357-
return {iter.first->first, iter.first->second};
3358-
}
3310+
iter.first->getSecond().addFlag(TrackableValueFlag::isSendable);
3311+
return {iter.first->first, iter.first->second};
33593312
}
33603313

33613314
// Otherwise refer to the oracle. If we have a Sendable value, just return.

lib/SILOptimizer/Utils/PartitionUtils.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,50 @@ SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) {
104104
}
105105
}
106106

107+
// Treat function ref as either actor isolated or sendable.
108+
if (auto *fri = dyn_cast<FunctionRefInst>(inst)) {
109+
auto isolation = fri->getReferencedFunction()->getActorIsolation();
110+
if (isolation.isActorIsolated()) {
111+
return SILIsolationInfo::getActorIsolated(fri, isolation);
112+
}
113+
114+
// Otherwise, lets look at the AST and see if our function ref is from an
115+
// autoclosure.
116+
if (auto *autoclosure = fri->getLoc().getAsASTNode<AutoClosureExpr>()) {
117+
if (auto *funcType = autoclosure->getType()->getAs<AnyFunctionType>()) {
118+
if (funcType->hasGlobalActor()) {
119+
if (funcType->hasGlobalActor()) {
120+
return SILIsolationInfo::getActorIsolated(
121+
fri,
122+
ActorIsolation::forGlobalActor(funcType->getGlobalActor()));
123+
}
124+
}
125+
126+
if (auto *resultFType =
127+
funcType->getResult()->getAs<AnyFunctionType>()) {
128+
if (resultFType->hasGlobalActor()) {
129+
return SILIsolationInfo::getActorIsolated(
130+
fri,
131+
ActorIsolation::forGlobalActor(resultFType->getGlobalActor()));
132+
}
133+
}
134+
}
135+
}
136+
}
137+
138+
if (auto *cmi = dyn_cast<ClassMethodInst>(inst)) {
139+
if (auto *declRefExpr = cmi->getLoc().getAsASTNode<DeclRefExpr>()) {
140+
// See if we are actor isolated. If so, treat this as non-Sendable so we
141+
// propagate actor isolation.
142+
if (auto isolation = swift::getActorIsolation(declRefExpr->getDecl())) {
143+
if (isolation.isActorIsolated()) {
144+
return SILIsolationInfo::getActorIsolated(cmi->getOperand(),
145+
isolation);
146+
}
147+
}
148+
}
149+
}
150+
107151
return SILIsolationInfo();
108152
}
109153

0 commit comments

Comments
 (0)