Skip to content

Commit fcb1dca

Browse files
committed
Requestify SIL parsing
Replace `parseSourceFileSIL` with ParseSILModuleRequest, and add some convenience members to SILGenDescriptor to retrieve the SourceFile to be parsed.
1 parent 9c8be74 commit fcb1dca

File tree

5 files changed

+88
-11
lines changed

5 files changed

+88
-11
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/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/SIL/Parser/ParseSIL.cpp

Lines changed: 14 additions & 7 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,23 @@ 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);
118124
parser.parseTopLevelSIL();
125+
return silMod;
119126
}
120127

121128
//===----------------------------------------------------------------------===//

lib/SILGen/SILGenRequests.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,49 @@ evaluator::DependencySource SILGenSourceFileRequest::readDependencySource(
5656
};
5757
}
5858

59+
ArrayRef<FileUnit *> SILGenDescriptor::getFiles() const {
60+
if (auto *mod = context.dyn_cast<ModuleDecl *>())
61+
return mod->getFiles();
62+
63+
// For a single file, we can form an ArrayRef that points at its storage in
64+
// the union.
65+
return llvm::makeArrayRef(*context.getAddrOfPtr1());
66+
}
67+
68+
bool SILGenDescriptor::isWholeModule() const {
69+
return context.is<ModuleDecl *>();
70+
}
71+
72+
SourceFile *SILGenDescriptor::getSourceFileToParse() const {
73+
#ifndef NDEBUG
74+
auto sfCount = llvm::count_if(getFiles(), [](FileUnit *file) {
75+
return isa<SourceFile>(file);
76+
});
77+
auto silFileCount = llvm::count_if(getFiles(), [](FileUnit *file) {
78+
auto *SF = dyn_cast<SourceFile>(file);
79+
return SF && SF->Kind == SourceFileKind::SIL;
80+
});
81+
assert(silFileCount == 0 || (silFileCount == 1 && sfCount == 1) &&
82+
"Cannot currently mix a .sil file with other SourceFiles");
83+
#endif
84+
85+
for (auto *file : getFiles()) {
86+
// Skip other kinds of files.
87+
auto *SF = dyn_cast<SourceFile>(file);
88+
if (!SF)
89+
continue;
90+
91+
// Given the above precondition that a .sil file isn't mixed with other
92+
// SourceFiles, we can return a SIL file if we have it, or return nullptr.
93+
if (SF->Kind == SourceFileKind::SIL) {
94+
return SF;
95+
} else {
96+
return nullptr;
97+
}
98+
}
99+
return nullptr;
100+
}
101+
59102
// Define request evaluation functions for each of the SILGen requests.
60103
static AbstractRequestFunction *silGenRequestFunctions[] = {
61104
#define SWIFT_REQUEST(Zone, Name, Sig, Caching, LocOptions) \

0 commit comments

Comments
 (0)