2
2
//
3
3
// This source file is part of the Swift.org open source project
4
4
//
5
- // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5
+ // Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6
6
// Licensed under Apache License v2.0 with Runtime Library Exception
7
7
//
8
8
// See https://swift.org/LICENSE.txt for license information
15
15
16
16
#include " swift/Basic/LLVM.h"
17
17
#include " swift/Driver/Action.h"
18
+ #include " swift/Driver/OutputFileMap.h"
18
19
#include " swift/Driver/Types.h"
19
20
#include " swift/Driver/Util.h"
20
21
#include " llvm/Option/Option.h"
21
22
#include " llvm/ADT/ArrayRef.h"
22
23
#include " llvm/ADT/DenseMap.h"
23
24
#include " llvm/ADT/PointerIntPair.h"
25
+ #include " llvm/ADT/SmallSet.h"
24
26
#include " llvm/ADT/SmallVector.h"
25
27
#include " llvm/ADT/StringRef.h"
26
28
#include " llvm/Support/Chrono.h"
@@ -34,48 +36,148 @@ namespace driver {
34
36
class Job ;
35
37
class JobAction ;
36
38
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
+
37
101
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;
44
102
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 ;
48
106
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);
50
139
51
140
public:
52
- CommandOutput (types::ID PrimaryOutputType)
53
- : PrimaryOutputType(PrimaryOutputType) { }
141
+ CommandOutput (types::ID PrimaryOutputType, OutputFileMap &Derived);
54
142
55
- types::ID getPrimaryOutputType () const { return PrimaryOutputType; }
143
+ // / Return the primary output type for this CommandOutput.
144
+ types::ID getPrimaryOutputType () const ;
56
145
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);
68
149
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.
73
164
void setAdditionalOutputForType (types::ID type, StringRef OutputFilename);
74
- const std::string &getAdditionalOutputForType (types::ID type) const ;
75
165
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 ;
77
175
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;
79
181
};
80
182
81
183
class Job {
0 commit comments