Skip to content

Commit 7838244

Browse files
authored
Merge pull request #14495 from graydon/batch-mode-driver-work
2 parents 781e020 + f9d7bd2 commit 7838244

File tree

15 files changed

+588
-141
lines changed

15 files changed

+588
-141
lines changed

include/swift/Driver/Action.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -117,7 +117,7 @@ class JobAction : public Action {
117117
// Returns the index of the Input action's output file which is used as
118118
// (single) input to this action. Most actions produce only a single output
119119
// file, so we return 0 by default.
120-
virtual int getInputIndex() const { return 0; }
120+
virtual size_t getInputIndex() const { return 0; }
121121

122122
static bool classof(const Action *A) {
123123
return (A->getKind() >= ActionClass::JobFirst &&
@@ -188,16 +188,16 @@ class BackendJobAction : public JobAction {
188188
// In case of multi-threaded compilation, the compile-action produces multiple
189189
// output bitcode-files. For each bitcode-file a BackendJobAction is created.
190190
// This index specifies which of the files to select for the input.
191-
int InputIndex;
191+
size_t InputIndex;
192192
public:
193-
BackendJobAction(const Action *Input, types::ID OutputType, int InputIndex)
193+
BackendJobAction(const Action *Input, types::ID OutputType, size_t InputIndex)
194194
: JobAction(Action::BackendJob, Input, OutputType),
195195
InputIndex(InputIndex) {}
196196
static bool classof(const Action *A) {
197197
return A->getKind() == Action::BackendJob;
198198
}
199199

200-
virtual int getInputIndex() const { return InputIndex; }
200+
virtual size_t getInputIndex() const { return InputIndex; }
201201
};
202202

203203
class REPLJobAction : public JobAction {

include/swift/Driver/Compilation.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -72,11 +72,16 @@ class Compilation {
7272

7373
/// The ToolChain this Compilation was built with, that it may reuse to build
7474
/// subsequent BatchJobs.
75-
const ToolChain &TheToolChain;
75+
LLVM_ATTRIBUTE_UNUSED const ToolChain &TheToolChain;
7676

7777
/// The OutputLevel at which this Compilation should generate output.
7878
OutputLevel Level;
7979

80+
/// The OutputFileMap describing the Compilation's outputs, populated both by
81+
/// the user-provided output file map (if it exists) and inference rules that
82+
/// derive otherwise-unspecified output filenames from context.
83+
OutputFileMap DerivedOutputFileMap;
84+
8085
/// The Actions which were used to build the Jobs.
8186
///
8287
/// This is mostly only here for lifetime management.
@@ -218,6 +223,11 @@ class Compilation {
218223
const llvm::opt::DerivedArgList &getArgs() const { return *TranslatedArgs; }
219224
ArrayRef<InputPair> getInputFiles() const { return InputFilesWithTypes; }
220225

226+
OutputFileMap &getDerivedOutputFileMap() { return DerivedOutputFileMap; }
227+
const OutputFileMap &getDerivedOutputFileMap() const {
228+
return DerivedOutputFileMap;
229+
}
230+
221231
unsigned getNumberOfParallelCommands() const {
222232
return NumberOfParallelCommands;
223233
}

include/swift/Driver/Driver.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -289,7 +289,9 @@ class Driver {
289289
const ToolChain &TC, bool AtTopLevel,
290290
SmallVectorImpl<const Action *> &InputActions,
291291
SmallVectorImpl<const Job *> &InputJobs,
292-
const TypeToPathMap *OutputMap, StringRef BaseInput,
292+
const TypeToPathMap *OutputMap,
293+
StringRef BaseInput,
294+
StringRef PrimaryInput,
293295
llvm::SmallString<128> &Buf,
294296
CommandOutput *Output) const;
295297

include/swift/Driver/Job.h

Lines changed: 134 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -15,12 +15,14 @@
1515

1616
#include "swift/Basic/LLVM.h"
1717
#include "swift/Driver/Action.h"
18+
#include "swift/Driver/OutputFileMap.h"
1819
#include "swift/Driver/Types.h"
1920
#include "swift/Driver/Util.h"
2021
#include "llvm/Option/Option.h"
2122
#include "llvm/ADT/ArrayRef.h"
2223
#include "llvm/ADT/DenseMap.h"
2324
#include "llvm/ADT/PointerIntPair.h"
25+
#include "llvm/ADT/SmallSet.h"
2426
#include "llvm/ADT/SmallVector.h"
2527
#include "llvm/ADT/StringRef.h"
2628
#include "llvm/Support/Chrono.h"
@@ -34,48 +36,148 @@ namespace driver {
3436
class Job;
3537
class JobAction;
3638

39+
/// \file Job.h
40+
///
41+
///Some terminology for the following sections (and especially Driver.cpp):
42+
///
43+
/// BaseInput: a filename provided by the user, upstream of the entire Job
44+
/// graph, usually denoted by an InputAction. Every Job has access,
45+
/// during construction, to a set of BaseInputs that are upstream of
46+
/// its inputs and input jobs in the job graph, and from which it can
47+
/// derive PrimaryInput names for itself.
48+
///
49+
/// BaseOutput: a filename that is a non-temporary, output at the bottom of a
50+
/// Job graph, and often (though not always) directly specified by
51+
/// the user in the form of a -o or -emit-foo-path name, or an entry
52+
/// in a user-provided OutputFileMap. May also be an auxiliary,
53+
/// derived from a BaseInput and a type.
54+
///
55+
/// PrimaryInput: one of the distinguished inputs-to-act-on (as opposed to
56+
/// merely informative additional inputs) to a Job. May be a
57+
/// BaseInput but may also be a temporary that doesn't live beyond
58+
/// the execution of the Job graph.
59+
///
60+
/// PrimaryOutput: an output file matched 1:1 with a specific
61+
/// PrimaryInput. Auxiliary outputs may also be produced. A
62+
/// PrimaryOutput may be a BaseOutput, but may also be a
63+
/// temporary that doesn't live beyond the execution of the Job
64+
/// graph (that is: it exists in order to be the PrimaryInput
65+
/// for a subsequent Job).
66+
///
67+
/// The user-provided OutputFileMap lists BaseInputs and BaseOutputs, but doesn't
68+
/// describe the temporaries inside the Job graph.
69+
///
70+
/// The Compilation's DerivedOutputFileMap (shared by all CommandOutputs) lists
71+
/// PrimaryInputs and maps them to PrimaryOutputs, including all the
72+
/// temporaries. This means that in a multi-stage Job graph, the BaseInput =>
73+
/// BaseOutput entries provided by the user are split in two (or more) steps,
74+
/// one BaseInput => SomeTemporary and one SomeTemporary => BaseOutput.
75+
///
76+
/// To try to keep this as simple as possible (it's already awful) we associate
77+
/// every PrimaryInput 1:1 with a specific BaseInput from which it was derived;
78+
/// this way a CommandOutput will have a vector of _pairs_ of
79+
/// {Base,Primary}Inputs rather than a pair of separate vectors. This arrangement
80+
/// appears to cover all the graph topologies we encounter in practice.
81+
82+
83+
struct CommandInputPair {
84+
/// A filename provided from the user, either on the command line or in an
85+
/// input file map. Feeds into a Job graph, from InputActions, and is
86+
/// _associated_ with a PrimaryInput for a given Job, but may be upstream of
87+
/// the Job (and its PrimaryInput) and thus not necessarily passed as a
88+
/// filename to the job. Used as a key into the user-provided OutputFileMap
89+
/// (of BaseInputs and BaseOutputs), and used to derive downstream names --
90+
/// both temporaries and auxiliaries -- but _not_ used as a key into the
91+
/// DerivedOutputFileMap.
92+
StringRef Base;
93+
94+
/// A filename that _will be passed_ to the command as a designated primary
95+
/// input. Typically either equal to BaseInput or a temporary with a name
96+
/// derived from the BaseInput it is related to. Also used as a key into
97+
/// the DerivedOutputFileMap.
98+
StringRef Primary;
99+
};
100+
37101
class CommandOutput {
38-
types::ID PrimaryOutputType;
39-
40-
/// The primary output files of the command.
41-
/// Usually a command has only a single output file. Only the compiler in
42-
/// multi-threaded compilation produces multiple output files.
43-
SmallVector<std::string, 1> PrimaryOutputFilenames;
44102

45-
/// For each primary output file there is a base input. This is the input file
46-
/// from which the output file is derived.
47-
SmallVector<StringRef, 1> BaseInputs;
103+
/// A CommandOutput designates one type of output as primary, though there
104+
/// may be multiple outputs of that type.
105+
types::ID PrimaryOutputType;
48106

49-
llvm::SmallDenseMap<types::ID, std::string, 4> AdditionalOutputsMap;
107+
/// A CommandOutput also restricts its attention regarding additional-outputs
108+
/// to a subset of the PrimaryOutputs associated with its PrimaryInputs;
109+
/// sometimes multiple commands operate on the same PrimaryInput, in different
110+
/// phases (eg. autolink-extract and link both operate on the same .o file),
111+
/// so Jobs cannot _just_ rely on the presence of a primary output in the
112+
/// DerivedOutputFileMap.
113+
llvm::SmallSet<types::ID, 4> AdditionalOutputTypes;
114+
115+
/// The set of input filenames for this \c CommandOutput; combined with \c
116+
/// DerivedOutputMap, specifies a set of output filenames (of which one -- the
117+
/// one of type \c PrimaryOutputType) is the primary output filename.
118+
SmallVector<CommandInputPair, 1> Inputs;
119+
120+
/// All CommandOutputs in a Compilation share the same \c
121+
/// DerivedOutputMap. This is computed both from any user-provided input file
122+
/// map, and any inference steps.
123+
OutputFileMap &DerivedOutputMap;
124+
125+
// If there is an entry in the DerivedOutputMap for a given (\p
126+
// PrimaryInputFile, \p Type) pair, return a nonempty StringRef, otherwise
127+
// return an empty StringRef.
128+
StringRef
129+
getOutputForInputAndType(StringRef PrimaryInputFile, types::ID Type) const;
130+
131+
/// Add an entry to the \c DerivedOutputMap if it doesn't exist. If an entry
132+
/// already exists for \p PrimaryInputFile of type \p type, then either
133+
/// overwrite the entry (if \p overwrite is \c true) or assert that it has
134+
/// the same value as \p OutputFile.
135+
void ensureEntry(StringRef PrimaryInputFile,
136+
types::ID Type,
137+
StringRef OutputFile,
138+
bool Overwrite);
50139

51140
public:
52-
CommandOutput(types::ID PrimaryOutputType)
53-
: PrimaryOutputType(PrimaryOutputType) { }
141+
CommandOutput(types::ID PrimaryOutputType, OutputFileMap &Derived);
54142

55-
types::ID getPrimaryOutputType() const { return PrimaryOutputType; }
143+
/// Return the primary output type for this CommandOutput.
144+
types::ID getPrimaryOutputType() const;
56145

57-
void addPrimaryOutput(StringRef FileName, StringRef BaseInput) {
58-
PrimaryOutputFilenames.push_back(FileName);
59-
BaseInputs.push_back(BaseInput);
60-
}
61-
62-
// This returns a std::string instead of a StringRef so that users can rely
63-
// on the data buffer being null-terminated.
64-
const std::string &getPrimaryOutputFilename() const {
65-
assert(PrimaryOutputFilenames.size() == 1);
66-
return PrimaryOutputFilenames[0];
67-
}
146+
/// Associate a new \p PrimaryOutputFile (of type \c getPrimaryOutputType())
147+
/// with the provided \p Input pair of Base and Primary inputs.
148+
void addPrimaryOutput(CommandInputPair Input, StringRef PrimaryOutputFile);
68149

69-
ArrayRef<std::string> getPrimaryOutputFilenames() const {
70-
return PrimaryOutputFilenames;
71-
}
72-
150+
/// Assuming (and asserting) that there is only one input pair, return the
151+
/// primary output file associated with it. Note that the returned StringRef
152+
/// may be invalidated by subsequent mutations to the \c CommandOutput.
153+
StringRef getPrimaryOutputFilename() const;
154+
155+
/// Return a all of the outputs of type \c getPrimaryOutputType() associated
156+
/// with a primary input. Note that the returned \c StringRef vector may be
157+
/// invalidated by subsequent mutations to the \c CommandOutput.
158+
SmallVector<StringRef, 16> getPrimaryOutputFilenames() const;
159+
160+
/// Assuming (and asserting) that there are one or more input pairs, associate
161+
/// an additional output named \p OutputFilename of type \p type with the
162+
/// first primary input. If the provided \p type is the primary output type,
163+
/// overwrite the existing entry assocaited with the first primary input.
73164
void setAdditionalOutputForType(types::ID type, StringRef OutputFilename);
74-
const std::string &getAdditionalOutputForType(types::ID type) const;
75165

76-
const std::string &getAnyOutputForType(types::ID type) const;
166+
/// Assuming (and asserting) that there are one or more input pairs, return
167+
/// the _additional_ (not primary) output of type \p type associated with the
168+
/// first primary input.
169+
StringRef getAdditionalOutputForType(types::ID type) const;
170+
171+
/// Assuming (and asserting) that there is only one input pair, return any
172+
/// output -- primary or additional -- of type \p type associated with that
173+
/// the sole primary input.
174+
StringRef getAnyOutputForType(types::ID type) const;
77175

78-
StringRef getBaseInput(int Index) const { return BaseInputs[Index]; }
176+
/// Return the BaseInput numbered by \p Index.
177+
StringRef getBaseInput(size_t Index) const;
178+
179+
void print(raw_ostream &Stream) const;
180+
void dump() const LLVM_ATTRIBUTE_USED;
79181
};
80182

81183
class Job {

include/swift/Driver/OutputFileMap.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -33,9 +33,9 @@ class OutputFileMap {
3333
private:
3434
llvm::StringMap<TypeToPathMap> InputToOutputsMap;
3535

36+
public:
3637
OutputFileMap() {}
3738

38-
public:
3939
~OutputFileMap() = default;
4040

4141
/// Loads an OutputFileMap from the given \p Path, if possible.
@@ -52,9 +52,16 @@ class OutputFileMap {
5252
/// OutputFileMap. (If not present, returns nullptr.)
5353
const TypeToPathMap *getOutputMapForInput(StringRef Input) const;
5454

55+
/// Get a map of outputs for the given \p Input, creating it in
56+
/// the OutputFileMap if not already present.
57+
TypeToPathMap &getOrCreateOutputMapForInput(StringRef Input);
58+
5559
/// Get the map of outputs for a single compile product.
5660
const TypeToPathMap *getOutputMapForSingleOutput() const;
5761

62+
/// Get or create the map of outputs for a single compile product.
63+
TypeToPathMap &getOrCreateOutputMapForSingleOutput();
64+
5865
/// Dump the OutputFileMap to the given \p os.
5966
void dump(llvm::raw_ostream &os, bool Sort = false) const;
6067

0 commit comments

Comments
 (0)