Skip to content

Commit 5304999

Browse files
committed
Serialize lifetime dependence info on function types as well
1 parent 5f69a2f commit 5304999

13 files changed

+209
-50
lines changed

include/swift/AST/ExtInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,10 @@ class SILExtInfo {
13351335
return builder.withTransferringResult(hasTransferringResult).build();
13361336
}
13371337

1338+
SILExtInfo withLifetimeDependenceInfo(LifetimeDependenceInfo info) const {
1339+
return builder.withLifetimeDependenceInfo(info);
1340+
}
1341+
13381342
void Profile(llvm::FoldingSetNodeID &ID) const { builder.Profile(ID); }
13391343

13401344
bool isEqualTo(SILExtInfo other, bool useClangTypes) const {

include/swift/AST/LifetimeDependence.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ class LifetimeDependenceSpecifier {
132132
class LifetimeDependenceInfo {
133133
IndexSubset *inheritLifetimeParamIndices;
134134
IndexSubset *scopeLifetimeParamIndices;
135+
bool isExplicit;
135136

136137
static LifetimeDependenceInfo getForParamIndex(AbstractFunctionDecl *afd,
137138
unsigned index,
@@ -146,11 +147,18 @@ class LifetimeDependenceInfo {
146147
public:
147148
LifetimeDependenceInfo()
148149
: inheritLifetimeParamIndices(nullptr),
149-
scopeLifetimeParamIndices(nullptr) {}
150+
scopeLifetimeParamIndices(nullptr), isExplicit(false) {}
150151
LifetimeDependenceInfo(IndexSubset *inheritLifetimeParamIndices,
151-
IndexSubset *scopeLifetimeParamIndices)
152+
IndexSubset *scopeLifetimeParamIndices,
153+
bool isExplicit = false)
152154
: inheritLifetimeParamIndices(inheritLifetimeParamIndices),
153-
scopeLifetimeParamIndices(scopeLifetimeParamIndices) {}
155+
scopeLifetimeParamIndices(scopeLifetimeParamIndices),
156+
isExplicit(isExplicit) {
157+
assert(!empty());
158+
assert(!inheritLifetimeParamIndices ||
159+
!inheritLifetimeParamIndices->isEmpty());
160+
assert(!scopeLifetimeParamIndices || !scopeLifetimeParamIndices->isEmpty());
161+
}
154162

155163
operator bool() const { return !empty(); }
156164

@@ -159,6 +167,8 @@ class LifetimeDependenceInfo {
159167
scopeLifetimeParamIndices == nullptr;
160168
}
161169

170+
bool isExplicitlySpecified() const { return isExplicit; }
171+
162172
bool hasInheritLifetimeParamIndices() const {
163173
return inheritLifetimeParamIndices != nullptr;
164174
}

include/swift/AST/Types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3781,6 +3781,9 @@ class FunctionType final
37813781

37823782
/// Returns nullptr for an empty dependence list.
37833783
const LifetimeDependenceInfo *getLifetimeDependenceInfoOrNull() const {
3784+
if (!hasLifetimeDependenceInfo()) {
3785+
return nullptr;
3786+
}
37843787
auto *info = getTrailingObjects<LifetimeDependenceInfo>();
37853788
assert(!info->empty() && "If the LifetimeDependenceInfo was empty, we "
37863789
"shouldn't have stored it.");
@@ -3935,6 +3938,9 @@ class GenericFunctionType final
39353938

39363939
/// Returns nullptr for an empty dependence list.
39373940
const LifetimeDependenceInfo *getLifetimeDependenceInfoOrNull() const {
3941+
if (!hasLifetimeDependenceInfo()) {
3942+
return nullptr;
3943+
}
39383944
auto *info = getTrailingObjects<LifetimeDependenceInfo>();
39393945
assert(!info->empty() && "If the LifetimeDependenceInfo was empty, we "
39403946
"shouldn't have stored it.");

lib/Sema/LifetimeDependence.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
272272
: nullptr,
273273
scopeLifetimeParamIndices.any()
274274
? IndexSubset::get(ctx, scopeLifetimeParamIndices)
275-
: nullptr);
275+
: nullptr,
276+
/*isExplicit*/ true);
276277
}
277278

278279
std::optional<LifetimeDependenceInfo>

lib/Serialization/Deserialization.cpp

Lines changed: 82 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3605,7 +3605,8 @@ class DeclDeserializer {
36053605
ctor->setParameters(bodyParams);
36063606

36073607
SmallVector<LifetimeDependenceSpecifier> specifierList;
3608-
if (MF.maybeReadLifetimeDependence(specifierList, bodyParams->size())) {
3608+
if (MF.maybeReadLifetimeDependenceSpecifier(specifierList,
3609+
bodyParams->size())) {
36093610
auto SelfType = ctor->getDeclaredInterfaceType();
36103611
auto typeRepr = new (ctx) FixedTypeRepr(SelfType, SourceLoc());
36113612
auto lifetimeTypeRepr =
@@ -4174,7 +4175,8 @@ class DeclDeserializer {
41744175
ParameterList *paramList = MF.readParameterList();
41754176
fn->setParameters(paramList);
41764177
SmallVector<LifetimeDependenceSpecifier> specifierList;
4177-
if (MF.maybeReadLifetimeDependence(specifierList, paramList->size())) {
4178+
if (MF.maybeReadLifetimeDependenceSpecifier(specifierList,
4179+
paramList->size())) {
41784180
auto typeRepr = new (ctx) FixedTypeRepr(resultType, SourceLoc());
41794181
auto lifetimeTypeRepr =
41804182
LifetimeDependentReturnTypeRepr::create(ctx, typeRepr, specifierList);
@@ -6849,7 +6851,6 @@ detail::function_deserializer::deserialize(ModuleFile &MF,
68496851
isolation = swift::FunctionTypeIsolation::forGlobalActor(globalActorTy.get());
68506852
}
68516853

6852-
// TODO: Handle LifetimeDependenceInfo here.
68536854
auto info = FunctionType::ExtInfoBuilder(
68546855
*representation, noescape, throws, thrownError, *diffKind,
68556856
clangFunctionType, isolation, LifetimeDependenceInfo(),
@@ -6905,6 +6906,12 @@ detail::function_deserializer::deserialize(ModuleFile &MF,
69056906
MF.getIdentifier(internalLabelID));
69066907
}
69076908

6909+
auto lifetimeDependenceInfo = MF.maybeReadLifetimeDependenceInfo(params.size());
6910+
6911+
if (lifetimeDependenceInfo.has_value()) {
6912+
info = info.withLifetimeDependenceInfo(*lifetimeDependenceInfo);
6913+
}
6914+
69086915
if (!isGeneric) {
69096916
assert(genericSig.isNull());
69106917
return FunctionType::get(params, resultTy.get(), info);
@@ -7382,7 +7389,6 @@ Expected<Type> DESERIALIZE_TYPE(SIL_FUNCTION_TYPE)(
73827389
if (erasedIsolation)
73837390
isolation = SILFunctionTypeIsolation::Erased;
73847391

7385-
// Handle LifetimeDependenceInfo here.
73867392
auto extInfo =
73877393
SILFunctionType::ExtInfoBuilder(
73887394
*representation, pseudogeneric, noescape, concurrent, async,
@@ -7525,6 +7531,13 @@ Expected<Type> DESERIALIZE_TYPE(SIL_FUNCTION_TYPE)(
75257531
if (!patternSubsOrErr)
75267532
return patternSubsOrErr.takeError();
75277533

7534+
auto lifetimeDependenceInfo = MF.maybeReadLifetimeDependenceInfo(
7535+
extInfo.hasSelfParam() ? numParams : numParams + 1);
7536+
7537+
if (lifetimeDependenceInfo.has_value()) {
7538+
extInfo = extInfo.withLifetimeDependenceInfo(*lifetimeDependenceInfo);
7539+
}
7540+
75287541
return SILFunctionType::get(invocationSig, extInfo, coroutineKind.value(),
75297542
calleeConvention.value(), allParams, allYields,
75307543
allResults, errorResult,
@@ -8685,11 +8698,9 @@ ModuleFile::maybeReadForeignAsyncConvention() {
86858698
errorFlagPolarity);
86868699
}
86878700

8688-
bool ModuleFile::maybeReadLifetimeDependence(
8689-
SmallVectorImpl<LifetimeDependenceSpecifier> &specifierList,
8690-
unsigned numParams) {
8701+
bool ModuleFile::maybeReadLifetimeDependenceRecord(
8702+
SmallVectorImpl<uint64_t> &scratch) {
86918703
using namespace decls_block;
8692-
SmallVector<uint64_t, 8> scratch;
86938704

86948705
BCOffsetRAII restoreOffset(DeclTypeCursor);
86958706

@@ -8709,22 +8720,82 @@ bool ModuleFile::maybeReadLifetimeDependence(
87098720
return false;
87108721
}
87118722

8712-
bool hasInheritLifetimeParamIndices, hasScopeLifetimeParamIndices;
8723+
return true;
8724+
}
8725+
8726+
std::optional<LifetimeDependenceInfo>
8727+
ModuleFile::maybeReadLifetimeDependenceInfo(unsigned numParams) {
8728+
using namespace decls_block;
8729+
8730+
SmallVector<uint64_t, 8> scratch;
8731+
if (!maybeReadLifetimeDependenceRecord(scratch)) {
8732+
return std::nullopt;
8733+
}
8734+
8735+
bool hasInheritLifetimeParamIndices;
8736+
bool hasScopeLifetimeParamIndices;
8737+
ArrayRef<uint64_t> lifetimeDependenceData;
8738+
LifetimeDependenceLayout::readRecord(scratch, hasInheritLifetimeParamIndices,
8739+
hasScopeLifetimeParamIndices,
8740+
lifetimeDependenceData);
8741+
8742+
SmallBitVector inheritLifetimeParamIndices(numParams, false);
8743+
SmallBitVector scopeLifetimeParamIndices(numParams, false);
8744+
8745+
unsigned startIndex = 0;
8746+
auto pushData = [&](SmallBitVector &bits) {
8747+
for (unsigned i = 0; i < numParams; i++) {
8748+
if (lifetimeDependenceData[startIndex + i]) {
8749+
bits.set(i);
8750+
}
8751+
}
8752+
startIndex += numParams;
8753+
};
8754+
8755+
if (hasInheritLifetimeParamIndices) {
8756+
pushData(inheritLifetimeParamIndices);
8757+
}
8758+
if (hasScopeLifetimeParamIndices) {
8759+
pushData(scopeLifetimeParamIndices);
8760+
}
8761+
8762+
ASTContext &ctx = getContext();
8763+
return LifetimeDependenceInfo(
8764+
hasInheritLifetimeParamIndices
8765+
? IndexSubset::get(ctx, inheritLifetimeParamIndices)
8766+
: nullptr,
8767+
hasScopeLifetimeParamIndices
8768+
? IndexSubset::get(ctx, scopeLifetimeParamIndices)
8769+
: nullptr);
8770+
}
8771+
8772+
bool ModuleFile::maybeReadLifetimeDependenceSpecifier(
8773+
SmallVectorImpl<LifetimeDependenceSpecifier> &specifierList,
8774+
unsigned numDeclParams) {
8775+
using namespace decls_block;
8776+
8777+
SmallVector<uint64_t, 8> scratch;
8778+
if (!maybeReadLifetimeDependenceRecord(scratch)) {
8779+
return false;
8780+
}
8781+
8782+
bool hasInheritLifetimeParamIndices;
8783+
bool hasScopeLifetimeParamIndices;
87138784
ArrayRef<uint64_t> lifetimeDependenceData;
87148785
LifetimeDependenceLayout::readRecord(scratch, hasInheritLifetimeParamIndices,
87158786
hasScopeLifetimeParamIndices,
87168787
lifetimeDependenceData);
87178788

87188789
unsigned startIndex = 0;
87198790
auto pushData = [&](LifetimeDependenceKind kind) {
8720-
for (unsigned i = 0; i < numParams + 1; i++) {
8791+
for (unsigned i = 0; i < numDeclParams + 1; i++) {
87218792
if (lifetimeDependenceData[startIndex + i]) {
87228793
specifierList.push_back(
87238794
LifetimeDependenceSpecifier::getOrderedLifetimeDependenceSpecifier(
87248795
SourceLoc(), kind, i));
87258796
}
87268797
}
8727-
startIndex += numParams + 1;
8798+
startIndex += numDeclParams + 1;
87288799
};
87298800

87308801
if (hasInheritLifetimeParamIndices) {

lib/Serialization/ModuleFile.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,9 +1063,16 @@ class ModuleFile
10631063
/// Reads a foreign async convention from \c DeclTypeCursor, if present.
10641064
std::optional<ForeignAsyncConvention> maybeReadForeignAsyncConvention();
10651065

1066-
bool maybeReadLifetimeDependence(
1066+
bool maybeReadLifetimeDependenceRecord(SmallVectorImpl<uint64_t> &scratch);
1067+
1068+
// Reads lifetime dependence info from type if present.
1069+
std::optional<LifetimeDependenceInfo>
1070+
maybeReadLifetimeDependenceInfo(unsigned numParams);
1071+
1072+
// Reads lifetime dependence specifier from decl if present
1073+
bool maybeReadLifetimeDependenceSpecifier(
10671074
SmallVectorImpl<LifetimeDependenceSpecifier> &specifierList,
1068-
unsigned numParams);
1075+
unsigned numDeclParams);
10691076

10701077
/// Reads inlinable body text from \c DeclTypeCursor, if present.
10711078
std::optional<StringRef> maybeReadInlinableBodyText();

lib/Serialization/ModuleFormat.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 858; // Replace inherited types with protocols in protocol layout
61+
const uint16_t SWIFTMODULE_VERSION_MINOR =
62+
859; // add lifetime dependence info in type serialization as well.
6263

6364
/// A standard hash seed used for all string hashes in a serialized module.
6465
///
@@ -1234,6 +1235,7 @@ namespace decls_block {
12341235
FunctionTypeIsolationField, // isolation
12351236
BCFixed<1> // has transferring result
12361237
// trailed by parameters
1238+
// Optionally lifetime dependence info
12371239
);
12381240

12391241
using FunctionParamLayout =
@@ -1335,6 +1337,7 @@ namespace decls_block {
13351337
GenericSignatureIDField // generic signature
13361338

13371339
// trailed by parameters
1340+
// Optionally lifetime dependence info
13381341
);
13391342

13401343
TYPE_LAYOUT(SILFunctionTypeLayout,
@@ -1363,6 +1366,7 @@ namespace decls_block {
13631366
// followed by error result type/convention
13641367
// Optionally a protocol conformance (for witness_methods)
13651368
// Optionally a substitution map (for substituted function types)
1369+
// Optionally lifetime dependence info
13661370
);
13671371

13681372
TYPE_LAYOUT(SILBlockStorageTypeLayout,

0 commit comments

Comments
 (0)