|
12 | 12 |
|
13 | 13 | #include "swift/SILOptimizer/Utils/PartitionUtils.h" |
14 | 14 |
|
| 15 | +#include "swift/AST/ASTWalker.h" |
15 | 16 | #include "swift/AST/Expr.h" |
16 | 17 | #include "swift/SIL/ApplySite.h" |
17 | 18 | #include "swift/SIL/InstructionUtils.h" |
@@ -70,6 +71,37 @@ getGlobalActorInitIsolation(SILFunction *fn) { |
70 | 71 | return getActorIsolation(globalDecl); |
71 | 72 | } |
72 | 73 |
|
| 74 | +static DeclRefExpr *getDeclRefExprFromExpr(Expr *expr) { |
| 75 | + struct LocalWalker final : ASTWalker { |
| 76 | + DeclRefExpr *result = nullptr; |
| 77 | + |
| 78 | + PreWalkResult<Expr *> walkToExprPre(Expr *expr) override { |
| 79 | + assert(!result && "Shouldn't have a result yet"); |
| 80 | + |
| 81 | + if (auto *dre = dyn_cast<DeclRefExpr>(expr)) { |
| 82 | + result = dre; |
| 83 | + return Action::Stop(); |
| 84 | + } |
| 85 | + |
| 86 | + if (isa<CoerceExpr, MemberRefExpr, ImplicitConversionExpr, IdentityExpr>( |
| 87 | + expr)) |
| 88 | + return Action::Continue(expr); |
| 89 | + |
| 90 | + return Action::Stop(); |
| 91 | + } |
| 92 | + }; |
| 93 | + |
| 94 | + LocalWalker walker; |
| 95 | + |
| 96 | + if (auto *ae = dyn_cast<AssignExpr>(expr)) { |
| 97 | + ae->getSrc()->walk(walker); |
| 98 | + } else { |
| 99 | + expr->walk(walker); |
| 100 | + } |
| 101 | + |
| 102 | + return walker.result; |
| 103 | +} |
| 104 | + |
73 | 105 | SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) { |
74 | 106 | if (auto fas = FullApplySite::isa(inst)) { |
75 | 107 | if (auto crossing = fas.getIsolationCrossing()) { |
@@ -176,15 +208,30 @@ SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) { |
176 | 208 | // actor isolated method. Use the AST to compute the actor isolation and |
177 | 209 | // check if we are self. If we are not self, we want this to be |
178 | 210 | // disconnected. |
179 | | - if (auto *declRefExpr = cmi->getLoc().getAsASTNode<DeclRefExpr>()) { |
180 | | - if (auto isolation = swift::getActorIsolation(declRefExpr->getDecl())) { |
181 | | - if (isolation.isActorIsolated() && |
182 | | - (isolation.getKind() != ActorIsolation::ActorInstance || |
183 | | - isolation.getActorInstanceParameter() == 0)) { |
184 | | - auto actor = cmi->getOperand()->getType().isAnyActor() |
185 | | - ? cmi->getOperand() |
186 | | - : SILValue(); |
187 | | - return SILIsolationInfo::getActorIsolated(cmi, actor, isolation); |
| 211 | + if (auto *expr = cmi->getLoc().getAsASTNode<Expr>()) { |
| 212 | + if (auto *dre = getDeclRefExprFromExpr(expr)) { |
| 213 | + if (auto isolation = swift::getActorIsolation(dre->getDecl())) { |
| 214 | + if (isolation.isActorIsolated() && |
| 215 | + (isolation.getKind() != ActorIsolation::ActorInstance || |
| 216 | + isolation.getActorInstanceParameter() == 0)) { |
| 217 | + auto actor = cmi->getOperand()->getType().isAnyActor() |
| 218 | + ? cmi->getOperand() |
| 219 | + : SILValue(); |
| 220 | + return SILIsolationInfo::getActorIsolated(cmi, actor, isolation); |
| 221 | + } |
| 222 | + } |
| 223 | + |
| 224 | + if (auto type = dre->getType()->getNominalOrBoundGenericNominal()) { |
| 225 | + if (auto isolation = swift::getActorIsolation(type)) { |
| 226 | + if (isolation.isActorIsolated() && |
| 227 | + (isolation.getKind() != ActorIsolation::ActorInstance || |
| 228 | + isolation.getActorInstanceParameter() == 0)) { |
| 229 | + auto actor = cmi->getOperand()->getType().isAnyActor() |
| 230 | + ? cmi->getOperand() |
| 231 | + : SILValue(); |
| 232 | + return SILIsolationInfo::getActorIsolated(cmi, actor, isolation); |
| 233 | + } |
| 234 | + } |
188 | 235 | } |
189 | 236 | } |
190 | 237 | } |
@@ -266,9 +313,15 @@ SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) { |
266 | 313 | // of the actor. |
267 | 314 | if (ApplyExpr *apply = inst->getLoc().getAsASTNode<ApplyExpr>()) { |
268 | 315 | if (auto crossing = apply->getIsolationCrossing()) { |
269 | | - if (crossing->getCalleeIsolation().isActorIsolated()) |
| 316 | + auto calleeIsolation = crossing->getCalleeIsolation(); |
| 317 | + if (calleeIsolation.isActorIsolated()) { |
270 | 318 | return SILIsolationInfo::getActorIsolated( |
271 | 319 | SILValue(), SILValue(), crossing->getCalleeIsolation()); |
| 320 | + } |
| 321 | + |
| 322 | + if (calleeIsolation.isNonisolated()) { |
| 323 | + return SILIsolationInfo::getDisconnected(); |
| 324 | + } |
272 | 325 | } |
273 | 326 | } |
274 | 327 |
|
|
0 commit comments