Skip to content

Commit bf5133d

Browse files
authored
Merge pull request #19485 from jrose-apple/disintegrated
Rework the integrated REPL to use separate modules for every line
2 parents 1974f8d + a9bbaf7 commit bf5133d

23 files changed

+267
-378
lines changed

include/swift/SIL/SILModule.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,9 @@ class SILModule {
343343
/// should contain source files.
344344
///
345345
/// If a source file is provided, SIL will only be emitted for decls in that
346-
/// source file, starting from the specified element number.
346+
/// source file.
347347
static std::unique_ptr<SILModule>
348-
constructSIL(ModuleDecl *M, SILOptions &Options, FileUnit *sf = nullptr,
349-
Optional<unsigned> startElem = None,
350-
bool isWholeModule = false);
348+
constructSIL(ModuleDecl *M, SILOptions &Options, FileUnit *sf = nullptr);
351349

352350
/// \brief Create and return an empty SIL module that we can
353351
/// later parse SIL bodies directly into, without converting from an AST.

include/swift/Subsystems.h

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -237,21 +237,14 @@ namespace swift {
237237

238238
/// Turn the given module into SIL IR.
239239
///
240-
/// The module must contain source files.
241-
///
242-
/// if \p wholeModuleCompilation is true, the optimizer assumes that the SIL
243-
/// of all files in the module is present in the SILModule.
240+
/// The module must contain source files. The optimizer will assume that the
241+
/// SIL of all files in the module is present in the SILModule.
244242
std::unique_ptr<SILModule>
245-
performSILGeneration(ModuleDecl *M, SILOptions &options,
246-
bool wholeModuleCompilation = false);
243+
performSILGeneration(ModuleDecl *M, SILOptions &options);
247244

248245
/// Turn a source file into SIL IR.
249-
///
250-
/// If \p StartElem is provided, the module is assumed to be only part of the
251-
/// SourceFile, and any optimizations should take that into account.
252246
std::unique_ptr<SILModule>
253-
performSILGeneration(FileUnit &SF, SILOptions &options,
254-
Optional<unsigned> StartElem = None);
247+
performSILGeneration(FileUnit &SF, SILOptions &options);
255248

256249
using ModuleOrSourceFile = PointerUnion<ModuleDecl *, SourceFile *>;
257250

@@ -283,7 +276,6 @@ namespace swift {
283276
std::unique_ptr<SILModule> SILMod,
284277
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
285278
llvm::LLVMContext &LLVMContext,
286-
unsigned StartElem = 0,
287279
llvm::GlobalVariable **outModuleHash = nullptr);
288280

289281
/// Given an already created LLVM module, construct a pass pipeline and run

lib/AST/Module.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,12 @@ SourceFile::collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const
13051305
if (next->getName() == getParentModule()->getName())
13061306
return true;
13071307

1308+
// Hack: Assume other REPL files already have their libraries linked.
1309+
if (!next->getFiles().empty())
1310+
if (auto *nextSource = dyn_cast<SourceFile>(next->getFiles().front()))
1311+
if (nextSource->Kind == SourceFileKind::REPL)
1312+
return true;
1313+
13081314
next->collectLinkLibraries(callback);
13091315
return true;
13101316
});

