Skip to content

Commit 63b3c2b

Browse files
committed
[Distributed] Add a new access strategy - DispatchToDistributedThunk
This strategy is used to dispatch accesses to 'distributed' computed property to distributed thunk accessor instead of a regular getter when access happen outside actor isolation context.
1 parent a77351e commit 63b3c2b

File tree

5 files changed

+47
-6
lines changed

5 files changed

+47
-6
lines changed

include/swift/AST/StorageImpl.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ class AccessStrategy {
110110
/// separately performing a Read into a temporary variable followed by
111111
/// a Write access back into the storage.
112112
MaterializeToTemporary,
113+
114+
/// The access is to a computed distributed property, and thus the
115+
/// get-accessor is a distributed thunk which may perform a remote call.
116+
DispatchToDistributedThunk,
113117
};
114118

115119
private:
@@ -149,6 +153,10 @@ class AccessStrategy {
149153
return { dispatched ? DispatchToAccessor : DirectToAccessor, accessor };
150154
}
151155

156+
static AccessStrategy getDistributedThunkDispatchStrategy() {
157+
return {DispatchToDistributedThunk, AccessorKind::Get};
158+
}
159+
152160
static AccessStrategy getMaterializeToTemporary(AccessStrategy read,
153161
AccessStrategy write) {
154162
return { read, write };
@@ -157,7 +165,8 @@ class AccessStrategy {
157165
Kind getKind() const { return TheKind; }
158166

159167
bool hasAccessor() const {
160-
return TheKind == DirectToAccessor || TheKind == DispatchToAccessor;
168+
return TheKind == DirectToAccessor || TheKind == DispatchToAccessor ||
169+
TheKind == DispatchToDistributedThunk;
161170
}
162171

163172
AccessorKind getAccessor() const {

lib/AST/Decl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,10 +2272,8 @@ AbstractStorageDecl::getAccessStrategy(AccessSemantics semantics,
22722272
assert(hasStorage());
22732273
return AccessStrategy::getStorage();
22742274

2275-
// FIXME: For now `DistributedThunk` behaves just like `Ordinary` but it
2276-
// needs a new strategy to be useful.
22772275
case AccessSemantics::DistributedThunk:
2278-
LLVM_FALLTHROUGH;
2276+
return AccessStrategy::getDistributedThunkDispatchStrategy();
22792277

22802278
case AccessSemantics::Ordinary:
22812279
// Skip these checks for local variables, both because they're unnecessary

lib/SILGen/SILGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,7 @@ SILGenModule::canStorageUseStoredKeyPathComponent(AbstractStorageDecl *decl,
18391839
case AccessStrategy::DirectToAccessor:
18401840
case AccessStrategy::DispatchToAccessor:
18411841
case AccessStrategy::MaterializeToTemporary:
1842+
case AccessStrategy::DispatchToDistributedThunk:
18421843
return false;
18431844
}
18441845
llvm_unreachable("unhandled strategy");

lib/SILGen/SILGenExpr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3508,6 +3508,14 @@ getIdForKeyPathComponentComputedProperty(SILGenModule &SGM,
35083508
// Identify the property by its vtable or wtable slot.
35093509
return SGM.getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage));
35103510
}
3511+
3512+
case AccessStrategy::DispatchToDistributedThunk: {
3513+
auto thunkRef = SILDeclRef(cast<VarDecl>(storage)->getDistributedThunk(),
3514+
SILDeclRef::Kind::Func,
3515+
/*isForeign=*/false,
3516+
/*isDistributed=*/true);
3517+
return SGM.getFunction(thunkRef, NotForDefinition);
3518+
}
35113519
}
35123520
llvm_unreachable("unhandled access strategy");
35133521
}

lib/SILGen/SILGenLValue.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2684,6 +2684,9 @@ namespace {
26842684
strategy.getWriteStrategy(),
26852685
typeData);
26862686
}
2687+
2688+
case AccessStrategy::DispatchToDistributedThunk:
2689+
return asImpl().emitUsingDistributedThunk();
26872690
}
26882691
llvm_unreachable("unknown kind");
26892692
}
@@ -2889,6 +2892,11 @@ void LValue::addNonMemberVarComponent(SILGenFunction &SGF, SILLocation loc,
28892892
if (address.getType().is<ReferenceStorageType>())
28902893
LV.add<OwnershipComponent>(typeData);
28912894
}
2895+
2896+
void emitUsingDistributedThunk() {
2897+
llvm_unreachable("cannot dispatch non-member var via distributed thunk");
2898+
}
2899+
28922900
} emitter(SGF, loc, var, subs, accessKind, formalRValueType, options,
28932901
actorIso, *this);
28942902

@@ -3184,11 +3192,11 @@ static SGFAccessKind getBaseAccessKind(SILGenModule &SGM,
31843192
}
31853193

31863194
case AccessStrategy::DirectToAccessor:
3187-
case AccessStrategy::DispatchToAccessor: {
3195+
case AccessStrategy::DispatchToAccessor:
3196+
case AccessStrategy::DispatchToDistributedThunk: {
31883197
auto accessor = member->getOpaqueAccessor(strategy.getAccessor());
31893198
return getBaseAccessKindForAccessor(SGM, accessor, baseFormalType);
31903199
}
3191-
31923200
}
31933201
llvm_unreachable("bad access strategy");
31943202
}
@@ -3396,6 +3404,19 @@ void LValue::addMemberVarComponent(SILGenFunction &SGF, SILLocation loc,
33963404
LV.add<OwnershipComponent>(typeData);
33973405
}
33983406
}
3407+
3408+
void emitUsingDistributedThunk() {
3409+
auto *var = cast<VarDecl>(Storage);
3410+
SILDeclRef accessor(var->getDistributedThunk(), SILDeclRef::Kind::Func,
3411+
/*isForeign=*/false, /*isDistributed=*/true);
3412+
3413+
auto typeData = getLogicalStorageTypeData(
3414+
SGF.getTypeExpansionContext(), SGF.SGM, AccessKind, FormalRValueType);
3415+
3416+
asImpl().emitUsingGetterSetter(accessor, /*isDirect=*/false,
3417+
/*isDistributed=*/true, typeData);
3418+
}
3419+
33993420
} emitter(SGF, loc, var, subs, isSuper, accessKind,
34003421
formalRValueType, options, *this,
34013422
/*indices for diags*/ nullptr, /*indices*/ PreparedArguments(),
@@ -3571,6 +3592,10 @@ void LValue::addMemberSubscriptComponent(SILGenFunction &SGF, SILLocation loc,
35713592
void emitUsingStorage(LValueTypeData typeData) {
35723593
llvm_unreachable("subscripts never have storage");
35733594
}
3595+
3596+
void emitUsingDistributedThunk() {
3597+
llvm_unreachable("subscripts cannot be dispatch via distributed thunk");
3598+
}
35743599
} emitter(SGF, loc, decl, subs, isSuper, accessKind, formalRValueType,
35753600
options, *this, argListForDiagnostics, std::move(indices),
35763601
isOnSelfParameter, actorIso);

0 commit comments

Comments
 (0)