Skip to content

Commit eb84095

Browse files
committed
Serialize lifetime dependence info on function types as well
1 parent 6c05584 commit eb84095

13 files changed

+219
-50
lines changed

include/swift/AST/ExtInfo.h

+4
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

+13-3
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

+6
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

+2-1
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

+86-11
Original file line numberDiff line numberDiff line change
@@ -3590,7 +3590,8 @@ class DeclDeserializer {
35903590
ctor->setParameters(bodyParams);
35913591

35923592
SmallVector<LifetimeDependenceSpecifier> specifierList;
3593-
if (MF.maybeReadLifetimeDependence(specifierList, bodyParams->size())) {
3593+
if (MF.maybeReadLifetimeDependenceSpecifier(specifierList,
3594+
bodyParams->size())) {
35943595
auto SelfType = ctor->getDeclaredInterfaceType();
35953596
auto typeRepr = new (ctx) FixedTypeRepr(SelfType, SourceLoc());
35963597
auto lifetimeTypeRepr =
@@ -4159,7 +4160,8 @@ class DeclDeserializer {
41594160
ParameterList *paramList = MF.readParameterList();
41604161
fn->setParameters(paramList);
41614162
SmallVector<LifetimeDependenceSpecifier> specifierList;
4162-
if (MF.maybeReadLifetimeDependence(specifierList, paramList->size())) {
4163+
if (MF.maybeReadLifetimeDependenceSpecifier(specifierList,
4164+
paramList->size())) {
41634165
auto typeRepr = new (ctx) FixedTypeRepr(resultType, SourceLoc());
41644166
auto lifetimeTypeRepr =
41654167
LifetimeDependentReturnTypeRepr::create(ctx, typeRepr, specifierList);
@@ -6851,7 +6853,6 @@ detail::function_deserializer::deserialize(ModuleFile &MF,
68516853
isolation = swift::FunctionTypeIsolation::forGlobalActor(globalActorTy.get());
68526854
}
68536855

6854-
// TODO: Handle LifetimeDependenceInfo here.
68556856
auto info = FunctionType::ExtInfoBuilder(
68566857
*representation, noescape, throws, thrownError, *diffKind,
68576858
clangFunctionType, isolation, LifetimeDependenceInfo(),
@@ -6866,6 +6867,7 @@ detail::function_deserializer::deserialize(ModuleFile &MF,
68666867

68676868
SmallVector<AnyFunctionType::Param, 8> params;
68686869
while (true) {
6870+
BCOffsetRAII restoreOffset(MF.DeclTypeCursor);
68696871
llvm::BitstreamEntry entry =
68706872
MF.fatalIfUnexpected(MF.DeclTypeCursor.advance(AF_DontPopBlockAtEnd));
68716873
if (entry.Kind != llvm::BitstreamEntry::Record)
@@ -6877,6 +6879,8 @@ detail::function_deserializer::deserialize(ModuleFile &MF,
68776879
if (recordID != decls_block::FUNCTION_PARAM)
68786880
break;
68796881

6882+
restoreOffset.reset();
6883+
68806884
IdentifierID labelID;
68816885
IdentifierID internalLabelID;
68826886
TypeID typeID;
@@ -6907,6 +6911,13 @@ detail::function_deserializer::deserialize(ModuleFile &MF,
69076911
MF.getIdentifier(internalLabelID));
69086912
}
69096913

6914+
auto lifetimeDependenceInfo =
6915+
MF.maybeReadLifetimeDependenceInfo(params.size());
6916+
6917+
if (lifetimeDependenceInfo.has_value()) {
6918+
info = info.withLifetimeDependenceInfo(*lifetimeDependenceInfo);
6919+
}
6920+
69106921
if (!isGeneric) {
69116922
assert(genericSig.isNull());
69126923
return FunctionType::get(params, resultTy.get(), info);
@@ -7384,7 +7395,6 @@ Expected<Type> DESERIALIZE_TYPE(SIL_FUNCTION_TYPE)(
73847395
if (erasedIsolation)
73857396
isolation = SILFunctionTypeIsolation::Erased;
73867397

7387-
// Handle LifetimeDependenceInfo here.
73887398
auto extInfo =
73897399
SILFunctionType::ExtInfoBuilder(
73907400
*representation, pseudogeneric, noescape, concurrent, async,
@@ -7527,6 +7537,13 @@ Expected<Type> DESERIALIZE_TYPE(SIL_FUNCTION_TYPE)(
75277537
if (!patternSubsOrErr)
75287538
return patternSubsOrErr.takeError();
75297539

7540+
auto lifetimeDependenceInfo = MF.maybeReadLifetimeDependenceInfo(
7541+
extInfo.hasSelfParam() ? numParams : numParams + 1);
7542+
7543+
if (lifetimeDependenceInfo.has_value()) {
7544+
extInfo = extInfo.withLifetimeDependenceInfo(*lifetimeDependenceInfo);
7545+
}
7546+
75307547
return SILFunctionType::get(invocationSig, extInfo, coroutineKind.value(),
75317548
calleeConvention.value(), allParams, allYields,
75327549
allResults, errorResult,
@@ -8687,11 +8704,9 @@ ModuleFile::maybeReadForeignAsyncConvention() {
86878704
errorFlagPolarity);
86888705
}
86898706

8690-
bool ModuleFile::maybeReadLifetimeDependence(
8691-
SmallVectorImpl<LifetimeDependenceSpecifier> &specifierList,
8692-
unsigned numParams) {
8707+
bool ModuleFile::maybeReadLifetimeDependenceRecord(
8708+
SmallVectorImpl<uint64_t> &scratch) {
86938709
using namespace decls_block;
8694-
SmallVector<uint64_t, 8> scratch;
86958710

86968711
BCOffsetRAII restoreOffset(DeclTypeCursor);
86978712

@@ -8711,22 +8726,82 @@ bool ModuleFile::maybeReadLifetimeDependence(
87118726
return false;
87128727
}
87138728

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

87208795
unsigned startIndex = 0;
87218796
auto pushData = [&](LifetimeDependenceKind kind) {
8722-
for (unsigned i = 0; i < numParams + 1; i++) {
8797+
for (unsigned i = 0; i < numDeclParams + 1; i++) {
87238798
if (lifetimeDependenceData[startIndex + i]) {
87248799
specifierList.push_back(
87258800
LifetimeDependenceSpecifier::getOrderedLifetimeDependenceSpecifier(
87268801
SourceLoc(), kind, i));
87278802
}
87288803
}
8729-
startIndex += numParams + 1;
8804+
startIndex += numDeclParams + 1;
87308805
};
87318806

87328807
if (hasInheritLifetimeParamIndices) {

lib/Serialization/ModuleFile.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -1067,9 +1067,16 @@ class ModuleFile
10671067
/// Reads a foreign async convention from \c DeclTypeCursor, if present.
10681068
std::optional<ForeignAsyncConvention> maybeReadForeignAsyncConvention();
10691069

1070-
bool maybeReadLifetimeDependence(
1070+
bool maybeReadLifetimeDependenceRecord(SmallVectorImpl<uint64_t> &scratch);
1071+
1072+
// Reads lifetime dependence info from type if present.
1073+
std::optional<LifetimeDependenceInfo>
1074+
maybeReadLifetimeDependenceInfo(unsigned numParams);
1075+
1076+
// Reads lifetime dependence specifier from decl if present
1077+
bool maybeReadLifetimeDependenceSpecifier(
10711078
SmallVectorImpl<LifetimeDependenceSpecifier> &specifierList,
1072-
unsigned numParams);
1079+
unsigned numDeclParams);
10731080

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

lib/Serialization/ModuleFormat.h

+5-1
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 = 861; // AllowNonResilientAccess
61+
const uint16_t SWIFTMODULE_VERSION_MINOR =
62+
862; // 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
///
@@ -1245,6 +1246,7 @@ namespace decls_block {
12451246
FunctionTypeIsolationField, // isolation
12461247
BCFixed<1> // has transferring result
12471248
// trailed by parameters
1249+
// Optionally lifetime dependence info
12481250
);
12491251

12501252
using FunctionParamLayout =
@@ -1346,6 +1348,7 @@ namespace decls_block {
13461348
GenericSignatureIDField // generic signature
13471349

13481350
// trailed by parameters
1351+
// Optionally lifetime dependence info
13491352
);
13501353

13511354
TYPE_LAYOUT(SILFunctionTypeLayout,
@@ -1374,6 +1377,7 @@ namespace decls_block {
13741377
// followed by error result type/convention
13751378
// Optionally a protocol conformance (for witness_methods)
13761379
// Optionally a substitution map (for substituted function types)
1380+
// Optionally lifetime dependence info
13771381
);
13781382

13791383
TYPE_LAYOUT(SILBlockStorageTypeLayout,

0 commit comments

Comments
 (0)