mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
SIL: Share TypeConverter between SILModules in batch mode
This commit is contained in:
@@ -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<ASTContext> Context;
|
||||
std::unique_ptr<Lowering::TypeConverter> TheSILTypes;
|
||||
std::unique_ptr<SILModule> TheSILModule;
|
||||
|
||||
std::unique_ptr<PersistentParserState> 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);
|
||||
}
|
||||
|
||||
@@ -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<SILModule>
|
||||
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<SILModule>
|
||||
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.
|
||||
|
||||
@@ -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<SILModule>
|
||||
performSILGeneration(ModuleDecl *M, SILOptions &options);
|
||||
performSILGeneration(ModuleDecl *M, Lowering::TypeConverter &TC,
|
||||
SILOptions &options);
|
||||
|
||||
/// Turn a source file into SIL IR.
|
||||
std::unique_ptr<SILModule>
|
||||
performSILGeneration(FileUnit &SF, SILOptions &options);
|
||||
performSILGeneration(FileUnit &SF, Lowering::TypeConverter &TC,
|
||||
SILOptions &options);
|
||||
|
||||
using ModuleOrSourceFile = PointerUnion<ModuleDecl *, SourceFile *>;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<PostSILGenInputs> PSGIs;
|
||||
const PrimarySpecificPaths PSPs =
|
||||
Instance.getPrimarySpecificPathsForWholeModuleOptimizationMode();
|
||||
@@ -930,7 +930,7 @@ generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) {
|
||||
// once for each such input.
|
||||
std::deque<PostSILGenInputs> 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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace {
|
||||
struct IRGenContext {
|
||||
IRGenOptions IROpts;
|
||||
SILOptions SILOpts;
|
||||
Lowering::TypeConverter TC;
|
||||
std::unique_ptr<SILModule> 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) {}
|
||||
|
||||
|
||||
@@ -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<DeserializationNotificationHandler> callback(
|
||||
new SILModule::SerializationCallback());
|
||||
@@ -118,10 +120,10 @@ SILModule::~SILModule() {
|
||||
}
|
||||
|
||||
std::unique_ptr<SILModule>
|
||||
SILModule::createEmptyModule(ModuleDecl *M, SILOptions &Options,
|
||||
SILModule::createEmptyModule(ModuleDecl *M, TypeConverter &TC, SILOptions &Options,
|
||||
bool WholeModule) {
|
||||
return std::unique_ptr<SILModule>(
|
||||
new SILModule(M, Options, M, WholeModule));
|
||||
new SILModule(M, TC, Options, M, WholeModule));
|
||||
}
|
||||
|
||||
ASTContext &SILModule::getASTContext() const {
|
||||
|
||||
@@ -1662,7 +1662,8 @@ void SILGenModule::emitSourceFile(SourceFile *sf) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
std::unique_ptr<SILModule>
|
||||
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<SILModule> 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<SILModule>
|
||||
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<SILModule>
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1000,7 +1000,8 @@ ASTUnitRef ASTProducer::createASTUnit(
|
||||
|
||||
if (auto SF = CompIns.getPrimarySourceFile()) {
|
||||
SILOptions SILOpts = Invocation.getSILOptions();
|
||||
std::unique_ptr<SILModule> SILMod = performSILGeneration(*SF, SILOpts);
|
||||
auto &TC = CompIns.getSILTypes();
|
||||
std::unique_ptr<SILModule> SILMod = performSILGeneration(*SF, TC, SILOpts);
|
||||
runSILDiagnosticPasses(*SILMod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<const char *> Args, const char *Argv0,
|
||||
true);
|
||||
ModuleDecl *M = ModuleDecl::create(ASTCtx.getIdentifier("swiftmodule"), ASTCtx);
|
||||
SILOptions SILOpts;
|
||||
std::unique_ptr<SILModule> SM = SILModule::createEmptyModule(M, SILOpts);
|
||||
std::unique_ptr<Lowering::TypeConverter> TC(new Lowering::TypeConverter(*M));
|
||||
std::unique_ptr<SILModule> SM = SILModule::createEmptyModule(M, *TC, SILOpts);
|
||||
createSwiftModuleObjectFile(*SM, (*ErrOrBuf)->getBuffer(),
|
||||
Invocation.getOutputFilename());
|
||||
return 0;
|
||||
|
||||
@@ -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<SerializedSILLoader> SL = SerializedSILLoader::create(
|
||||
CI.getASTContext(), CI.getSILModule(), nullptr);
|
||||
|
||||
|
||||
@@ -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<SerializedSILLoader> SL = SerializedSILLoader::create(
|
||||
CI.getASTContext(), CI.getSILModule(), nullptr);
|
||||
|
||||
|
||||
@@ -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<SerializedSILLoader> SL = SerializedSILLoader::create(
|
||||
CI.getASTContext(), CI.getSILModule(), nullptr);
|
||||
|
||||
|
||||
@@ -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<SerializedSILLoader> SL = SerializedSILLoader::create(
|
||||
CI.getASTContext(), CI.getSILModule(), nullptr);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user