Skip to content

Commit 10fd090

Browse files
authored
Merge pull request swiftlang#6609 from DougGregor/sil-generic-env-serialization
2 parents 8c01531 + 69cc9f4 commit 10fd090

File tree

9 files changed

+65
-76
lines changed

9 files changed

+65
-76
lines changed

include/swift/Serialization/DeclTypeRecordNodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ OTHER(GENERIC_PARAM_LIST, 240)
164164
TRAILING_INFO(GENERIC_PARAM)
165165
TRAILING_INFO(GENERIC_REQUIREMENT)
166166
OTHER(GENERIC_ENVIRONMENT, 243)
167-
TRAILING_INFO(SIL_GENERIC_ENVIRONMENT)
167+
OTHER(SIL_GENERIC_ENVIRONMENT, 244)
168168

169169
OTHER(LOCAL_DISCRIMINATOR, 248)
170170
OTHER(PRIVATE_DISCRIMINATOR, 249)

include/swift/Serialization/ModuleFile.h

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,17 @@ class ModuleFile : public LazyMemberLoader {
529529
serialization::DeclID willSet,
530530
serialization::DeclID didSet);
531531

532+
/// Return the generic signature or environment at the current position in
533+
/// the given cursor.
534+
///
535+
/// \param cursor The cursor to read from.
536+
/// \param wantEnvironment Whether we always want to receive a generic
537+
/// environment vs. being able to handle the generic signature.
538+
llvm::PointerUnion<GenericSignature *, GenericEnvironment *>
539+
readGenericSignatureOrEnvironment(
540+
llvm::BitstreamCursor &cursor,
541+
bool wantEnvironment);
542+
532543
public:
533544
/// Loads a module from the given memory buffer.
534545
///
@@ -741,20 +752,6 @@ class ModuleFile : public LazyMemberLoader {
741752
/// is loaded instead.
742753
Module *getModule(ArrayRef<Identifier> name);
743754

744-
/// Return the generic signature or environment at the current position in
745-
/// the given cursor.
746-
///
747-
/// \param cursor The cursor to read from.
748-
/// \param wantEnvironment Whether we always want to receive a generic
749-
/// environment vs. being able to handle the generic signature.
750-
/// \param optRequirements If not \c None, use these generic requirements
751-
/// rather than deserializing requirements.
752-
llvm::PointerUnion<GenericSignature *, GenericEnvironment *>
753-
readGenericSignatureOrEnvironment(
754-
llvm::BitstreamCursor &cursor,
755-
bool wantEnvironment,
756-
Optional<ArrayRef<Requirement>> optRequirements);
757-
758755
/// Returns the generic signature or environment for the given ID,
759756
/// deserializing it if needed.
760757
///

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
5454
/// in source control, you should also update the comment to briefly
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
57-
const uint16_t VERSION_MINOR = 302; // Last change: SIL box type substitutions
57+
const uint16_t VERSION_MINOR = 303; // Last change: SIL generic environments
5858

5959
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6060
using DeclIDField = BCFixed<31>;

lib/Serialization/Deserialization.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -967,8 +967,7 @@ void ModuleFile::configureGenericEnvironment(
967967
llvm::PointerUnion<GenericSignature *, GenericEnvironment *>
968968
ModuleFile::readGenericSignatureOrEnvironment(
969969
llvm::BitstreamCursor &cursor,
970-
bool wantEnvironment,
971-
Optional<ArrayRef<Requirement>> optRequirements) {
970+
bool wantEnvironment) {
972971
using namespace decls_block;
973972

974973
SmallVector<uint64_t, 8> scratch;
@@ -1068,14 +1067,8 @@ ModuleFile::readGenericSignatureOrEnvironment(
10681067
}
10691068

10701069
// Read the generic requirements.
1071-
ArrayRef<Requirement> requirements;
1072-
SmallVector<Requirement, 4> requirementsVec;
1073-
if (optRequirements) {
1074-
requirements = *optRequirements;
1075-
} else {
1076-
readGenericRequirements(requirementsVec, cursor);
1077-
requirements = requirementsVec;
1078-
}
1070+
SmallVector<Requirement, 4> requirements;
1071+
readGenericRequirements(requirements, cursor);
10791072

10801073
// Construct the generic signature from the loaded parameters and
10811074
// requirements.
@@ -1113,15 +1106,20 @@ ModuleFile::getGenericSignatureOrEnvironment(
11131106
// Read the generic environment.
11141107
BCOffsetRAII restoreOffset(DeclTypeCursor);
11151108
DeclTypeCursor.JumpToBit(envOrOffset);
1109+
DeserializingEntityRAII deserializingEntity(*this);
11161110

11171111
auto result = readGenericSignatureOrEnvironment(DeclTypeCursor,
1118-
wantEnvironment,
1119-
None);
1112+
wantEnvironment);
11201113
if (result.isNull()) {
11211114
envOrOffset = nullptr;
11221115
return envOrOffset.get();
11231116
}
11241117

1118+
// If we've already deserialized this generic environment, return it.
1119+
if (envOrOffset.isComplete()) {
1120+
return envOrOffset.get();
1121+
}
1122+
11251123
if (auto signature = result.dyn_cast<GenericSignature *>()) {
11261124
assert(!wantEnvironment && "Reader should have produced the environment");
11271125
return signature;

lib/Serialization/DeserializeSIL.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -379,14 +379,15 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID,
379379

380380
DeclID clangNodeOwnerID;
381381
TypeID funcTyID;
382+
GenericEnvironmentID genericEnvID;
382383
unsigned rawLinkage, isTransparent, isFragile, isThunk, isGlobal,
383384
inlineStrategy, effect, numSpecAttrs, hasQualifiedOwnership;
384385
ArrayRef<uint64_t> SemanticsIDs;
385386
// TODO: read fragile
386387
SILFunctionLayout::readRecord(scratch, rawLinkage, isTransparent, isFragile,
387388
isThunk, isGlobal, inlineStrategy, effect,
388389
numSpecAttrs, hasQualifiedOwnership, funcTyID,
389-
clangNodeOwnerID, SemanticsIDs);
390+
genericEnvID, clangNodeOwnerID, SemanticsIDs);
390391

391392
if (funcTyID == 0) {
392393
DEBUG(llvm::dbgs() << "SILFunction typeID is 0.\n");
@@ -491,15 +492,8 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID,
491492
}
492493

493494
GenericEnvironment *genericEnv = nullptr;
494-
if (!declarationOnly) {
495-
auto signature = fn->getLoweredFunctionType()->getGenericSignature();
496-
genericEnv = MF->readGenericSignatureOrEnvironment(
497-
SILCursor,
498-
/*wantEnvironment=*/true,
499-
signature ? signature->getRequirements()
500-
: ArrayRef<Requirement>())
501-
.get<GenericEnvironment *>();
502-
}
495+
if (!declarationOnly)
496+
genericEnv = MF->getGenericEnvironment(genericEnvID);
503497

504498
// If the next entry is the end of the block, then this function has
505499
// no contents.
@@ -2001,13 +1995,14 @@ bool SILDeserializer::hasSILFunction(StringRef Name,
20011995
// linkage to avoid re-reading it from the bitcode each time?
20021996
DeclID clangOwnerID;
20031997
TypeID funcTyID;
1998+
GenericEnvironmentID genericEnvID;
20041999
unsigned rawLinkage, isTransparent, isFragile, isThunk, isGlobal,
20052000
inlineStrategy, effect, numSpecAttrs, hasQualifiedOwnership;
20062001
ArrayRef<uint64_t> SemanticsIDs;
20072002
SILFunctionLayout::readRecord(scratch, rawLinkage, isTransparent, isFragile,
20082003
isThunk, isGlobal, inlineStrategy, effect,
20092004
numSpecAttrs, hasQualifiedOwnership, funcTyID,
2010-
clangOwnerID, SemanticsIDs);
2005+
genericEnvID, clangOwnerID, SemanticsIDs);
20112006
auto linkage = fromStableSILLinkage(rawLinkage);
20122007
if (!linkage) {
20132008
DEBUG(llvm::dbgs() << "invalid linkage code " << rawLinkage

lib/Serialization/SILFormat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ namespace sil_block {
247247
BCFixed<2>, // number of specialize attributes
248248
BCFixed<1>, // has qualified ownership
249249
TypeIDField, // SILFunctionType
250+
GenericEnvironmentIDField,
250251
DeclIDField, // ClangNode owner
251252
BCArray<IdentifierIDField> // Semantics Attribute
252253
// followed by specialize attributes

lib/Serialization/Serialization.cpp

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -556,8 +556,6 @@ void Serializer::writeBlockInfoBlock() {
556556
decls_block::GENERIC_PARAM);
557557
BLOCK_RECORD_WITH_NAMESPACE(sil_block,
558558
decls_block::GENERIC_REQUIREMENT);
559-
BLOCK_RECORD_WITH_NAMESPACE(sil_block,
560-
decls_block::SIL_GENERIC_ENVIRONMENT);
561559

562560
BLOCK(SIL_INDEX_BLOCK);
563561
BLOCK_RECORD(sil_index_block, SIL_FUNC_NAMES);
@@ -1011,25 +1009,32 @@ bool Serializer::writeGenericParams(const GenericParamList *genericParams) {
10111009
return true;
10121010
}
10131011

1014-
void Serializer::writeGenericEnvironment(
1015-
const GenericEnvironment *env,
1016-
const std::array<unsigned, 256> &abbrCodes,
1017-
bool SILMode) {
1012+
void Serializer::writeGenericEnvironment(const GenericEnvironment *env) {
10181013
using namespace decls_block;
10191014

10201015
// Record the offset of this generic environment.
1021-
if (!SILMode) {
1022-
auto id = GenericEnvironmentIDs[env];
1023-
assert(id != 0 && "generic environment not referenced properly");
1024-
(void)id;
1016+
auto id = GenericEnvironmentIDs[env];
1017+
assert(id != 0 && "generic environment not referenced properly");
1018+
(void)id;
10251019

1026-
assert((id - 1) == GenericEnvironmentOffsets.size());
1027-
GenericEnvironmentOffsets.push_back(Out.GetCurrentBitNo());
1028-
}
1020+
assert((id - 1) == GenericEnvironmentOffsets.size());
1021+
GenericEnvironmentOffsets.push_back(Out.GetCurrentBitNo());
10291022

10301023
if (env == nullptr)
10311024
return;
10321025

1026+
// Determine whether we must use SIL mode, because one of the generic
1027+
// parameters has a declaration with module context.
1028+
bool SILMode = false;
1029+
for (auto *paramTy : env->getGenericParams()) {
1030+
if (auto *decl = paramTy->getDecl()) {
1031+
if (decl->getDeclContext()->isModuleScopeContext()) {
1032+
SILMode = true;
1033+
break;
1034+
}
1035+
}
1036+
}
1037+
10331038
// Record the generic parameters.
10341039
SmallVector<uint64_t, 4> rawParamIDs;
10351040
for (auto *paramTy : env->getGenericParams()) {
@@ -1050,20 +1055,17 @@ void Serializer::writeGenericEnvironment(
10501055
}
10511056

10521057
if (SILMode) {
1053-
assert(&abbrCodes != &DeclTypeAbbrCodes);
1054-
auto envAbbrCode = abbrCodes[SILGenericEnvironmentLayout::Code];
1058+
auto envAbbrCode = DeclTypeAbbrCodes[SILGenericEnvironmentLayout::Code];
10551059
SILGenericEnvironmentLayout::emitRecord(Out, ScratchRecord, envAbbrCode,
10561060
rawParamIDs);
1057-
return;
1061+
} else {
1062+
auto envAbbrCode = DeclTypeAbbrCodes[GenericEnvironmentLayout::Code];
1063+
GenericEnvironmentLayout::emitRecord(Out, ScratchRecord, envAbbrCode,
1064+
rawParamIDs);
10581065
}
10591066

1060-
assert(&abbrCodes == &DeclTypeAbbrCodes);
1061-
auto envAbbrCode = abbrCodes[GenericEnvironmentLayout::Code];
1062-
GenericEnvironmentLayout::emitRecord(Out, ScratchRecord, envAbbrCode,
1063-
rawParamIDs);
1064-
10651067
writeGenericRequirements(env->getGenericSignature()->getRequirements(),
1066-
abbrCodes);
1068+
DeclTypeAbbrCodes);
10671069
}
10681070

10691071
void Serializer::writeSILLayout(SILLayout *layout) {
@@ -3437,6 +3439,7 @@ void Serializer::writeAllDeclsAndTypes() {
34373439
registerDeclTypeAbbr<GenericParamLayout>();
34383440
registerDeclTypeAbbr<GenericRequirementLayout>();
34393441
registerDeclTypeAbbr<GenericEnvironmentLayout>();
3442+
registerDeclTypeAbbr<SILGenericEnvironmentLayout>();
34403443

34413444
registerDeclTypeAbbr<ForeignErrorConventionLayout>();
34423445
registerDeclTypeAbbr<DeclContextLayout>();
@@ -3498,7 +3501,7 @@ void Serializer::writeAllDeclsAndTypes() {
34983501
while (!GenericEnvironmentsToWrite.empty()) {
34993502
auto next = GenericEnvironmentsToWrite.front();
35003503
GenericEnvironmentsToWrite.pop();
3501-
writeGenericEnvironment(next, DeclTypeAbbrCodes, /*SILMode=*/false);
3504+
writeGenericEnvironment(next);
35023505
}
35033506

35043507
while (!NormalConformancesToWrite.empty()) {

lib/Serialization/Serialization.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,9 @@ class Serializer {
338338
/// Writes the given type.
339339
void writeType(Type ty);
340340

341+
/// Writes a generic environment.
342+
void writeGenericEnvironment(const GenericEnvironment *env);
343+
341344
/// Registers the abbreviation for the given decl or type layout.
342345
template <typename Layout>
343346
void registerDeclTypeAbbr() {
@@ -471,11 +474,6 @@ class Serializer {
471474
void writeConformance(ProtocolConformance *conformance,
472475
const std::array<unsigned, 256> &abbrCodes,
473476
GenericEnvironment *genericEnv = nullptr);
474-
475-
/// Writes a generic environment.
476-
void writeGenericEnvironment(const GenericEnvironment *env,
477-
const std::array<unsigned, 256> &abbrCodes,
478-
bool SILMode);
479477
};
480478
} // end namespace serialization
481479
} // end namespace swift

lib/Serialization/SerializeSIL.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,11 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) {
348348
Linkage = addExternalToLinkage(Linkage);
349349
}
350350

351+
// If we have a body, we might have a generic environment.
352+
GenericEnvironmentID genericEnvID = 0;
353+
if (!F.isExternalDeclaration())
354+
genericEnvID = S.addGenericEnvironmentRef(F.getGenericEnvironment());
355+
351356
DeclID clangNodeOwnerID;
352357
if (F.hasClangNode())
353358
clangNodeOwnerID = S.addDeclRef(F.getClangNodeOwner());
@@ -359,7 +364,7 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) {
359364
(unsigned)F.isThunk(), (unsigned)F.isGlobalInit(),
360365
(unsigned)F.getInlineStrategy(), (unsigned)F.getEffectsKind(),
361366
(unsigned)numSpecAttrs, (unsigned)F.hasQualifiedOwnership(), FnID,
362-
clangNodeOwnerID, SemanticsIDs);
367+
genericEnvID, clangNodeOwnerID, SemanticsIDs);
363368

364369
if (NoBody)
365370
return;
@@ -373,12 +378,6 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) {
373378
S.writeSubstitutions(subs, SILAbbrCodes);
374379
}
375380

376-
// Write the body's context archetypes, unless we don't actually have a body.
377-
if (!F.isExternalDeclaration()) {
378-
if (auto genericEnv = F.getGenericEnvironment())
379-
S.writeGenericEnvironment(genericEnv, SILAbbrCodes, true);
380-
}
381-
382381
// Assign a unique ID to each basic block of the SILFunction.
383382
unsigned BasicID = 0;
384383
BasicBlockMap.clear();
@@ -1918,8 +1917,6 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
19181917
registerSILAbbr<decls_block::NormalProtocolConformanceIdLayout>();
19191918
registerSILAbbr<decls_block::ProtocolConformanceXrefLayout>();
19201919
registerSILAbbr<decls_block::GenericRequirementLayout>();
1921-
registerSILAbbr<decls_block::GenericEnvironmentLayout>();
1922-
registerSILAbbr<decls_block::SILGenericEnvironmentLayout>();
19231920

19241921
for (const SILGlobalVariable &g : SILMod->getSILGlobals())
19251922
writeSILGlobalVar(g);

0 commit comments

Comments
 (0)