Skip to content

Commit 98d3a81

Browse files
authored
Merge pull request swiftlang#31609 from hamishknight/ill-sil-you-in-later
2 parents 00ff1c3 + 70abfd3 commit 98d3a81

File tree

15 files changed

+202
-179
lines changed

15 files changed

+202
-179
lines changed

include/swift/AST/SILGenRequests.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void reportEvaluatedRequest(UnifiedStatsReporter &stats,
4141
const Request &request);
4242

4343
struct SILGenDescriptor {
44-
llvm::PointerUnion<ModuleDecl *, FileUnit *> context;
44+
llvm::PointerUnion<FileUnit *, ModuleDecl *> context;
4545
Lowering::TypeConverter &conv;
4646
const SILOptions &opts;
4747

@@ -73,6 +73,17 @@ struct SILGenDescriptor {
7373
const SILOptions &opts) {
7474
return SILGenDescriptor{mod, conv, opts};
7575
}
76+
77+
/// For a single file input, returns a single element array containing that
78+
/// file. Otherwise returns an array of each file in the module.
79+
ArrayRef<FileUnit *> getFiles() const;
80+
81+
/// If the module or file contains SIL that needs parsing, returns the file
82+
/// to be parsed, or \c nullptr if parsing isn't required.
83+
SourceFile *getSourceFileToParse() const;
84+
85+
/// Whether the SIL is being emitted for a whole module.
86+
bool isWholeModule() const;
7687
};
7788

7889
void simple_display(llvm::raw_ostream &out, const SILGenDescriptor &d);
@@ -120,6 +131,22 @@ class SILGenWholeModuleRequest :
120131
bool isCached() const { return true; }
121132
};
122133

134+
/// Parses a .sil file into a SILModule.
135+
class ParseSILModuleRequest
136+
: public SimpleRequest<ParseSILModuleRequest,
137+
std::unique_ptr<SILModule>(SILGenDescriptor),
138+
RequestFlags::Uncached> {
139+
public:
140+
using SimpleRequest::SimpleRequest;
141+
142+
private:
143+
friend SimpleRequest;
144+
145+
// Evaluation.
146+
std::unique_ptr<SILModule>
147+
evaluate(Evaluator &evaluator, SILGenDescriptor desc) const;
148+
};
149+
123150
/// The zone number for SILGen.
124151
#define SWIFT_TYPEID_ZONE SILGen
125152
#define SWIFT_TYPEID_HEADER "swift/AST/SILGenTypeIDZone.def"

