Skip to content

Commit 5191c31

Browse files
committed
Eliminate ImplicitActorHopTarget in favor of ActorIsolation.
The generalized ActorIsolation is enough to represent everything that ImplicitActorHopTarget can do, and we were mapping between the two way too often, so collapse them.
1 parent 141ffc2 commit 5191c31

File tree

5 files changed

+39
-123
lines changed

5 files changed

+39
-123
lines changed

include/swift/AST/Expr.h

Lines changed: 15 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,80 +1163,19 @@ class DiscardAssignmentExpr : public Expr {
11631163
}
11641164
};
11651165

1166-
/// Describes the actor to which an implicit-async expression will hop.
1167-
struct ImplicitActorHopTarget {
1168-
enum Kind {
1169-
/// The "self" instance.
1170-
InstanceSelf,
1171-
/// A global actor with the given type.
1172-
GlobalActor,
1173-
/// An isolated parameter in a call.
1174-
IsolatedParameter,
1175-
};
1176-
1177-
private:
1178-
/// The lower two bits are the Kind, and the remaining bits are used for
1179-
/// the payload, which might by a TypeBase * (for a global actor) or a
1180-
/// integer value (for an isolated parameter).
1181-
uintptr_t bits;
1182-
1183-
constexpr ImplicitActorHopTarget(uintptr_t bits) : bits(bits) { }
1184-
1185-
public:
1186-
/// Default-initialized to instance "self".
1187-
constexpr ImplicitActorHopTarget() : bits(0) { }
1188-
1189-
static ImplicitActorHopTarget forInstanceSelf() {
1190-
return ImplicitActorHopTarget(InstanceSelf);
1191-
}
1192-
1193-
static ImplicitActorHopTarget forGlobalActor(Type globalActor) {
1194-
uintptr_t bits =
1195-
reinterpret_cast<uintptr_t>(globalActor.getPointer()) | GlobalActor;
1196-
return ImplicitActorHopTarget(bits);
1197-
}
1198-
1199-
static ImplicitActorHopTarget forIsolatedParameter(unsigned index) {
1200-
uintptr_t bits = static_cast<uintptr_t>(index) << 2 | IsolatedParameter;
1201-
return ImplicitActorHopTarget(bits);
1202-
}
1203-
1204-
/// Determine the kind of implicit actor hop being performed.
1205-
Kind getKind() const {
1206-
return static_cast<Kind>(bits & 0x03);
1207-
}
1208-
1209-
operator Kind() const {
1210-
return getKind();
1211-
}
1212-
1213-
/// Retrieve the global actor type for an implicit hop to a global actor.
1214-
Type getGlobalActor() const {
1215-
assert(getKind() == GlobalActor);
1216-
return Type(reinterpret_cast<TypeBase *>(bits & ~0x03));
1217-
}
1218-
1219-
/// Retrieve the (zero-based) parameter index for the isolated parameter
1220-
/// in a call.
1221-
unsigned getIsolatedParameterIndex() const {
1222-
assert(getKind() == IsolatedParameter);
1223-
return bits >> 2;
1224-
}
1225-
};
1226-
1227-
12281166
/// DeclRefExpr - A reference to a value, "x".
12291167
class DeclRefExpr : public Expr {
12301168
/// The declaration pointer.
12311169
ConcreteDeclRef D;
12321170
DeclNameLoc Loc;
1233-
ImplicitActorHopTarget implicitActorHopTarget;
1171+
ActorIsolation implicitActorHopTarget;
12341172

12351173
public:
12361174
DeclRefExpr(ConcreteDeclRef D, DeclNameLoc Loc, bool Implicit,
12371175
AccessSemantics semantics = AccessSemantics::Ordinary,
12381176
Type Ty = Type())
1239-
: Expr(ExprKind::DeclRef, Implicit, Ty), D(D), Loc(Loc) {
1177+
: Expr(ExprKind::DeclRef, Implicit, Ty), D(D), Loc(Loc),
1178+
implicitActorHopTarget(ActorIsolation::forUnspecified()) {
12401179
Bits.DeclRefExpr.Semantics = (unsigned) semantics;
12411180
Bits.DeclRefExpr.FunctionRefKind =
12421181
static_cast<unsigned>(Loc.isCompound() ? FunctionRefKind::Compound
@@ -1258,15 +1197,15 @@ class DeclRefExpr : public Expr {
12581197

12591198
/// Determine whether this reference needs to happen asynchronously, i.e.,
12601199
/// guarded by hop_to_executor, and if so describe the target.
1261-
Optional<ImplicitActorHopTarget> isImplicitlyAsync() const {
1200+
Optional<ActorIsolation> isImplicitlyAsync() const {
12621201
if (!Bits.DeclRefExpr.IsImplicitlyAsync)
12631202
return None;
12641203

12651204
return implicitActorHopTarget;
12661205
}
12671206

12681207
/// Note that this reference is implicitly async and set the target.
1269-
void setImplicitlyAsync(ImplicitActorHopTarget target) {
1208+
void setImplicitlyAsync(ActorIsolation target) {
12701209
Bits.DeclRefExpr.IsImplicitlyAsync = true;
12711210
implicitActorHopTarget = target;
12721211
}
@@ -1600,12 +1539,13 @@ class UnresolvedDeclRefExpr : public Expr {
16001539
class LookupExpr : public Expr {
16011540
Expr *Base;
16021541
ConcreteDeclRef Member;
1603-
ImplicitActorHopTarget implicitActorHopTarget;
1542+
ActorIsolation implicitActorHopTarget;
16041543

16051544
protected:
16061545
explicit LookupExpr(ExprKind Kind, Expr *base, ConcreteDeclRef member,
16071546
bool Implicit)
1608-
: Expr(Kind, Implicit), Base(base), Member(member) {
1547+
: Expr(Kind, Implicit), Base(base), Member(member),
1548+
implicitActorHopTarget(ActorIsolation::forUnspecified()) {
16091549
Bits.LookupExpr.IsSuper = false;
16101550
Bits.LookupExpr.IsImplicitlyAsync = false;
16111551
Bits.LookupExpr.IsImplicitlyThrows = false;
@@ -1640,15 +1580,15 @@ class LookupExpr : public Expr {
16401580

16411581
/// Determine whether this reference needs to happen asynchronously, i.e.,
16421582
/// guarded by hop_to_executor, and if so describe the target.
1643-
Optional<ImplicitActorHopTarget> isImplicitlyAsync() const {
1583+
Optional<ActorIsolation> isImplicitlyAsync() const {
16441584
if (!Bits.LookupExpr.IsImplicitlyAsync)
16451585
return None;
16461586

16471587
return implicitActorHopTarget;
16481588
}
16491589

16501590
/// Note that this reference is implicitly async and set the target.
1651-
void setImplicitlyAsync(ImplicitActorHopTarget target) {
1591+
void setImplicitlyAsync(ActorIsolation target) {
16521592
Bits.LookupExpr.IsImplicitlyAsync = true;
16531593
implicitActorHopTarget = target;
16541594
}
@@ -4482,12 +4422,13 @@ class ApplyExpr : public Expr {
44824422
/// The list of arguments to call the function with.
44834423
ArgumentList *ArgList;
44844424

4485-
ImplicitActorHopTarget implicitActorHopTarget;
4425+
ActorIsolation implicitActorHopTarget;
44864426

44874427
protected:
44884428
ApplyExpr(ExprKind kind, Expr *fn, ArgumentList *argList, bool implicit,
44894429
Type ty = Type())
4490-
: Expr(kind, implicit, ty), Fn(fn), ArgList(argList) {
4430+
: Expr(kind, implicit, ty), Fn(fn), ArgList(argList),
4431+
implicitActorHopTarget(ActorIsolation::forUnspecified()) {
44914432
assert(ArgList);
44924433
assert(classof((Expr*)this) && "ApplyExpr::classof out of date");
44934434
Bits.ApplyExpr.ThrowsIsSet = false;
@@ -4553,15 +4494,15 @@ class ApplyExpr : public Expr {
45534494
///
45544495
/// When the application is implicitly async, the result describes
45554496
/// the actor to which we need to need to hop.
4556-
Optional<ImplicitActorHopTarget> isImplicitlyAsync() const {
4497+
Optional<ActorIsolation> isImplicitlyAsync() const {
45574498
if (!Bits.ApplyExpr.ImplicitlyAsync)
45584499
return None;
45594500

45604501
return implicitActorHopTarget;
45614502
}
45624503

45634504
/// Note that this application is implicitly async and set the target.
4564-
void setImplicitlyAsync(ImplicitActorHopTarget target) {
4505+
void setImplicitlyAsync(ActorIsolation target) {
45654506
Bits.ApplyExpr.ImplicitlyAsync = true;
45664507
implicitActorHopTarget = target;
45674508
}

lib/SILGen/SILGenApply.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3886,7 +3886,7 @@ class CallEmission {
38863886

38873887
Callee callee;
38883888
FormalEvaluationScope initialWritebackScope;
3889-
Optional<ImplicitActorHopTarget> implicitActorHopTarget;
3889+
Optional<ActorIsolation> implicitActorHopTarget;
38903890
bool implicitlyThrows;
38913891

38923892
public:
@@ -3937,7 +3937,7 @@ class CallEmission {
39373937
/// implicitly async, i.e., it requires a hop_to_executor prior to
39383938
/// invoking the sync callee, etc.
39393939
void setImplicitlyAsync(
3940-
Optional<ImplicitActorHopTarget> implicitActorHopTarget) {
3940+
Optional<ActorIsolation> implicitActorHopTarget) {
39413941
this->implicitActorHopTarget = implicitActorHopTarget;
39423942
}
39433943

@@ -4573,7 +4573,7 @@ RValue SILGenFunction::emitApply(
45734573
ArrayRef<ManagedValue> args,
45744574
const CalleeTypeInfo &calleeTypeInfo,
45754575
ApplyOptions options, SGFContext evalContext,
4576-
Optional<ImplicitActorHopTarget> implicitActorHopTarget) {
4576+
Optional<ActorIsolation> implicitActorHopTarget) {
45774577
auto substFnType = calleeTypeInfo.substFnType;
45784578
auto substResultType = calleeTypeInfo.substResultType;
45794579

@@ -4672,18 +4672,24 @@ RValue SILGenFunction::emitApply(
46724672

46734673
SILValue executor;
46744674
switch (*implicitActorHopTarget) {
4675-
case ImplicitActorHopTarget::InstanceSelf:
4676-
executor = emitLoadActorExecutor(loc, args.back());
4675+
case ActorIsolation::ActorInstance:
4676+
if (unsigned paramIndex =
4677+
implicitActorHopTarget->getActorInstanceParameter()) {
4678+
executor = emitLoadActorExecutor(loc, args[paramIndex-1]);
4679+
} else {
4680+
executor = emitLoadActorExecutor(loc, args.back());
4681+
}
46774682
break;
46784683

4679-
case ImplicitActorHopTarget::GlobalActor:
4684+
case ActorIsolation::GlobalActor:
4685+
case ActorIsolation::GlobalActorUnsafe:
46804686
executor = emitLoadGlobalActorExecutor(
46814687
implicitActorHopTarget->getGlobalActor());
46824688
break;
46834689

4684-
case ImplicitActorHopTarget::IsolatedParameter:
4685-
executor = emitLoadActorExecutor(
4686-
loc, args[implicitActorHopTarget->getIsolatedParameterIndex()]);
4690+
case ActorIsolation::Unspecified:
4691+
case ActorIsolation::Independent:
4692+
llvm_unreachable("Not isolated");
46874693
break;
46884694
}
46894695

@@ -5897,7 +5903,7 @@ RValue SILGenFunction::emitGetAccessor(
58975903
PreparedArguments &&subscriptIndices,
58985904
SGFContext c,
58995905
bool isOnSelfParameter,
5900-
Optional<ImplicitActorHopTarget> implicitActorHopTarget) {
5906+
Optional<ActorIsolation> implicitActorHopTarget) {
59015907
// Scope any further writeback just within this operation.
59025908
FormalEvaluationScope writebackScope(*this);
59035909

lib/SILGen/SILGenFunction.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
14511451
bool isDirectAccessorUse,
14521452
PreparedArguments &&optionalSubscripts, SGFContext C,
14531453
bool isOnSelfParameter,
1454-
Optional<ImplicitActorHopTarget> implicitActorHopTarget = None);
1454+
Optional<ActorIsolation> implicitActorHopTarget = None);
14551455

14561456
void emitSetAccessor(SILLocation loc, SILDeclRef setter,
14571457
SubstitutionMap substitutions,
@@ -1684,7 +1684,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
16841684
ArrayRef<ManagedValue> args,
16851685
const CalleeTypeInfo &calleeTypeInfo, ApplyOptions options,
16861686
SGFContext evalContext,
1687-
Optional<ImplicitActorHopTarget> implicitActorHopTarget);
1687+
Optional<ActorIsolation> implicitActorHopTarget);
16881688

16891689
RValue emitApplyOfDefaultArgGenerator(SILLocation loc,
16901690
ConcreteDeclRef defaultArgsOwner,

lib/SILGen/SILGenLValue.cpp

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,23 +1648,13 @@ namespace {
16481648
RValue rvalue;
16491649
FormalEvaluationScope scope(SGF);
16501650

1651-
// FIXME: This somewhat silly, because the original expression should
1652-
// already have one of these.
1653-
Optional<ImplicitActorHopTarget> implicitActorHopTarget;
1654-
if (ActorIso) {
1655-
implicitActorHopTarget = ActorIso->isGlobalActor()
1656-
? ImplicitActorHopTarget::forGlobalActor(
1657-
ActorIso->getGlobalActor())
1658-
: ImplicitActorHopTarget::forInstanceSelf();
1659-
}
1660-
16611651
auto args =
16621652
std::move(*this).prepareAccessorArgs(SGF, loc, base, getter);
16631653

16641654
rvalue = SGF.emitGetAccessor(
16651655
loc, getter, Substitutions, std::move(args.base), IsSuper,
16661656
IsDirectAccessorUse, std::move(args.Indices), c,
1667-
IsOnSelfParameter, implicitActorHopTarget);
1657+
IsOnSelfParameter, ActorIso);
16681658

16691659
return rvalue;
16701660
}

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,7 +1783,7 @@ namespace {
17831783
///
17841784
/// and we reach up to mark the CallExpr.
17851785
void markNearestCallAsImplicitly(
1786-
Optional<ImplicitActorHopTarget> setAsync,
1786+
Optional<ActorIsolation> setAsync,
17871787
bool setThrows = false,
17881788
bool setDistributedThunk = false) {
17891789
assert(applyStack.size() > 0 && "not contained within an Apply?");
@@ -2369,7 +2369,7 @@ namespace {
23692369
AsyncMarkingResult tryMarkImplicitlyAsync(SourceLoc declLoc,
23702370
ConcreteDeclRef concDeclRef,
23712371
Expr* context,
2372-
ImplicitActorHopTarget target,
2372+
ActorIsolation target,
23732373
bool isDistributed) {
23742374
ValueDecl *decl = concDeclRef.getDecl();
23752375
AsyncMarkingResult result = AsyncMarkingResult::NotFound;
@@ -2583,25 +2583,8 @@ namespace {
25832583
}
25842584

25852585
// Mark as implicitly async.
2586-
if (!fnType->getExtInfo().isAsync()) {
2587-
switch (*unsatisfiedIsolation) {
2588-
case ActorIsolation::GlobalActor:
2589-
case ActorIsolation::GlobalActorUnsafe:
2590-
apply->setImplicitlyAsync(
2591-
ImplicitActorHopTarget::forGlobalActor(
2592-
unsatisfiedIsolation->getGlobalActor()));
2593-
break;
2594-
2595-
case ActorIsolation::ActorInstance:
2596-
apply->setImplicitlyAsync(
2597-
ImplicitActorHopTarget::forIsolatedParameter(
2598-
unsatisfiedIsolation->getActorInstanceParameter() - 1));
2599-
break;
2600-
2601-
case ActorIsolation::Unspecified:
2602-
case ActorIsolation::Independent:
2603-
llvm_unreachable("Not actor-isolated");
2604-
}
2586+
if (!fnType->getExtInfo().isAsync() && unsatisfiedIsolation) {
2587+
apply->setImplicitlyAsync(*unsatisfiedIsolation);
26052588
}
26062589

26072590
// Check for sendability of the parameter types.
@@ -2879,12 +2862,8 @@ namespace {
28792862
ActorReferenceResult::Flags::Distributed);
28802863

28812864
// Determine the actor hop.
2882-
ImplicitActorHopTarget target = result.isolation.isGlobalActor()
2883-
? ImplicitActorHopTarget::forGlobalActor(
2884-
result.isolation.getGlobalActor())
2885-
: ImplicitActorHopTarget::forInstanceSelf();
28862865
auto implicitAsyncResult = tryMarkImplicitlyAsync(
2887-
loc, declRef, context, target, isDistributed);
2866+
loc, declRef, context, result.isolation, isDistributed);
28882867
switch (implicitAsyncResult) {
28892868
case AsyncMarkingResult::FoundAsync:
28902869
// Success! We're done.

0 commit comments

Comments
 (0)