Skip to content

Commit 2120438

Browse files
committed
SIL: Add flag to SILDeclRef for back deployment thunks.
1 parent b0a038b commit 2120438

File tree

5 files changed

+73
-15
lines changed

5 files changed

+73
-15
lines changed

include/swift/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6268,6 +6268,9 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
62686268
/// Returns 'true' if the function is distributed.
62696269
bool isDistributed() const;
62706270

6271+
/// Returns 'true' if the function can be back deployed.
6272+
bool isBackDeployed() const;
6273+
62716274
PolymorphicEffectKind getPolymorphicEffectKind(EffectKind kind) const;
62726275

62736276
// FIXME: Hack that provides names with keyword arguments for accessors.

include/swift/SIL/SILDeclRef.h

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ struct SILDeclRef {
170170
unsigned isForeign : 1;
171171
/// True if this references a distributed function.
172172
unsigned isDistributed : 1;
173+
/// True if this references a back deployed entry point for the referenced decl.
174+
unsigned isBackDeployed : 1;
173175
/// The default argument index for a default argument getter.
174176
unsigned defaultArgIndex : 10;
175177

@@ -204,13 +206,15 @@ struct SILDeclRef {
204206

205207
/// Produces a null SILDeclRef.
206208
SILDeclRef()
207-
: loc(), kind(Kind::Func), isForeign(0), isDistributed(0), defaultArgIndex(0) {}
209+
: loc(), kind(Kind::Func), isForeign(0), isDistributed(0),
210+
isBackDeployed(0), defaultArgIndex(0) {}
208211

209212
/// Produces a SILDeclRef of the given kind for the given decl.
210213
explicit SILDeclRef(
211214
ValueDecl *decl, Kind kind,
212215
bool isForeign = false,
213216
bool isDistributed = false,
217+
bool isBackDeployed = false,
214218
AutoDiffDerivativeFunctionIdentifier *derivativeId = nullptr);
215219

216220
/// Produces a SILDeclRef for the given ValueDecl or
@@ -224,7 +228,11 @@ struct SILDeclRef {
224228
/// for the containing ClassDecl.
225229
/// - If 'loc' is a global VarDecl, this returns its GlobalAccessor
226230
/// SILDeclRef.
227-
explicit SILDeclRef(Loc loc, bool isForeign = false, bool isDistributed = false);
231+
explicit SILDeclRef(
232+
Loc loc,
233+
bool isForeign = false,
234+
bool isDistributed = false,
235+
bool isBackDeployed = false);
228236

229237
/// See above put produces a prespecialization according to the signature.
230238
explicit SILDeclRef(Loc loc, GenericSignature prespecializationSig);
@@ -360,6 +368,7 @@ struct SILDeclRef {
360368
return loc.getOpaqueValue() == rhs.loc.getOpaqueValue() &&
361369
kind == rhs.kind && isForeign == rhs.isForeign &&
362370
isDistributed == rhs.isDistributed &&
371+
isBackDeployed == rhs.isBackDeployed &&
363372
defaultArgIndex == rhs.defaultArgIndex &&
364373
pointer == rhs.pointer;
365374
}
@@ -378,6 +387,7 @@ struct SILDeclRef {
378387
return SILDeclRef(loc.getOpaqueValue(), kind,
379388
/*foreign=*/foreign,
380389
/*distributed=*/false,
390+
/*backDeployed=*/false,
381391
defaultArgIndex,
382392
pointer.get<AutoDiffDerivativeFunctionIdentifier *>());
383393
}
@@ -387,6 +397,17 @@ struct SILDeclRef {
387397
return SILDeclRef(loc.getOpaqueValue(), kind,
388398
/*foreign=*/false,
389399
/*distributed=*/distributed,
400+
/*backDeployed=*/false,
401+
defaultArgIndex,
402+
pointer.get<AutoDiffDerivativeFunctionIdentifier *>());
403+
}
404+
/// Returns the back deployment entry point corresponding to the same
405+
/// decl.
406+
SILDeclRef asBackDeployed(bool backDeployed = true) const {
407+
return SILDeclRef(loc.getOpaqueValue(), kind,
408+
/*foreign=*/false,
409+
/*distributed=*/false,
410+
/*backDeployed=*/backDeployed,
390411
defaultArgIndex,
391412
pointer.get<AutoDiffDerivativeFunctionIdentifier *>());
392413
}
@@ -431,6 +452,10 @@ struct SILDeclRef {
431452
/// True if the decl ref references a thunk handling potentially distributed actor functions
432453
bool isDistributedThunk() const;
433454

455+
/// True if the decl ref references a thunk handling a call to a back deployed
456+
/// function.
457+
bool isBackDeployedThunk() const;
458+
434459
/// True if the decl ref references a method which introduces a new vtable
435460
/// entry.
436461
bool requiresNewVTableEntry() const;
@@ -508,11 +533,12 @@ struct SILDeclRef {
508533
explicit SILDeclRef(void *opaqueLoc, Kind kind,
509534
bool isForeign,
510535
bool isDistributed,
536+
bool isBackDeployed,
511537
unsigned defaultArgIndex,
512538
AutoDiffDerivativeFunctionIdentifier *derivativeId)
513539
: loc(Loc::getFromOpaqueValue(opaqueLoc)), kind(kind),
514540
isForeign(isForeign), isDistributed(isDistributed),
515-
defaultArgIndex(defaultArgIndex),
541+
isBackDeployed(isBackDeployed), defaultArgIndex(defaultArgIndex),
516542
pointer(derivativeId) {}
517543
};
518544

@@ -534,12 +560,12 @@ template<> struct DenseMapInfo<swift::SILDeclRef> {
534560
using UnsignedInfo = DenseMapInfo<unsigned>;
535561

536562
static SILDeclRef getEmptyKey() {
537-
return SILDeclRef(PointerInfo::getEmptyKey(), Kind::Func, false, false, 0,
538-
nullptr);
563+
return SILDeclRef(PointerInfo::getEmptyKey(), Kind::Func, false, false,
564+
false, 0, nullptr);
539565
}
540566
static SILDeclRef getTombstoneKey() {
541567
return SILDeclRef(PointerInfo::getTombstoneKey(), Kind::Func, false, false,
542-
0, nullptr);
568+
false, 0, nullptr);
543569
}
544570
static unsigned getHashValue(swift::SILDeclRef Val) {
545571
unsigned h1 = PointerInfo::getHashValue(Val.loc.getOpaqueValue());
@@ -550,7 +576,9 @@ template<> struct DenseMapInfo<swift::SILDeclRef> {
550576
unsigned h4 = UnsignedInfo::getHashValue(Val.isForeign);
551577
unsigned h5 = PointerInfo::getHashValue(Val.pointer.getOpaqueValue());
552578
unsigned h6 = UnsignedInfo::getHashValue(Val.isDistributed);
553-
return h1 ^ (h2 << 4) ^ (h3 << 9) ^ (h4 << 7) ^ (h5 << 11) ^ (h6 << 8);
579+
unsigned h7 = UnsignedInfo::getHashValue(Val.isBackDeployed);
580+
return h1 ^ (h2 << 4) ^ (h3 << 9) ^ (h4 << 7) ^ (h5 << 11) ^ (h6 << 8) ^
581+
(h7 << 10);
554582
}
555583
static bool isEqual(swift::SILDeclRef const &LHS,
556584
swift::SILDeclRef const &RHS) {

lib/AST/Decl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7531,6 +7531,10 @@ bool AbstractFunctionDecl::isSendable() const {
75317531
return getAttrs().hasAttribute<SendableAttr>();
75327532
}
75337533

7534+
bool AbstractFunctionDecl::isBackDeployed() const {
7535+
return getAttrs().hasAttribute<BackDeployAttr>();
7536+
}
7537+
75347538
BraceStmt *AbstractFunctionDecl::getBody(bool canSynthesize) const {
75357539
if ((getBodyKind() == BodyKind::Synthesize ||
75367540
getBodyKind() == BodyKind::Unparsed) &&

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,13 @@ bool swift::requiresForeignEntryPoint(ValueDecl *vd) {
122122
}
123123

124124
SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind,
125-
bool isForeign, bool isDistributed,
125+
bool isForeign, bool isDistributed, bool isBackDeployed,
126126
AutoDiffDerivativeFunctionIdentifier *derivativeId)
127127
: loc(vd), kind(kind), isForeign(isForeign), isDistributed(isDistributed),
128-
defaultArgIndex(0), pointer(derivativeId) {}
128+
isBackDeployed(isBackDeployed), defaultArgIndex(0), pointer(derivativeId) {}
129129

130-
SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, bool asForeign, bool asDistributed)
130+
SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, bool asForeign,
131+
bool asDistributed, bool asBackDeployed)
131132
: defaultArgIndex(0),
132133
pointer((AutoDiffDerivativeFunctionIdentifier *)nullptr) {
133134
if (auto *vd = baseLoc.dyn_cast<ValueDecl*>()) {
@@ -167,6 +168,7 @@ SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, bool asForeign, bool asDistribut
167168

168169
isForeign = asForeign;
169170
isDistributed = asDistributed;
171+
isBackDeployed = asBackDeployed;
170172
}
171173

172174
SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc,
@@ -202,7 +204,8 @@ ASTContext &SILDeclRef::getASTContext() const {
202204
}
203205

204206
bool SILDeclRef::isThunk() const {
205-
return isForeignToNativeThunk() || isNativeToForeignThunk() || isDistributedThunk();
207+
return isForeignToNativeThunk() || isNativeToForeignThunk() ||
208+
isDistributedThunk() || isBackDeployedThunk();
206209
}
207210

208211
bool SILDeclRef::isClangImported() const {
@@ -730,7 +733,8 @@ bool SILDeclRef::isAlwaysInline() const {
730733
bool SILDeclRef::isAnyThunk() const {
731734
return isForeignToNativeThunk() ||
732735
isNativeToForeignThunk() ||
733-
isDistributedThunk();
736+
isDistributedThunk() ||
737+
isBackDeployedThunk();
734738
}
735739

736740
bool SILDeclRef::isForeignToNativeThunk() const {
@@ -784,6 +788,12 @@ bool SILDeclRef::isDistributedThunk() const {
784788
return kind == Kind::Func;
785789
}
786790

791+
bool SILDeclRef::isBackDeployedThunk() const {
792+
if (!isBackDeployed)
793+
return false;
794+
return kind == Kind::Func;
795+
}
796+
787797
/// Use the Clang importer to mangle a Clang declaration.
788798
static void mangleClangDecl(raw_ostream &buffer,
789799
const clang::NamedDecl *clangDecl,
@@ -995,6 +1005,8 @@ bool SILDeclRef::requiresNewVTableEntry() const {
9951005
return false;
9961006
if (isDistributedThunk())
9971007
return false;
1008+
if (isBackDeployedThunk())
1009+
return false;
9981010
auto fnDecl = dyn_cast<AbstractFunctionDecl>(getDecl());
9991011
if (!fnDecl)
10001012
return false;
@@ -1031,7 +1043,11 @@ SILDeclRef SILDeclRef::getNextOverriddenVTableEntry() const {
10311043
// Distributed thunks are not in the vtable.
10321044
if (isDistributedThunk())
10331045
return SILDeclRef();
1034-
1046+
1047+
// Back deployed thunks are not in the vtable.
1048+
if (isBackDeployedThunk())
1049+
return SILDeclRef();
1050+
10351051
// An @objc convenience initializer can be "overridden" in the sense that
10361052
// its selector is reclaimed by a subclass's convenience init with the
10371053
// same name. The AST models this as an override for the purposes of
@@ -1313,6 +1329,8 @@ bool SILDeclRef::canBeDynamicReplacement() const {
13131329
return false;
13141330
if (isDistributedThunk())
13151331
return false;
1332+
if (isBackDeployedThunk())
1333+
return false;
13161334
if (kind == SILDeclRef::Kind::Destroyer ||
13171335
kind == SILDeclRef::Kind::DefaultArgGenerator)
13181336
return false;
@@ -1332,6 +1350,9 @@ bool SILDeclRef::isDynamicallyReplaceable() const {
13321350
if (isDistributedThunk())
13331351
return false;
13341352

1353+
if (isBackDeployedThunk())
1354+
return false;
1355+
13351356
if (kind == SILDeclRef::Kind::DefaultArgGenerator)
13361357
return false;
13371358
if (isStoredPropertyInitializer() || isPropertyWrapperBackingInitializer())

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,7 +1518,8 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Result,
15181518

15191519
if (!P.consumeIf(tok::sil_exclamation)) {
15201520
// Construct SILDeclRef.
1521-
Result = SILDeclRef(VD, Kind, IsObjC, /*distributed=*/false, DerivativeId);
1521+
Result = SILDeclRef(VD, Kind, IsObjC, /*distributed=*/false,
1522+
/*backDeployed=*/false, DerivativeId);
15221523
return false;
15231524
}
15241525

@@ -1638,7 +1639,8 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Result,
16381639
} while (P.consumeIf(tok::period));
16391640

16401641
// Construct SILDeclRef.
1641-
Result = SILDeclRef(VD, Kind, IsObjC, /*distributed=*/false, DerivativeId);
1642+
Result = SILDeclRef(VD, Kind, IsObjC, /*distributed=*/false,
1643+
/*backDeployed=*/false, DerivativeId);
16421644
return false;
16431645
}
16441646

0 commit comments

Comments
 (0)