From 153ef7dbcbd20e7d7e442e76ffe8b7eb67f58459 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 5 Jan 2017 16:06:03 -0800 Subject: [PATCH 1/2] [Sema] Remove unused variable. --- lib/Sema/MiscDiagnostics.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index 1ef1b1562120e..ce92a9e8e4690 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -519,7 +519,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E, // Add fix-it to insert '()', only if this is a metatype of // non-existential type and has any initializers. - auto eTy = E->getType(); bool isExistential = false; if (auto metaTy = E->getType()->getAs()) { auto instanceTy = metaTy->getInstanceType(); From 69cc9f4b54492639a915e4aaf8faa2caee87db5d Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 5 Jan 2017 18:24:55 -0800 Subject: [PATCH 2/2] [Serialization] Unique SIL generic environments when serializing. Teach the serialization of SIL generic environments, which used to be a trailing record following the SIL function definition, to use the same uniqued "generic environment IDs" that are used for the AST generic environments. Many of them overlap anyway, and SIL functions tend to have AST generic environments anyway. This approach guarantees that the AST + SIL deserialization provide the same uniqueness of generic environments present prior to serialization. --- .../Serialization/DeclTypeRecordNodes.def | 2 +- include/swift/Serialization/ModuleFile.h | 25 +++++----- include/swift/Serialization/ModuleFormat.h | 2 +- lib/Serialization/Deserialization.cpp | 22 ++++----- lib/Serialization/DeserializeSIL.cpp | 17 +++---- lib/Serialization/SILFormat.h | 1 + lib/Serialization/Serialization.cpp | 49 ++++++++++--------- lib/Serialization/Serialization.h | 8 ++- lib/Serialization/SerializeSIL.cpp | 15 +++--- 9 files changed, 65 insertions(+), 76 deletions(-) diff --git a/include/swift/Serialization/DeclTypeRecordNodes.def b/include/swift/Serialization/DeclTypeRecordNodes.def index a9a99c62c4164..6a1001cbe3fe7 100644 --- a/include/swift/Serialization/DeclTypeRecordNodes.def +++ b/include/swift/Serialization/DeclTypeRecordNodes.def @@ -164,7 +164,7 @@ OTHER(GENERIC_PARAM_LIST, 240) TRAILING_INFO(GENERIC_PARAM) TRAILING_INFO(GENERIC_REQUIREMENT) OTHER(GENERIC_ENVIRONMENT, 243) -TRAILING_INFO(SIL_GENERIC_ENVIRONMENT) +OTHER(SIL_GENERIC_ENVIRONMENT, 244) OTHER(LOCAL_DISCRIMINATOR, 248) OTHER(PRIVATE_DISCRIMINATOR, 249) diff --git a/include/swift/Serialization/ModuleFile.h b/include/swift/Serialization/ModuleFile.h index e645e28c02a95..77d0b79b48b90 100644 --- a/include/swift/Serialization/ModuleFile.h +++ b/include/swift/Serialization/ModuleFile.h @@ -529,6 +529,17 @@ class ModuleFile : public LazyMemberLoader { serialization::DeclID willSet, serialization::DeclID didSet); + /// Return the generic signature or environment at the current position in + /// the given cursor. + /// + /// \param cursor The cursor to read from. + /// \param wantEnvironment Whether we always want to receive a generic + /// environment vs. being able to handle the generic signature. + llvm::PointerUnion + readGenericSignatureOrEnvironment( + llvm::BitstreamCursor &cursor, + bool wantEnvironment); + public: /// Loads a module from the given memory buffer. /// @@ -741,20 +752,6 @@ class ModuleFile : public LazyMemberLoader { /// is loaded instead. Module *getModule(ArrayRef name); - /// Return the generic signature or environment at the current position in - /// the given cursor. - /// - /// \param cursor The cursor to read from. - /// \param wantEnvironment Whether we always want to receive a generic - /// environment vs. being able to handle the generic signature. - /// \param optRequirements If not \c None, use these generic requirements - /// rather than deserializing requirements. - llvm::PointerUnion - readGenericSignatureOrEnvironment( - llvm::BitstreamCursor &cursor, - bool wantEnvironment, - Optional> optRequirements); - /// Returns the generic signature or environment for the given ID, /// deserializing it if needed. /// diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h index 23aa9271fccee..54a20c3b32600 100644 --- a/include/swift/Serialization/ModuleFormat.h +++ b/include/swift/Serialization/ModuleFormat.h @@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0; /// in source control, you should also update the comment to briefly /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. -const uint16_t VERSION_MINOR = 302; // Last change: SIL box type substitutions +const uint16_t VERSION_MINOR = 303; // Last change: SIL generic environments using DeclID = PointerEmbeddedInt; using DeclIDField = BCFixed<31>; diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 67635e3ab303e..de263dbb936c9 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -967,8 +967,7 @@ void ModuleFile::configureGenericEnvironment( llvm::PointerUnion ModuleFile::readGenericSignatureOrEnvironment( llvm::BitstreamCursor &cursor, - bool wantEnvironment, - Optional> optRequirements) { + bool wantEnvironment) { using namespace decls_block; SmallVector scratch; @@ -1068,14 +1067,8 @@ ModuleFile::readGenericSignatureOrEnvironment( } // Read the generic requirements. - ArrayRef requirements; - SmallVector requirementsVec; - if (optRequirements) { - requirements = *optRequirements; - } else { - readGenericRequirements(requirementsVec, cursor); - requirements = requirementsVec; - } + SmallVector requirements; + readGenericRequirements(requirements, cursor); // Construct the generic signature from the loaded parameters and // requirements. @@ -1113,15 +1106,20 @@ ModuleFile::getGenericSignatureOrEnvironment( // Read the generic environment. BCOffsetRAII restoreOffset(DeclTypeCursor); DeclTypeCursor.JumpToBit(envOrOffset); + DeserializingEntityRAII deserializingEntity(*this); auto result = readGenericSignatureOrEnvironment(DeclTypeCursor, - wantEnvironment, - None); + wantEnvironment); if (result.isNull()) { envOrOffset = nullptr; return envOrOffset.get(); } + // If we've already deserialized this generic environment, return it. + if (envOrOffset.isComplete()) { + return envOrOffset.get(); + } + if (auto signature = result.dyn_cast()) { assert(!wantEnvironment && "Reader should have produced the environment"); return signature; diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp index ad5a9f0e134a9..70a054d6411c4 100644 --- a/lib/Serialization/DeserializeSIL.cpp +++ b/lib/Serialization/DeserializeSIL.cpp @@ -379,6 +379,7 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID, DeclID clangNodeOwnerID; TypeID funcTyID; + GenericEnvironmentID genericEnvID; unsigned rawLinkage, isTransparent, isFragile, isThunk, isGlobal, inlineStrategy, effect, numSpecAttrs, hasQualifiedOwnership; ArrayRef SemanticsIDs; @@ -386,7 +387,7 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID, SILFunctionLayout::readRecord(scratch, rawLinkage, isTransparent, isFragile, isThunk, isGlobal, inlineStrategy, effect, numSpecAttrs, hasQualifiedOwnership, funcTyID, - clangNodeOwnerID, SemanticsIDs); + genericEnvID, clangNodeOwnerID, SemanticsIDs); if (funcTyID == 0) { DEBUG(llvm::dbgs() << "SILFunction typeID is 0.\n"); @@ -491,15 +492,8 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID, } GenericEnvironment *genericEnv = nullptr; - if (!declarationOnly) { - auto signature = fn->getLoweredFunctionType()->getGenericSignature(); - genericEnv = MF->readGenericSignatureOrEnvironment( - SILCursor, - /*wantEnvironment=*/true, - signature ? signature->getRequirements() - : ArrayRef()) - .get(); - } + if (!declarationOnly) + genericEnv = MF->getGenericEnvironment(genericEnvID); // If the next entry is the end of the block, then this function has // no contents. @@ -2001,13 +1995,14 @@ bool SILDeserializer::hasSILFunction(StringRef Name, // linkage to avoid re-reading it from the bitcode each time? DeclID clangOwnerID; TypeID funcTyID; + GenericEnvironmentID genericEnvID; unsigned rawLinkage, isTransparent, isFragile, isThunk, isGlobal, inlineStrategy, effect, numSpecAttrs, hasQualifiedOwnership; ArrayRef SemanticsIDs; SILFunctionLayout::readRecord(scratch, rawLinkage, isTransparent, isFragile, isThunk, isGlobal, inlineStrategy, effect, numSpecAttrs, hasQualifiedOwnership, funcTyID, - clangOwnerID, SemanticsIDs); + genericEnvID, clangOwnerID, SemanticsIDs); auto linkage = fromStableSILLinkage(rawLinkage); if (!linkage) { DEBUG(llvm::dbgs() << "invalid linkage code " << rawLinkage diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h index 8cd27f7d5748e..da73899b19dba 100644 --- a/lib/Serialization/SILFormat.h +++ b/lib/Serialization/SILFormat.h @@ -247,6 +247,7 @@ namespace sil_block { BCFixed<2>, // number of specialize attributes BCFixed<1>, // has qualified ownership TypeIDField, // SILFunctionType + GenericEnvironmentIDField, DeclIDField, // ClangNode owner BCArray // Semantics Attribute // followed by specialize attributes diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 7ee6206c9fc48..0cb5363a8f59c 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -556,8 +556,6 @@ void Serializer::writeBlockInfoBlock() { decls_block::GENERIC_PARAM); BLOCK_RECORD_WITH_NAMESPACE(sil_block, decls_block::GENERIC_REQUIREMENT); - BLOCK_RECORD_WITH_NAMESPACE(sil_block, - decls_block::SIL_GENERIC_ENVIRONMENT); BLOCK(SIL_INDEX_BLOCK); BLOCK_RECORD(sil_index_block, SIL_FUNC_NAMES); @@ -1011,25 +1009,32 @@ bool Serializer::writeGenericParams(const GenericParamList *genericParams) { return true; } -void Serializer::writeGenericEnvironment( - const GenericEnvironment *env, - const std::array &abbrCodes, - bool SILMode) { +void Serializer::writeGenericEnvironment(const GenericEnvironment *env) { using namespace decls_block; // Record the offset of this generic environment. - if (!SILMode) { - auto id = GenericEnvironmentIDs[env]; - assert(id != 0 && "generic environment not referenced properly"); - (void)id; + auto id = GenericEnvironmentIDs[env]; + assert(id != 0 && "generic environment not referenced properly"); + (void)id; - assert((id - 1) == GenericEnvironmentOffsets.size()); - GenericEnvironmentOffsets.push_back(Out.GetCurrentBitNo()); - } + assert((id - 1) == GenericEnvironmentOffsets.size()); + GenericEnvironmentOffsets.push_back(Out.GetCurrentBitNo()); if (env == nullptr) return; + // Determine whether we must use SIL mode, because one of the generic + // parameters has a declaration with module context. + bool SILMode = false; + for (auto *paramTy : env->getGenericParams()) { + if (auto *decl = paramTy->getDecl()) { + if (decl->getDeclContext()->isModuleScopeContext()) { + SILMode = true; + break; + } + } + } + // Record the generic parameters. SmallVector rawParamIDs; for (auto *paramTy : env->getGenericParams()) { @@ -1050,20 +1055,17 @@ void Serializer::writeGenericEnvironment( } if (SILMode) { - assert(&abbrCodes != &DeclTypeAbbrCodes); - auto envAbbrCode = abbrCodes[SILGenericEnvironmentLayout::Code]; + auto envAbbrCode = DeclTypeAbbrCodes[SILGenericEnvironmentLayout::Code]; SILGenericEnvironmentLayout::emitRecord(Out, ScratchRecord, envAbbrCode, rawParamIDs); - return; + } else { + auto envAbbrCode = DeclTypeAbbrCodes[GenericEnvironmentLayout::Code]; + GenericEnvironmentLayout::emitRecord(Out, ScratchRecord, envAbbrCode, + rawParamIDs); } - assert(&abbrCodes == &DeclTypeAbbrCodes); - auto envAbbrCode = abbrCodes[GenericEnvironmentLayout::Code]; - GenericEnvironmentLayout::emitRecord(Out, ScratchRecord, envAbbrCode, - rawParamIDs); - writeGenericRequirements(env->getGenericSignature()->getRequirements(), - abbrCodes); + DeclTypeAbbrCodes); } void Serializer::writeSILLayout(SILLayout *layout) { @@ -3437,6 +3439,7 @@ void Serializer::writeAllDeclsAndTypes() { registerDeclTypeAbbr(); registerDeclTypeAbbr(); registerDeclTypeAbbr(); + registerDeclTypeAbbr(); registerDeclTypeAbbr(); registerDeclTypeAbbr(); @@ -3498,7 +3501,7 @@ void Serializer::writeAllDeclsAndTypes() { while (!GenericEnvironmentsToWrite.empty()) { auto next = GenericEnvironmentsToWrite.front(); GenericEnvironmentsToWrite.pop(); - writeGenericEnvironment(next, DeclTypeAbbrCodes, /*SILMode=*/false); + writeGenericEnvironment(next); } while (!NormalConformancesToWrite.empty()) { diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h index f8ae314c19eb8..c688f9d1c904b 100644 --- a/lib/Serialization/Serialization.h +++ b/lib/Serialization/Serialization.h @@ -338,6 +338,9 @@ class Serializer { /// Writes the given type. void writeType(Type ty); + /// Writes a generic environment. + void writeGenericEnvironment(const GenericEnvironment *env); + /// Registers the abbreviation for the given decl or type layout. template void registerDeclTypeAbbr() { @@ -471,11 +474,6 @@ class Serializer { void writeConformance(ProtocolConformance *conformance, const std::array &abbrCodes, GenericEnvironment *genericEnv = nullptr); - - /// Writes a generic environment. - void writeGenericEnvironment(const GenericEnvironment *env, - const std::array &abbrCodes, - bool SILMode); }; } // end namespace serialization } // end namespace swift diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index 13f05db4610b2..e457884ba4d91 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -348,6 +348,11 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { Linkage = addExternalToLinkage(Linkage); } + // If we have a body, we might have a generic environment. + GenericEnvironmentID genericEnvID = 0; + if (!F.isExternalDeclaration()) + genericEnvID = S.addGenericEnvironmentRef(F.getGenericEnvironment()); + DeclID clangNodeOwnerID; if (F.hasClangNode()) clangNodeOwnerID = S.addDeclRef(F.getClangNodeOwner()); @@ -359,7 +364,7 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { (unsigned)F.isThunk(), (unsigned)F.isGlobalInit(), (unsigned)F.getInlineStrategy(), (unsigned)F.getEffectsKind(), (unsigned)numSpecAttrs, (unsigned)F.hasQualifiedOwnership(), FnID, - clangNodeOwnerID, SemanticsIDs); + genericEnvID, clangNodeOwnerID, SemanticsIDs); if (NoBody) return; @@ -373,12 +378,6 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { S.writeSubstitutions(subs, SILAbbrCodes); } - // Write the body's context archetypes, unless we don't actually have a body. - if (!F.isExternalDeclaration()) { - if (auto genericEnv = F.getGenericEnvironment()) - S.writeGenericEnvironment(genericEnv, SILAbbrCodes, true); - } - // Assign a unique ID to each basic block of the SILFunction. unsigned BasicID = 0; BasicBlockMap.clear(); @@ -1918,8 +1917,6 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { registerSILAbbr(); registerSILAbbr(); registerSILAbbr(); - registerSILAbbr(); - registerSILAbbr(); for (const SILGlobalVariable &g : SILMod->getSILGlobals()) writeSILGlobalVar(g);