Skip to content

Commit 7d637c8

Browse files
author
David Ungar
authored
Merge pull request swiftlang#12335 from davidungar/primaryFilesMode-Inputs-rebased
NFC: First step (refactoring) towards speeding up compilation w/ >1 primary file
2 parents 634f719 + 47ee930 commit 7d637c8

File tree

15 files changed

+597
-382
lines changed

15 files changed

+597
-382
lines changed

include/swift/Frontend/Frontend.h

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,25 +243,19 @@ class CompilerInvocation {
243243
}
244244

245245
void addInputFilename(StringRef Filename) {
246-
FrontendOpts.InputFilenames.push_back(Filename);
246+
FrontendOpts.Inputs.addInputFilename(Filename);
247247
}
248248

249249
/// Does not take ownership of \p Buf.
250250
void addInputBuffer(llvm::MemoryBuffer *Buf) {
251-
FrontendOpts.InputBuffers.push_back(Buf);
251+
FrontendOpts.Inputs.addInputBuffer(Buf);
252252
}
253253

254-
void clearInputs() {
255-
FrontendOpts.InputFilenames.clear();
256-
FrontendOpts.InputBuffers.clear();
254+
void setPrimaryInput(SelectedInput pi) {
255+
FrontendOpts.Inputs.setPrimaryInput(pi);
257256
}
258257

259-
ArrayRef<std::string> getInputFilenames() const {
260-
return FrontendOpts.InputFilenames;
261-
}
262-
ArrayRef<llvm::MemoryBuffer*> getInputBuffers() const {
263-
return FrontendOpts.InputBuffers;
264-
}
258+
void clearInputs() { FrontendOpts.Inputs.clearInputs(); }
265259

266260
StringRef getOutputFilename() const {
267261
return FrontendOpts.getSingleOutputFilename();
@@ -339,7 +333,7 @@ class CompilerInstance {
339333
SerializedModuleLoader *SML = nullptr;
340334

341335
/// Contains buffer IDs for input source code files.
342-
std::vector<unsigned> BufferIDs;
336+
std::vector<unsigned> InputSourceCodeBufferIDs;
343337

344338
struct PartialModuleInputs {
345339
std::unique_ptr<llvm::MemoryBuffer> ModuleBuffer;
@@ -362,6 +356,8 @@ class CompilerInstance {
362356
void createSILModule();
363357
void setPrimarySourceFile(SourceFile *SF);
364358

359+
bool setupForFileAt(unsigned i);
360+
365361
public:
366362
SourceManager &getSourceMgr() { return SourceMgr; }
367363

@@ -418,7 +414,9 @@ class CompilerInstance {
418414

419415
SerializedModuleLoader *getSerializedModuleLoader() const { return SML; }
420416

421-
ArrayRef<unsigned> getInputBufferIDs() const { return BufferIDs; }
417+
ArrayRef<unsigned> getInputBufferIDs() const {
418+
return InputSourceCodeBufferIDs;
419+
}
422420

423421
ArrayRef<LinkLibrary> getLinkLibraries() const {
424422
return Invocation.getLinkLibraries();

include/swift/Frontend/FrontendOptions.h

Lines changed: 154 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121

2222
namespace llvm {
2323
class MemoryBuffer;
24+
namespace opt {
25+
class ArgList;
26+
class Arg;
27+
} // namespace opt
2428
}
2529

2630
namespace swift {
@@ -62,9 +66,11 @@ enum class InputFileKind {
6266
IFK_LLVM_IR
6367
};
6468

65-
/// Options for controlling the behavior of the frontend.
66-
class FrontendOptions {
67-
public:
69+
/// Information about all the inputs to the frontend.
70+
class FrontendInputs {
71+
private:
72+
// FIXME: (dmu) create a class for the inputs
73+
6874
/// The names of input files to the frontend.
6975
std::vector<std::string> InputFilenames;
7076

@@ -75,13 +81,147 @@ class FrontendOptions {
7581
/// be generated for the whole module.
7682
Optional<SelectedInput> PrimaryInput;
7783

84+
public:
85+
// Readers:
86+
87+
// Input filename readers
88+
ArrayRef<std::string> getInputFilenames() const { return InputFilenames; }
89+
bool hasInputFilenames() const { return !getInputFilenames().empty(); }
90+
unsigned inputFilenameCount() const { return getInputFilenames().size(); }
91+
92+
bool hasUniqueInputFilename() const { return inputFilenameCount() == 1; }
93+
const std::string &getFilenameOfFirstInput() const {
94+
assert(hasInputFilenames());
95+
return getInputFilenames()[0];
96+
}
97+
98+
bool isReadingFromStdin() {
99+
return hasUniqueInputFilename() && getFilenameOfFirstInput() == "-";
100+
}
101+
102+
// If we have exactly one input filename, and its extension is "bc" or "ll",
103+
// treat the input as LLVM_IR.
104+
bool shouldTreatAsLLVM() const;
105+
106+
// Input buffer readers
107+
108+
ArrayRef<llvm::MemoryBuffer *> getInputBuffers() const {
109+
return InputBuffers;
110+
}
111+
unsigned inputBufferCount() const { return getInputBuffers().size(); }
112+
113+
// Primary input readers
114+
115+
Optional<SelectedInput> getPrimaryInput() const { return PrimaryInput; }
116+
bool hasPrimaryInput() const { return getPrimaryInput().hasValue(); }
117+
118+
bool isWholeModule() { return !hasPrimaryInput(); }
119+
120+
bool isPrimaryInputAFileAt(unsigned i) {
121+
return hasPrimaryInput() && getPrimaryInput()->isFilename() &&
122+
getPrimaryInput()->Index == i;
123+
}
124+
bool haveAPrimaryInputFile() const {
125+
return hasPrimaryInput() && getPrimaryInput()->isFilename();
126+
}
127+
Optional<unsigned> primaryInputFileIndex() const {
128+
return haveAPrimaryInputFile()
129+
? Optional<unsigned>(getPrimaryInput()->Index)
130+
: None;
131+
}
132+
133+
StringRef primaryInputFilenameIfAny() const {
134+
if (auto Index = primaryInputFileIndex()) {
135+
return getInputFilenames()[*Index];
136+
}
137+
return StringRef();
138+
}
139+
140+
// Multi-facet readers
141+
StringRef baseNameOfOutput(const llvm::opt::ArgList &Args,
142+
StringRef ModuleName) const;
143+
bool shouldTreatAsSIL() const;
144+
145+
/// Return true for error
146+
bool verifyInputs(DiagnosticEngine &Diags, bool TreatAsSIL,
147+
bool isREPLRequested, bool isNoneRequested) const;
148+
149+
// Input filename writers
150+
151+
void addInputFilename(StringRef Filename) {
152+
InputFilenames.push_back(Filename);
153+
}
154+
void transformInputFilenames(
155+
const llvm::function_ref<std::string(std::string)> &fn);
156+
157+
// Input buffer writers
158+
159+
void addInputBuffer(llvm::MemoryBuffer *Buf) { InputBuffers.push_back(Buf); }
160+
161+
// Primary input writers
162+
163+
void setPrimaryInput(SelectedInput si) { PrimaryInput = si; }
164+
void clearPrimaryInput() { PrimaryInput = 0; }
165+
void setPrimaryInputForInputFilename(const std::string &inputFilename) {
166+
setPrimaryInput(!inputFilename.empty() && inputFilename != "-"
167+
? SelectedInput(inputFilenameCount(),
168+
SelectedInput::InputKind::Filename)
169+
: SelectedInput(inputBufferCount(),
170+
SelectedInput::InputKind::Buffer));
171+
}
172+
173+
// Multi-faceted writers
174+
175+
void clearInputs() {
176+
InputFilenames.clear();
177+
InputBuffers.clear();
178+
}
179+
180+
void setInputFilenamesAndPrimaryInput(DiagnosticEngine &Diags,
181+
llvm::opt::ArgList &Args);
182+
183+
void readInputFileList(DiagnosticEngine &diags, llvm::opt::ArgList &Args,
184+
const llvm::opt::Arg *filelistPath);
185+
};
186+
187+
/// Options for controlling the behavior of the frontend.
188+
class FrontendOptions {
189+
public:
190+
FrontendInputs Inputs;
191+
78192
/// The kind of input on which the frontend should operate.
79193
InputFileKind InputKind = InputFileKind::IFK_Swift;
80194

81195
/// The specified output files. If only a single outputfile is generated,
82196
/// the name of the last specified file is taken.
83197
std::vector<std::string> OutputFilenames;
84198

199+
void forAllOutputPaths(std::function<void(const std::string &)> fn) const;
200+
201+
/// Gets the name of the specified output filename.
202+
/// If multiple files are specified, the last one is returned.
203+
StringRef getSingleOutputFilename() const {
204+
if (OutputFilenames.size() >= 1)
205+
return OutputFilenames.back();
206+
return StringRef();
207+
}
208+
/// Sets a single filename as output filename.
209+
void setSingleOutputFilename(const std::string &FileName) {
210+
OutputFilenames.clear();
211+
OutputFilenames.push_back(FileName);
212+
}
213+
void setOutputFilenameToStdout() { setSingleOutputFilename("-"); }
214+
bool isOutputFilenameStdout() const {
215+
return getSingleOutputFilename() == "-";
216+
}
217+
bool isOutputFileDirectory() const;
218+
bool isOutputFilePlainFile() const;
219+
bool hasNamedOutputFile() const {
220+
return !OutputFilenames.empty() && !isOutputFilenameStdout();
221+
}
222+
void setOutputFileList(DiagnosticEngine &Diags,
223+
const llvm::opt::ArgList &Args);
224+
85225
/// A list of arbitrary modules to import and make implicitly visible.
86226
std::vector<std::string> ImplicitImportModuleNames;
87227

@@ -325,27 +465,22 @@ class FrontendOptions {
325465
/// Indicates whether the RequestedAction will immediately run code.
326466
bool actionIsImmediate() const;
327467

328-
void forAllOutputPaths(std::function<void(const std::string &)> fn) const;
329-
330-
/// Gets the name of the specified output filename.
331-
/// If multiple files are specified, the last one is returned.
332-
StringRef getSingleOutputFilename() const {
333-
if (OutputFilenames.size() >= 1)
334-
return OutputFilenames.back();
335-
return StringRef();
336-
}
337-
338-
/// Sets a single filename as output filename.
339-
void setSingleOutputFilename(const std::string &FileName) {
340-
OutputFilenames.clear();
341-
OutputFilenames.push_back(FileName);
342-
}
343-
344468
/// Return a hash code of any components from these options that should
345469
/// contribute to a Swift Bridging PCH hash.
346470
llvm::hash_code getPCHHashComponents() const {
347471
return llvm::hash_value(0);
348472
}
473+
474+
StringRef originalPath() const;
475+
476+
StringRef determineFallbackModuleName() const;
477+
478+
bool isCompilingExactlyOneSwiftFile() const {
479+
return InputKind == InputFileKind::IFK_Swift &&
480+
Inputs.hasUniqueInputFilename();
481+
}
482+
483+
void setModuleName(DiagnosticEngine &Diags, const llvm::opt::ArgList &Args);
349484
};
350485

351486
}

0 commit comments

Comments
 (0)