lib/FrontendTool/FrontendTool.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) {
819819
if (!opts.InputsAndOutputs.hasPrimaryInputs()) {
820820
// If there are no primary inputs the compiler is in WMO mode and builds one
821821
// SILModule for the entire module.
822-
auto SM = performSILGeneration(mod, SILOpts, true);
822+
auto SM = performSILGeneration(mod, SILOpts);
823823
std::deque<PostSILGenInputs> PSGIs;
824824
const PrimarySpecificPaths PSPs =
825825
Instance.getPrimarySpecificPathsForWholeModuleOptimizationMode();
@@ -832,7 +832,7 @@ generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) {
832832
// once for each such input.
833833
std::deque<PostSILGenInputs> PSGIs;
834834
for (auto *PrimaryFile : Instance.getPrimarySourceFiles()) {
835-
auto SM = performSILGeneration(*PrimaryFile, SILOpts, None);
835+
auto SM = performSILGeneration(*PrimaryFile, SILOpts);
836836
const PrimarySpecificPaths PSPs =
837837
Instance.getPrimarySpecificPathsForSourceFile(*PrimaryFile);
838838
PSGIs.push_back(PostSILGenInputs{std::move(SM), true, PrimaryFile, PSPs});
@@ -846,7 +846,7 @@ generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) {
846846
if (Invocation.getFrontendOptions().InputsAndOutputs.isInputPrimary(
847847
SASTF->getFilename())) {
848848
assert(PSGIs.empty() && "Can only handle one primary AST input");
849-
auto SM = performSILGeneration(*SASTF, SILOpts, None);
849+
auto SM = performSILGeneration(*SASTF, SILOpts);
850850
const PrimarySpecificPaths &PSPs =
851851
Instance.getPrimarySpecificPathsForPrimary(SASTF->getFilename());
852852
PSGIs.push_back(
@@ -1130,7 +1130,7 @@ static void generateIR(IRGenOptions &IRGenOpts, std::unique_ptr<SILModule> SM,
11301130
IRModule = MSF.is<SourceFile *>()
11311131
? performIRGeneration(IRGenOpts, *MSF.get<SourceFile *>(),
11321132
std::move(SM), OutputFilename, PSPs,
1133-
LLVMContext, 0, &HashGlobal)
1133+
LLVMContext, &HashGlobal)
11341134
: performIRGeneration(IRGenOpts, MSF.get<ModuleDecl *>(),
11351135
std::move(SM), OutputFilename, PSPs,
11361136
LLVMContext, parallelOutputFilenames,

lib/IDE/REPLCodeCompletion.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID,
193193
CodeCompletionCallbacksFactory *CompletionCallbacksFactory) {
194194
// Temporarily disable printing the diagnostics.
195195
ASTContext &Ctx = SF.getASTContext();
196-
auto DiagnosticConsumers = Ctx.Diags.takeConsumers();
196+
DiagnosticTransaction DelayedDiags(Ctx.Diags);
197197

198198
std::string AugmentedCode = EnteredCode.str();
199199
AugmentedCode += '\0';
@@ -206,30 +206,23 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID,
206206
// Parse, typecheck and temporarily insert the incomplete code into the AST.
207207
const unsigned OriginalDeclCount = SF.Decls.size();
208208

209-
unsigned CurElem = OriginalDeclCount;
210209
PersistentParserState PersistentState(Ctx);
211210
std::unique_ptr<DelayedParsingCallbacks> DelayedCB(
212211
new CodeCompleteDelayedCallbacks(Ctx.SourceMgr.getCodeCompletionLoc()));
213212
bool Done;
214213
do {
215214
parseIntoSourceFile(SF, *BufferID, &Done, nullptr, &PersistentState,
216215
DelayedCB.get());
217-
performTypeChecking(SF, PersistentState.getTopLevelContext(), None,
218-
CurElem);
219-
CurElem = SF.Decls.size();
220216
} while (!Done);
217+
performTypeChecking(SF, PersistentState.getTopLevelContext(), None,
218+
OriginalDeclCount);
221219

222220
performDelayedParsing(&SF, PersistentState, CompletionCallbacksFactory);
223221

224222
// Now we are done with code completion. Remove the declarations we
225223
// temporarily inserted.
226224
SF.Decls.resize(OriginalDeclCount);
227-
228-
// Add the diagnostic consumers back.
229-
for (auto DC : DiagnosticConsumers)
230-
Ctx.Diags.addConsumer(*DC);
231-
232-
Ctx.Diags.resetHadAnyError();
225+
DelayedDiags.abort();
233226
}
234227

235228
void REPLCompletions::populate(SourceFile &SF, StringRef EnteredCode) {

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -467,13 +467,13 @@ class PrettySourceFileEmission : public llvm::PrettyStackTraceEntry {
467467
} // end anonymous namespace
468468

469469
/// Emit all the top-level code in the source file.
470-
void IRGenModule::emitSourceFile(SourceFile &SF, unsigned StartElem) {
470+
void IRGenModule::emitSourceFile(SourceFile &SF) {
471471
PrettySourceFileEmission StackEntry(SF);
472472
llvm::SaveAndRestore<SourceFile *> SetCurSourceFile(CurSourceFile, &SF);
473473

474474
// Emit types and other global decls.
475-
for (unsigned i = StartElem, e = SF.Decls.size(); i != e; ++i)
476-
emitGlobalDecl(SF.Decls[i]);
475+
for (auto *decl : SF.Decls)
476+
emitGlobalDecl(decl);
477477
for (auto *localDecl : SF.LocalTypeDecls)
478478
emitGlobalDecl(localDecl);
479479

lib/IRGen/IRGen.cpp

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -762,15 +762,12 @@ static void runIRGenPreparePasses(SILModule &Module,
762762

763763
/// Generates LLVM IR, runs the LLVM passes and produces the output file.
764764
/// All this is done in a single thread.
765-
static std::unique_ptr<llvm::Module> performIRGeneration(IRGenOptions &Opts,
766-
swift::ModuleDecl *M,
767-
std::unique_ptr<SILModule> SILMod,
768-
StringRef ModuleName,
769-
const PrimarySpecificPaths &PSPs,
770-
llvm::LLVMContext &LLVMContext,
771-
SourceFile *SF = nullptr,
772-
llvm::GlobalVariable **outModuleHash = nullptr,
773-
unsigned StartElem = 0) {
765+
static std::unique_ptr<llvm::Module>
766+
performIRGeneration(IRGenOptions &Opts, ModuleDecl *M,
767+
std::unique_ptr<SILModule> SILMod, StringRef ModuleName,
768+
const PrimarySpecificPaths &PSPs,
769+
llvm::LLVMContext &LLVMContext, SourceFile *SF = nullptr,
770+
llvm::GlobalVariable **outModuleHash = nullptr) {
774771
auto &Ctx = M->getASTContext();
775772
assert(!Ctx.hadError());
776773

@@ -795,13 +792,12 @@ static std::unique_ptr<llvm::Module> performIRGeneration(IRGenOptions &Opts,
795792
irgen.emitGlobalTopLevel();
796793

797794
if (SF) {
798-
IGM.emitSourceFile(*SF, StartElem);
795+
IGM.emitSourceFile(*SF);
799796
} else {
800-
assert(StartElem == 0 && "no explicit source file provided");
801797
for (auto *File : M->getFiles()) {
802798
if (auto *nextSF = dyn_cast<SourceFile>(File)) {
803799
if (nextSF->ASTStage >= SourceFile::TypeChecked)
804-
IGM.emitSourceFile(*nextSF, 0);
800+
IGM.emitSourceFile(*nextSF);
805801
} else {
806802
File->collectLinkLibraries([&IGM](LinkLibrary LinkLib) {
807803
IGM.addLinkLibrary(LinkLib);
@@ -972,7 +968,7 @@ static void performParallelIRGeneration(
972968
for (auto *File : M->getFiles()) {
973969
if (auto *SF = dyn_cast<SourceFile>(File)) {
974970
IRGenModule *IGM = irgen.getGenModule(SF);
975-
IGM->emitSourceFile(*SF, 0);
971+
IGM->emitSourceFile(*SF);
976972
} else {
977973
File->collectLinkLibraries([&](LinkLibrary LinkLib) {
978974
irgen.getPrimaryIGM()->addLinkLibrary(LinkLib);
@@ -1116,12 +1112,10 @@ performIRGeneration(IRGenOptions &Opts, SourceFile &SF,
11161112
std::unique_ptr<SILModule> SILMod,
11171113
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
11181114
llvm::LLVMContext &LLVMContext,
1119-
unsigned StartElem,
11201115
llvm::GlobalVariable **outModuleHash) {
1121-
return ::performIRGeneration(Opts, SF.getParentModule(),
1122-
std::move(SILMod), ModuleName,
1123-
PSPs,
1124-
LLVMContext, &SF, outModuleHash, StartElem);
1116+
return ::performIRGeneration(Opts, SF.getParentModule(), std::move(SILMod),
1117+
ModuleName, PSPs, LLVMContext, &SF,
1118+
outModuleHash);
11251119
}
11261120

11271121
void

lib/IRGen/IRGenModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ private: \
10951095

10961096
llvm::LLVMContext &getLLVMContext() const { return LLVMContext; }
10971097

1098-
void emitSourceFile(SourceFile &SF, unsigned StartElem);
1098+
void emitSourceFile(SourceFile &SF);
10991099
void addLinkLibrary(const LinkLibrary &linkLib);
11001100

11011101
/// Attempt to finalize the module.

lib/Immediate/Immediate.cpp

Lines changed: 6 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,8 @@ bool swift::immediate::linkLLVMModules(llvm::Module *Module,
204204
return !Failed;
205205
}
206206

207-
bool swift::immediate::IRGenImportedModules(
208-
CompilerInstance &CI, llvm::Module &Module,
209-
llvm::SmallPtrSetImpl<swift::ModuleDecl *> &ImportedModules,
210-
SmallVectorImpl<llvm::Function *> &InitFns, IRGenOptions &IRGenOpts,
211-
const SILOptions &SILOpts) {
212-
swift::ModuleDecl *M = CI.getMainModule();
213-
207+
bool swift::immediate::autolinkImportedModules(ModuleDecl *M,
208+
IRGenOptions &IRGenOpts) {
214209
// Perform autolinking.
215210
SmallVector<LinkLibrary, 4> AllLinkLibraries(IRGenOpts.LinkLibraries);
216211
auto addLinkLibrary = [&](LinkLibrary linkLib) {
@@ -219,63 +214,9 @@ bool swift::immediate::IRGenImportedModules(
219214

220215
M->collectLinkLibraries(addLinkLibrary);
221216

222-
tryLoadLibraries(AllLinkLibraries, CI.getASTContext().SearchPathOpts,
223-
CI.getDiags());
224-
225-
ImportedModules.insert(M);
226-
if (!CI.hasSourceImport())
227-
return false;
228-
229-
// IRGen the modules this module depends on. This is only really necessary
230-
// for imported source, but that's a very convenient thing to do in -i mode.
231-
// FIXME: Crawling all loaded modules is a hack.
232-
// FIXME: And re-doing SILGen, SIL-linking, SIL diagnostics, and IRGen is
233-
// expensive, because it's not properly being limited to new things right now.
234-
bool hadError = false;
235-
for (auto &entry : CI.getASTContext().LoadedModules) {
236-
swift::ModuleDecl *import = entry.second;
237-
if (!ImportedModules.insert(import).second)
238-
continue;
239-
240-
std::unique_ptr<SILModule> SILMod = performSILGeneration(import,
241-
CI.getSILOptions());
242-
if (runSILDiagnosticPasses(*SILMod)) {
243-
hadError = true;
244-
break;
245-
}
246-
runSILLoweringPasses(*SILMod);
247-
248-
const auto PSPs = CI.getPrimarySpecificPathsForAtMostOnePrimary();
249-
// FIXME: We shouldn't need to use the global context here, but
250-
// something is persisting across calls to performIRGeneration.
251-
auto SubModule = performIRGeneration(
252-
IRGenOpts, import, std::move(SILMod), import->getName().str(), PSPs,
253-
getGlobalLLVMContext(), ArrayRef<std::string>());
254-
255-
if (CI.getASTContext().hadError()) {
256-
hadError = true;
257-
break;
258-
}
259-
260-
if (!linkLLVMModules(&Module, std::move(SubModule)
261-
// TODO: reactivate the linker mode if it is
262-
// supported in llvm again. Otherwise remove the
263-
// commented code completely.
264-
/*, llvm::Linker::DestroySource */)) {
265-
hadError = true;
266-
break;
267-
}
268-
269-
// FIXME: This is an ugly hack; need to figure out how this should
270-
// actually work.
271-
SmallVector<char, 20> NameBuf;
272-
StringRef InitFnName = (import->getName().str() + ".init").toStringRef(NameBuf);
273-
llvm::Function *InitFn = Module.getFunction(InitFnName);
274-
if (InitFn)
275-
InitFns.push_back(InitFn);
276-
}
277-
278-
return hadError;
217+
tryLoadLibraries(AllLinkLibraries, M->getASTContext().SearchPathOpts,
218+
M->getASTContext().Diags);
219+
return false;
279220
}
280221

281222
int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
@@ -330,9 +271,7 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
330271
(*emplaceProcessArgs)(argBuf.data(), CmdLine.size());
331272

332273
SmallVector<llvm::Function*, 8> InitFns;
333-
llvm::SmallPtrSet<swift::ModuleDecl *, 8> ImportedModules;
334-
if (IRGenImportedModules(CI, *Module, ImportedModules, InitFns,
335-
IRGenOpts, SILOpts))
274+
if (autolinkImportedModules(swiftModule, IRGenOpts))
336275
return -1;
337276

338277
llvm::PassManagerBuilder PMBuilder;

lib/Immediate/ImmediateImpl.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,7 @@ bool tryLoadLibraries(ArrayRef<LinkLibrary> LinkLibraries,
4444
DiagnosticEngine &Diags);
4545
bool linkLLVMModules(llvm::Module *Module,
4646
std::unique_ptr<llvm::Module> SubModule);
47-
bool IRGenImportedModules(
48-
CompilerInstance &CI, llvm::Module &Module,
49-
llvm::SmallPtrSetImpl<swift::ModuleDecl *> &ImportedModules,
50-
SmallVectorImpl<llvm::Function *> &InitFns, IRGenOptions &IRGenOpts,
51-
const SILOptions &SILOpts);
47+
bool autolinkImportedModules(ModuleDecl *M, IRGenOptions &IRGenOpts);
5248

5349
} // end namespace immediate
5450
} // end namespace swift

0 commit comments

Comments
 (0)