diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h index a1e15c82654..395de845f6e 100644 --- a/include/swift/Frontend/Frontend.h +++ b/include/swift/Frontend/Frontend.h @@ -55,6 +55,10 @@ class SerializedModuleLoader; class MemoryBufferSerializedModuleLoader; class SILModule; +namespace Lowering { +class TypeConverter; +} + /// The abstract configuration of the compiler, including: /// - options for all stages of translation, /// - information about the build environment, @@ -372,6 +376,7 @@ class CompilerInstance { SourceManager SourceMgr; DiagnosticEngine Diagnostics{SourceMgr}; std::unique_ptr Context; + std::unique_ptr TheSILTypes; std::unique_ptr TheSILModule; std::unique_ptr PersistentState; @@ -422,8 +427,6 @@ class CompilerInstance { bool isWholeModuleCompilation() { return PrimaryBufferIDs.empty(); } - void createSILModule(); - public: // Out of line to avoid having to import SILModule.h. CompilerInstance(); @@ -448,6 +451,10 @@ public: SILOptions &getSILOptions() { return Invocation.getSILOptions(); } const SILOptions &getSILOptions() const { return Invocation.getSILOptions(); } + Lowering::TypeConverter &getSILTypes(); + + void createSILModule(); + void addDiagnosticConsumer(DiagnosticConsumer *DC) { Diagnostics.addConsumer(*DC); } diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h index 089e3d07596..802bb85041b 100644 --- a/include/swift/SIL/SILModule.h +++ b/include/swift/SIL/SILModule.h @@ -260,7 +260,8 @@ private: // Intentionally marked private so that we need to use 'constructSIL()' // to construct a SILModule. - SILModule(ModuleDecl *M, SILOptions &Options, const DeclContext *associatedDC, + SILModule(ModuleDecl *M, Lowering::TypeConverter &TC, + SILOptions &Options, const DeclContext *associatedDC, bool wholeModule); SILModule(const SILModule&) = delete; @@ -313,7 +314,7 @@ public: void serialize(); /// This converts Swift types to SILTypes. - mutable Lowering::TypeConverter Types; + Lowering::TypeConverter &Types; /// Invalidate cached entries in SIL Loader. void invalidateSILLoaderCaches(); @@ -340,12 +341,14 @@ public: /// If a source file is provided, SIL will only be emitted for decls in that /// source file. static std::unique_ptr - constructSIL(ModuleDecl *M, SILOptions &Options, FileUnit *sf = nullptr); + constructSIL(ModuleDecl *M, Lowering::TypeConverter &TC, + SILOptions &Options, FileUnit *sf = nullptr); /// Create and return an empty SIL module that we can /// later parse SIL bodies directly into, without converting from an AST. static std::unique_ptr - createEmptyModule(ModuleDecl *M, SILOptions &Options, + createEmptyModule(ModuleDecl *M, Lowering::TypeConverter &TC, + SILOptions &Options, bool WholeModule = false); /// Get the Swift module associated with this SIL module. diff --git a/include/swift/Subsystems.h b/include/swift/Subsystems.h index d2ce73b6f14..c9784cbf066 100644 --- a/include/swift/Subsystems.h +++ b/include/swift/Subsystems.h @@ -69,6 +69,10 @@ namespace swift { class UnifiedStatsReporter; enum class SourceFileKind; + namespace Lowering { + class TypeConverter; + } + /// Used to optionally maintain SIL parsing context for the parser. /// /// When not parsing SIL, this has no overhead. @@ -254,11 +258,13 @@ namespace swift { /// The module must contain source files. The optimizer will assume that the /// SIL of all files in the module is present in the SILModule. std::unique_ptr - performSILGeneration(ModuleDecl *M, SILOptions &options); + performSILGeneration(ModuleDecl *M, Lowering::TypeConverter &TC, + SILOptions &options); /// Turn a source file into SIL IR. std::unique_ptr - performSILGeneration(FileUnit &SF, SILOptions &options); + performSILGeneration(FileUnit &SF, Lowering::TypeConverter &TC, + SILOptions &options); using ModuleOrSourceFile = PointerUnion; diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index fffc5ed5171..0571a76fce4 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -148,11 +148,20 @@ SerializationOptions CompilerInvocation::computeSerializationOptions( return serializationOpts; } +Lowering::TypeConverter &CompilerInstance::getSILTypes() { + if (auto *tc = TheSILTypes.get()) + return *tc; + + auto *tc = new Lowering::TypeConverter(*getMainModule()); + TheSILTypes.reset(tc); + return *tc; +} + void CompilerInstance::createSILModule() { assert(MainModule && "main module not created yet"); // Assume WMO if a -primary-file option was not provided. TheSILModule = SILModule::createEmptyModule( - getMainModule(), Invocation.getSILOptions(), + getMainModule(), getSILTypes(), Invocation.getSILOptions(), Invocation.getFrontendOptions().InputsAndOutputs.isWholeModule()); } @@ -1074,6 +1083,7 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals, void CompilerInstance::freeASTContext() { PersistentState.reset(); + TheSILTypes.reset(); Context.reset(); MainModule = nullptr; SML = nullptr; diff --git a/lib/Frontend/ParseableInterfaceModuleLoader.cpp b/lib/Frontend/ParseableInterfaceModuleLoader.cpp index 36e960c077b..be93b99a4cb 100644 --- a/lib/Frontend/ParseableInterfaceModuleLoader.cpp +++ b/lib/Frontend/ParseableInterfaceModuleLoader.cpp @@ -592,7 +592,8 @@ public: SILOptions &SILOpts = subInvocation.getSILOptions(); auto Mod = SubInstance.getMainModule(); - auto SILMod = performSILGeneration(Mod, SILOpts); + auto &TC = SubInstance.getSILTypes(); + auto SILMod = performSILGeneration(Mod, TC, SILOpts); if (!SILMod) { LLVM_DEBUG(llvm::dbgs() << "SILGen did not produce a module\n"); SubError = true; diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index d60866ee490..8f921df7e83 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -917,7 +917,7 @@ generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) { if (!opts.InputsAndOutputs.hasPrimaryInputs()) { // If there are no primary inputs the compiler is in WMO mode and builds one // SILModule for the entire module. - auto SM = performSILGeneration(mod, SILOpts); + auto SM = performSILGeneration(mod, Instance.getSILTypes(), SILOpts); std::deque PSGIs; const PrimarySpecificPaths PSPs = Instance.getPrimarySpecificPathsForWholeModuleOptimizationMode(); @@ -930,7 +930,7 @@ generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) { // once for each such input. std::deque PSGIs; for (auto *PrimaryFile : Instance.getPrimarySourceFiles()) { - auto SM = performSILGeneration(*PrimaryFile, SILOpts); + auto SM = performSILGeneration(*PrimaryFile, Instance.getSILTypes(), SILOpts); const PrimarySpecificPaths PSPs = Instance.getPrimarySpecificPathsForSourceFile(*PrimaryFile); PSGIs.push_back(PostSILGenInputs{std::move(SM), true, PrimaryFile, PSPs}); @@ -944,7 +944,7 @@ generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) { if (Invocation.getFrontendOptions().InputsAndOutputs.isInputPrimary( SASTF->getFilename())) { assert(PSGIs.empty() && "Can only handle one primary AST input"); - auto SM = performSILGeneration(*SASTF, SILOpts); + auto SM = performSILGeneration(*SASTF, Instance.getSILTypes(), SILOpts); const PrimarySpecificPaths &PSPs = Instance.getPrimarySpecificPathsForPrimary(SASTF->getFilename()); PSGIs.push_back( diff --git a/lib/Immediate/REPL.cpp b/lib/Immediate/REPL.cpp index 0ae6644162d..5d55c9f633c 100644 --- a/lib/Immediate/REPL.cpp +++ b/lib/Immediate/REPL.cpp @@ -874,7 +874,8 @@ private: if (!CI.getASTContext().hadError()) { // We don't want anything to get stripped, so pretend we're doing a // non-whole-module generation. - sil = performSILGeneration(*M->getFiles().front(), CI.getSILOptions()); + sil = performSILGeneration(*M->getFiles().front(), CI.getSILTypes(), + CI.getSILOptions()); runSILDiagnosticPasses(*sil); runSILOwnershipEliminatorPass(*sil); runSILLoweringPasses(*sil); diff --git a/lib/RemoteAST/RemoteAST.cpp b/lib/RemoteAST/RemoteAST.cpp index 506ec914ca4..ef02e490f8b 100644 --- a/lib/RemoteAST/RemoteAST.cpp +++ b/lib/RemoteAST/RemoteAST.cpp @@ -61,6 +61,7 @@ namespace { struct IRGenContext { IRGenOptions IROpts; SILOptions SILOpts; + Lowering::TypeConverter TC; std::unique_ptr SILMod; llvm::LLVMContext LLVMContext; irgen::IRGenerator IRGen; @@ -69,7 +70,8 @@ struct IRGenContext { private: IRGenContext(ASTContext &ctx, ModuleDecl *module) : IROpts(createIRGenOptions()), - SILMod(SILModule::createEmptyModule(module, SILOpts)), + TC(*module), + SILMod(SILModule::createEmptyModule(module, TC, SILOpts)), IRGen(IROpts, *SILMod), IGM(IRGen, IRGen.createTargetMachine(), LLVMContext) {} diff --git a/lib/SIL/SILModule.cpp b/lib/SIL/SILModule.cpp index 76d224fc318..c6723e0b206 100644 --- a/lib/SIL/SILModule.cpp +++ b/lib/SIL/SILModule.cpp @@ -89,11 +89,13 @@ class SILModule::SerializationCallback final } }; -SILModule::SILModule(ModuleDecl *SwiftModule, SILOptions &Options, - const DeclContext *associatedDC, bool wholeModule) - : TheSwiftModule(SwiftModule), AssociatedDeclContext(associatedDC), +SILModule::SILModule(ModuleDecl *SwiftModule, TypeConverter &TC, + SILOptions &Options, const DeclContext *associatedDC, + bool wholeModule) + : TheSwiftModule(SwiftModule), + AssociatedDeclContext(associatedDC), Stage(SILStage::Raw), wholeModule(wholeModule), Options(Options), - serialized(false), SerializeSILAction(), Types(*SwiftModule) { + serialized(false), SerializeSILAction(), Types(TC) { // We always add the base SILModule serialization callback. std::unique_ptr callback( new SILModule::SerializationCallback()); @@ -118,10 +120,10 @@ SILModule::~SILModule() { } std::unique_ptr -SILModule::createEmptyModule(ModuleDecl *M, SILOptions &Options, +SILModule::createEmptyModule(ModuleDecl *M, TypeConverter &TC, SILOptions &Options, bool WholeModule) { return std::unique_ptr( - new SILModule(M, Options, M, WholeModule)); + new SILModule(M, TC, Options, M, WholeModule)); } ASTContext &SILModule::getASTContext() const { diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index e3dc128e087..c384666ac90 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -1662,7 +1662,8 @@ void SILGenModule::emitSourceFile(SourceFile *sf) { //===----------------------------------------------------------------------===// std::unique_ptr -SILModule::constructSIL(ModuleDecl *mod, SILOptions &options, FileUnit *SF) { +SILModule::constructSIL(ModuleDecl *mod, TypeConverter &tc, + SILOptions &options, FileUnit *SF) { SharedTimer timer("SILGen"); const DeclContext *DC; if (SF) { @@ -1672,7 +1673,7 @@ SILModule::constructSIL(ModuleDecl *mod, SILOptions &options, FileUnit *SF) { } std::unique_ptr M( - new SILModule(mod, options, DC, /*wholeModule*/ SF == nullptr)); + new SILModule(mod, tc, options, DC, /*wholeModule*/ SF == nullptr)); SILGenModule SGM(*M, mod); if (SF) { @@ -1721,11 +1722,13 @@ SILModule::constructSIL(ModuleDecl *mod, SILOptions &options, FileUnit *SF) { } std::unique_ptr -swift::performSILGeneration(ModuleDecl *mod, SILOptions &options) { - return SILModule::constructSIL(mod, options, nullptr); +swift::performSILGeneration(ModuleDecl *mod, Lowering::TypeConverter &tc, + SILOptions &options) { + return SILModule::constructSIL(mod, tc, options, nullptr); } std::unique_ptr -swift::performSILGeneration(FileUnit &sf, SILOptions &options) { - return SILModule::constructSIL(sf.getParentModule(), options, &sf); +swift::performSILGeneration(FileUnit &sf, Lowering::TypeConverter &tc, + SILOptions &options) { + return SILModule::constructSIL(sf.getParentModule(), tc, options, &sf); } diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp index 0ae7f8f68e9..230f055d450 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp @@ -1000,7 +1000,8 @@ ASTUnitRef ASTProducer::createASTUnit( if (auto SF = CompIns.getPrimarySourceFile()) { SILOptions SILOpts = Invocation.getSILOptions(); - std::unique_ptr SILMod = performSILGeneration(*SF, SILOpts); + auto &TC = CompIns.getSILTypes(); + std::unique_ptr SILMod = performSILGeneration(*SF, TC, SILOpts); runSILDiagnosticPasses(*SILMod); } } diff --git a/tools/driver/modulewrap_main.cpp b/tools/driver/modulewrap_main.cpp index bf871732043..886d7a62fba 100644 --- a/tools/driver/modulewrap_main.cpp +++ b/tools/driver/modulewrap_main.cpp @@ -24,6 +24,7 @@ #include "swift/Option/Options.h" #include "swift/Serialization/Validation.h" #include "swift/SIL/SILModule.h" +#include "swift/SIL/TypeLowering.h" #include "swift/Subsystems.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Bitcode/BitstreamReader.h" @@ -177,7 +178,8 @@ int modulewrap_main(ArrayRef Args, const char *Argv0, true); ModuleDecl *M = ModuleDecl::create(ASTCtx.getIdentifier("swiftmodule"), ASTCtx); SILOptions SILOpts; - std::unique_ptr SM = SILModule::createEmptyModule(M, SILOpts); + std::unique_ptr TC(new Lowering::TypeConverter(*M)); + std::unique_ptr SM = SILModule::createEmptyModule(M, *TC, SILOpts); createSwiftModuleObjectFile(*SM, (*ErrOrBuf)->getBuffer(), Invocation.getOutputFilename()); return 0; diff --git a/tools/sil-func-extractor/SILFunctionExtractor.cpp b/tools/sil-func-extractor/SILFunctionExtractor.cpp index c2d878b1cc6..7c04d529c33 100644 --- a/tools/sil-func-extractor/SILFunctionExtractor.cpp +++ b/tools/sil-func-extractor/SILFunctionExtractor.cpp @@ -277,8 +277,7 @@ int main(int argc, char **argv) { if (Invocation.hasSerializedAST()) { assert(!CI.hasSILModule() && "performSema() should not create a SILModule."); - CI.setSILModule( - SILModule::createEmptyModule(CI.getMainModule(), CI.getSILOptions())); + CI.createSILModule(); std::unique_ptr SL = SerializedSILLoader::create( CI.getASTContext(), CI.getSILModule(), nullptr); diff --git a/tools/sil-llvm-gen/SILLLVMGen.cpp b/tools/sil-llvm-gen/SILLLVMGen.cpp index e3fd63c679f..a8df48d756e 100644 --- a/tools/sil-llvm-gen/SILLLVMGen.cpp +++ b/tools/sil-llvm-gen/SILLLVMGen.cpp @@ -189,8 +189,7 @@ int main(int argc, char **argv) { if (Invocation.hasSerializedAST()) { assert(!CI.hasSILModule() && "performSema() should not create a SILModule."); - CI.setSILModule(SILModule::createEmptyModule( - CI.getMainModule(), CI.getSILOptions(), PerformWMO)); + CI.createSILModule(); std::unique_ptr SL = SerializedSILLoader::create( CI.getASTContext(), CI.getSILModule(), nullptr); diff --git a/tools/sil-nm/SILNM.cpp b/tools/sil-nm/SILNM.cpp index 3b1a6ed501a..04c754faebb 100644 --- a/tools/sil-nm/SILNM.cpp +++ b/tools/sil-nm/SILNM.cpp @@ -191,8 +191,7 @@ int main(int argc, char **argv) { if (Invocation.hasSerializedAST()) { assert(!CI.hasSILModule() && "performSema() should not create a SILModule."); - CI.setSILModule( - SILModule::createEmptyModule(CI.getMainModule(), CI.getSILOptions())); + CI.createSILModule(); std::unique_ptr SL = SerializedSILLoader::create( CI.getASTContext(), CI.getSILModule(), nullptr); diff --git a/tools/sil-opt/SILOpt.cpp b/tools/sil-opt/SILOpt.cpp index 9561e5cd5bc..90c9260c760 100644 --- a/tools/sil-opt/SILOpt.cpp +++ b/tools/sil-opt/SILOpt.cpp @@ -389,8 +389,7 @@ int main(int argc, char **argv) { if (Invocation.hasSerializedAST()) { assert(!CI.hasSILModule() && "performSema() should not create a SILModule."); - CI.setSILModule(SILModule::createEmptyModule( - CI.getMainModule(), CI.getSILOptions(), PerformWMO)); + CI.createSILModule(); std::unique_ptr SL = SerializedSILLoader::create( CI.getASTContext(), CI.getSILModule(), nullptr);