include/swift/AST/SILGenTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@ SWIFT_REQUEST(SILGen, SILGenSourceFileRequest,
2020
SWIFT_REQUEST(SILGen, SILGenWholeModuleRequest,
2121
std::unique_ptr<SILModule>(SILGenDescriptor),
2222
Uncached, NoLocationInfo)
23+
SWIFT_REQUEST(SILGen, ParseSILModuleRequest,
24+
std::unique_ptr<SILModule>(SILGenDescriptor),
25+
Uncached, NoLocationInfo)

include/swift/Frontend/Frontend.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,6 @@ class CompilerInstance {
425425
DiagnosticEngine Diagnostics{SourceMgr};
426426
std::unique_ptr<ASTContext> Context;
427427
std::unique_ptr<Lowering::TypeConverter> TheSILTypes;
428-
std::unique_ptr<SILModule> TheSILModule;
429428
std::unique_ptr<DiagnosticVerifier> DiagVerifier;
430429

431430
/// Null if no tracker.
@@ -498,8 +497,6 @@ class CompilerInstance {
498497

499498
Lowering::TypeConverter &getSILTypes();
500499

501-
void createSILModule();
502-
503500
void addDiagnosticConsumer(DiagnosticConsumer *DC) {
504501
Diagnostics.addConsumer(*DC);
505502
}
@@ -517,16 +514,6 @@ class CompilerInstance {
517514

518515
UnifiedStatsReporter *getStatsReporter() const { return Stats.get(); }
519516

520-
SILModule *getSILModule() {
521-
return TheSILModule.get();
522-
}
523-
524-
std::unique_ptr<SILModule> takeSILModule();
525-
526-
bool hasSILModule() {
527-
return static_cast<bool>(TheSILModule);
528-
}
529-
530517
ModuleDecl *getMainModule() const;
531518

532519
MemoryBufferSerializedModuleLoader *
@@ -659,9 +646,6 @@ class CompilerInstance {
659646
public:
660647
void freeASTContext();
661648

662-
/// Frees up the SILModule that this instance is holding on to.
663-
void freeSILModule();
664-
665649
private:
666650
/// Load stdlib & return true if should continue, i.e. no error
667651
bool loadStdlib();

include/swift/Parse/Parser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,8 @@ class Parser {
888888
void parseTopLevel(SmallVectorImpl<Decl *> &decls);
889889

890890
/// Parse the top-level SIL decls into the SIL module.
891-
void parseTopLevelSIL();
891+
/// \returns \c true if there was a parsing error.
892+
bool parseTopLevelSIL();
892893

893894
/// Flags that control the parsing of declarations.
894895
enum ParseDeclFlags {

include/swift/Subsystems.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,6 @@ namespace swift {
102102

103103
/// @}
104104

105-
/// Parse a source file's SIL declarations into a given SIL module.
106-
void parseSourceFileSIL(SourceFile &SF, SILParserState *sil);
107-
108105
/// Finish the code completion.
109106
void performCodeCompletionSecondPass(SourceFile &SF,
110107
CodeCompletionCallbacksFactory &Factory);

lib/Frontend/Frontend.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,6 @@ Lowering::TypeConverter &CompilerInstance::getSILTypes() {
186186
return *tc;
187187
}
188188

189-
void CompilerInstance::createSILModule() {
190-
assert(MainModule && "main module not created yet");
191-
// Assume WMO if a -primary-file option was not provided.
192-
TheSILModule = SILModule::createEmptyModule(
193-
getMainModule(), getSILTypes(), Invocation.getSILOptions(),
194-
Invocation.getFrontendOptions().InputsAndOutputs.isWholeModule());
195-
}
196-
197189
void CompilerInstance::recordPrimaryInputBuffer(unsigned BufID) {
198190
PrimaryBufferIDs.insert(BufID);
199191
}
@@ -678,10 +670,6 @@ CompilerInstance::openModuleDoc(const InputFile &input) {
678670
return None;
679671
}
680672

681-
std::unique_ptr<SILModule> CompilerInstance::takeSILModule() {
682-
return std::move(TheSILModule);
683-
}
684-
685673
/// Implicitly import the SwiftOnoneSupport module in non-optimized
686674
/// builds. This allows for use of popular specialized functions
687675
/// from the standard library, which makes the non-optimized builds
@@ -759,14 +747,6 @@ void CompilerInstance::performSemaUpTo(SourceFile::ASTStage_t LimitStage) {
759747
ModuleDecl *mainModule = getMainModule();
760748
Context->LoadedModules[mainModule->getName()] = mainModule;
761749

762-
if (Invocation.getInputKind() == InputFileKind::SIL) {
763-
assert(!InputSourceCodeBufferIDs.empty());
764-
assert(InputSourceCodeBufferIDs.size() == 1);
765-
assert(MainBufferID != NO_SUCH_BUFFER);
766-
assert(isPrimaryInput(MainBufferID) || isWholeModuleCompilation());
767-
createSILModule();
768-
}
769-
770750
if (Invocation.getImplicitStdlibKind() == ImplicitStdlibKind::Stdlib) {
771751
if (!loadStdlib())
772752
return;
@@ -804,13 +784,6 @@ void CompilerInstance::performSemaUpTo(SourceFile::ASTStage_t LimitStage) {
804784

805785
forEachFileToTypeCheck([&](SourceFile &SF) {
806786
performTypeChecking(SF);
807-
808-
// Parse the SIL decls if needed.
809-
// TODO: Requestify SIL parsing.
810-
if (TheSILModule) {
811-
SILParserState SILContext(TheSILModule.get());
812-
parseSourceFileSIL(SF, &SILContext);
813-
}
814787
});
815788

816789
finishTypeChecking();
@@ -986,8 +959,6 @@ void CompilerInstance::freeASTContext() {
986959
PrimarySourceFiles.clear();
987960
}
988961

989-
void CompilerInstance::freeSILModule() { TheSILModule.reset(); }
990-
991962
/// Perform "stable" optimizations that are invariant across compiler versions.
992963
static bool performMandatorySILPasses(CompilerInvocation &Invocation,
993964
SILModule *SM) {

lib/FrontendTool/FrontendTool.cpp

Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,17 +1066,11 @@ static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
10661066
static bool performCompileStepsPostSema(CompilerInstance &Instance,
10671067
int &ReturnValue,
10681068
FrontendObserver *observer) {
1069-
auto mod = Instance.getMainModule();
1070-
if (auto SM = Instance.takeSILModule()) {
1071-
const PrimarySpecificPaths PSPs =
1072-
Instance.getPrimarySpecificPathsForAtMostOnePrimary();
1073-
return performCompileStepsPostSILGen(Instance, std::move(SM), mod, PSPs,
1074-
ReturnValue, observer);
1075-
}
1076-
10771069
const auto &Invocation = Instance.getInvocation();
10781070
const SILOptions &SILOpts = Invocation.getSILOptions();
10791071
const FrontendOptions &opts = Invocation.getFrontendOptions();
1072+
1073+
auto *mod = Instance.getMainModule();
10801074
if (!opts.InputsAndOutputs.hasPrimaryInputs()) {
10811075
// If there are no primary inputs the compiler is in WMO mode and builds one
10821076
// SILModule for the entire module.
@@ -1466,30 +1460,24 @@ static bool validateTBDIfNeeded(const CompilerInvocation &Invocation,
14661460
}
14671461
}
14681462

1469-
enum class DeallocatableResources {
1470-
None,
1471-
SILModule,
1472-
SILModuleAndASTContext,
1473-
};
1474-
static DeallocatableResources
1475-
computeDeallocatableResources(const CompilerInstance &Instance) {
1476-
// If the stats reporter is installed, we need the ASTContext and SILModule
1477-
// to live through the entire compilation process.
1463+
static void freeASTContextIfPossible(CompilerInstance &Instance) {
1464+
// If the stats reporter is installed, we need the ASTContext to live through
1465+
// the entire compilation process.
14781466
if (Instance.getASTContext().Stats) {
1479-
return DeallocatableResources::None;
1467+
return;
14801468
}
14811469

14821470
// If we're going to dump the API of the module, we cannot tear down
14831471
// the ASTContext, as that would cause the module to be freed prematurely.
14841472
const auto &opts = Instance.getInvocation().getFrontendOptions();
14851473
if (!opts.DumpAPIPath.empty()) {
1486-
return DeallocatableResources::SILModule;
1474+
return;
14871475
}
14881476

14891477
// Verifying incremental dependencies relies on access to the Swift Module's
1490-
// source files. We can still free the SIL module, though.
1478+
// source files.
14911479
if (opts.EnableIncrementalDependencyVerifier) {
1492-
return DeallocatableResources::SILModule;
1480+
return;
14931481
}
14941482

14951483
// If there are multiple primary inputs it is too soon to free
@@ -1498,29 +1486,14 @@ computeDeallocatableResources(const CompilerInstance &Instance) {
14981486
// unlikely to reduce the peak heap size. So, only optimize the
14991487
// single-primary-case (or WMO).
15001488
if (opts.InputsAndOutputs.hasMultiplePrimaryInputs()) {
1501-
return DeallocatableResources::SILModule;
1489+
return;
15021490
}
15031491

1504-
return DeallocatableResources::SILModuleAndASTContext;
1505-
}
1492+
// Make sure we emit dependencies now, because we can't do it after the
1493+
// context is gone.
1494+
emitReferenceDependenciesForAllPrimaryInputsIfNeeded(Instance);
15061495

1507-
static void freeDeallocatableResourcesIfPossible(CompilerInstance &Instance) {
1508-
switch (computeDeallocatableResources(Instance)) {
1509-
case DeallocatableResources::None:
1510-
break;
1511-
case DeallocatableResources::SILModule:
1512-
Instance.freeSILModule();
1513-
break;
1514-
case DeallocatableResources::SILModuleAndASTContext:
1515-
Instance.freeSILModule();
1516-
1517-
// Make sure we emit dependencies now, because we can't do it after the
1518-
// context is gone.
1519-
emitReferenceDependenciesForAllPrimaryInputsIfNeeded(Instance);
1520-
1521-
Instance.freeASTContext();
1522-
break;
1523-
}
1496+
Instance.freeASTContext();
15241497
}
15251498

15261499
static bool generateCode(CompilerInstance &Instance, StringRef OutputFilename,
@@ -1533,7 +1506,7 @@ static bool generateCode(CompilerInstance &Instance, StringRef OutputFilename,
15331506
Instance.getASTContext().LangOpts.EffectiveLanguageVersion;
15341507

15351508
// Free up some compiler resources now that we have an IRModule.
1536-
freeDeallocatableResourcesIfPossible(Instance);
1509+
freeASTContextIfPossible(Instance);
15371510

15381511
// Now that we have a single IR Module, hand it over to performLLVM.
15391512
return performLLVM(opts, Instance.getDiags(), nullptr, HashGlobal, IRModule,

lib/Parse/ParseDecl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ void Parser::parseTopLevel(SmallVectorImpl<Decl *> &decls) {
241241
TokReceiver->finalize();
242242
}
243243

244-
void Parser::parseTopLevelSIL() {
244+
bool Parser::parseTopLevelSIL() {
245245
assert(SIL && isInSILMode());
246246

247247
// Prime the lexer.
@@ -253,6 +253,7 @@ void Parser::parseTopLevelSIL() {
253253
skipSingle();
254254
};
255255

256+
auto hadError = false;
256257
while (!Tok.is(tok::eof)) {
257258
// If we run into a Swift decl, skip over until we find the next SIL decl.
258259
if (isStartOfSwiftDecl()) {
@@ -269,6 +270,7 @@ void Parser::parseTopLevelSIL() {
269270
if (SIL->parse##NAME(*this)) { \
270271
Lexer::SILBodyRAII sbr(*L); \
271272
skipToNextSILDecl(); \
273+
hadError = true; \
272274
} \
273275
break; \
274276
}
@@ -288,9 +290,11 @@ void Parser::parseTopLevelSIL() {
288290
// or a SIL decl. Emit an error and skip ahead to the next SIL decl.
289291
diagnose(Tok, diag::expected_sil_keyword);
290292
skipToNextSILDecl();
293+
hadError = true;
291294
break;
292295
}
293296
}
297+
return hadError;
294298
}
295299

296300
ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/NameLookup.h"
1818
#include "swift/AST/NameLookupRequests.h"
1919
#include "swift/AST/ProtocolConformance.h"
20+
#include "swift/AST/SILGenRequests.h"
2021
#include "swift/AST/SourceFile.h"
2122
#include "swift/AST/TypeCheckRequests.h"
2223
#include "swift/Basic/Defer.h"
@@ -105,17 +106,30 @@ SILParserState::SILParserState(SILModule *M)
105106

106107
SILParserState::~SILParserState() = default;
107108

108-
void swift::parseSourceFileSIL(SourceFile &SF, SILParserState *sil) {
109-
auto bufferID = SF.getBufferID();
109+
std::unique_ptr<SILModule>
110+
ParseSILModuleRequest::evaluate(Evaluator &evaluator,
111+
SILGenDescriptor desc) const {
112+
auto *SF = desc.getSourceFileToParse();
113+
assert(SF);
114+
115+
auto bufferID = SF->getBufferID();
110116
assert(bufferID);
111117

112-
FrontendStatsTracer tracer(SF.getASTContext().Stats,
113-
"Parsing SIL");
114-
Parser parser(*bufferID, SF, sil->Impl.get(),
115-
/*persistentParserState*/ nullptr,
116-
/*syntaxTreeCreator*/ nullptr);
118+
auto *mod = SF->getParentModule();
119+
auto silMod = SILModule::createEmptyModule(mod, desc.conv, desc.opts,
120+
desc.isWholeModule());
121+
SILParserState parserState(silMod.get());
122+
Parser parser(*bufferID, *SF, parserState.Impl.get());
117123
PrettyStackTraceParser StackTrace(parser);
118-
parser.parseTopLevelSIL();
124+
125+
auto hadError = parser.parseTopLevelSIL();
126+
if (hadError) {
127+
// The rest of the SIL pipeline expects well-formed SIL, so if we encounter
128+
// a parsing error, just return an empty SIL module.
129+
return SILModule::createEmptyModule(mod, desc.conv, desc.opts,
130+
desc.isWholeModule());
131+
}
132+
return silMod;
119133
}
120134

121135
//===----------------------------------------------------------------------===//

lib/SILGen/SILGen.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,6 +1860,11 @@ class SILGenModuleRAII {
18601860
std::unique_ptr<SILModule>
18611861
SILGenSourceFileRequest::evaluate(Evaluator &evaluator,
18621862
SILGenDescriptor desc) const {
1863+
// If we have a .sil file to parse, defer to the parsing request.
1864+
if (desc.getSourceFileToParse()) {
1865+
return llvm::cantFail(evaluator(ParseSILModuleRequest{desc}));
1866+
}
1867+
18631868
auto *unit = desc.context.get<FileUnit *>();
18641869
auto *mod = unit->getParentModule();
18651870
auto M = std::unique_ptr<SILModule>(
@@ -1879,6 +1884,11 @@ SILGenSourceFileRequest::evaluate(Evaluator &evaluator,
18791884
std::unique_ptr<SILModule>
18801885
SILGenWholeModuleRequest::evaluate(Evaluator &evaluator,
18811886
SILGenDescriptor desc) const {
1887+
// If we have a .sil file to parse, defer to the parsing request.
1888+
if (desc.getSourceFileToParse()) {
1889+
return llvm::cantFail(evaluator(ParseSILModuleRequest{desc}));
1890+
}
1891+
18821892
auto *mod = desc.context.get<ModuleDecl *>();
18831893
auto M = std::unique_ptr<SILModule>(
18841894
new SILModule(mod, desc.conv, desc.opts, mod, /*wholeModule*/ true));

0 commit comments

Comments
 (0)