blob: 63c11831079e7fd177c424b7a1faf120ffb2cdb3 [file] [log] [blame]
Nick Lewycky6da90772010-12-31 17:31:54 +00001//===--- Action.cpp - Abstract compilation steps --------------------------===//
Daniel Dunbarf479c122009-03-12 18:40:18 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Driver/Action.h"
Samuel Antaod06239d2016-07-15 23:13:27 +000011#include "clang/Driver/ToolChain.h"
Justin Lebar29bfa892016-01-12 22:23:04 +000012#include "llvm/ADT/StringSwitch.h"
David Blaikie79000202011-09-23 05:57:42 +000013#include "llvm/Support/ErrorHandling.h"
Justin Lebar7bf77982016-01-11 23:27:13 +000014#include "llvm/Support/Regex.h"
Daniel Dunbarf479c122009-03-12 18:40:18 +000015#include <cassert>
16using namespace clang::driver;
Reid Kleckner898229a2013-06-14 17:17:23 +000017using namespace llvm::opt;
Daniel Dunbarf479c122009-03-12 18:40:18 +000018
Justin Lebar41094612016-01-11 23:07:27 +000019Action::~Action() {}
Daniel Dunbar80665fb2009-03-13 12:17:08 +000020
21const char *Action::getClassName(ActionClass AC) {
22 switch (AC) {
23 case InputClass: return "input";
24 case BindArchClass: return "bind-arch";
Samuel Antaod06239d2016-07-15 23:13:27 +000025 case OffloadClass:
26 return "offload";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000027 case PreprocessJobClass: return "preprocessor";
28 case PrecompileJobClass: return "precompiler";
29 case AnalyzeJobClass: return "analyzer";
Ted Kremenekf7639e12012-03-06 20:06:33 +000030 case MigrateJobClass: return "migrator";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000031 case CompileJobClass: return "compiler";
Bob Wilson23a55f12014-12-21 07:00:00 +000032 case BackendJobClass: return "backend";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000033 case AssembleJobClass: return "assembler";
34 case LinkJobClass: return "linker";
Daniel Dunbar80665fb2009-03-13 12:17:08 +000035 case LipoJobClass: return "lipo";
Daniel Dunbar88299622010-06-04 18:28:36 +000036 case DsymutilJobClass: return "dsymutil";
Ben Langmuir9b9a8d32014-02-06 18:53:25 +000037 case VerifyDebugInfoJobClass: return "verify-debug-info";
38 case VerifyPCHJobClass: return "verify-pch";
Daniel Dunbar80665fb2009-03-13 12:17:08 +000039 }
Mike Stump11289f42009-09-09 15:08:12 +000040
David Blaikie83d382b2011-09-23 05:06:16 +000041 llvm_unreachable("invalid class");
Daniel Dunbar80665fb2009-03-13 12:17:08 +000042}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +000043
Samuel Antaod06239d2016-07-15 23:13:27 +000044void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch) {
45 // Offload action set its own kinds on their dependences.
46 if (Kind == OffloadClass)
47 return;
48
49 assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
50 "Setting device kind to a different device??");
51 assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??");
52 OffloadingDeviceKind = OKind;
53 OffloadingArch = OArch;
54
55 for (auto *A : Inputs)
56 A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch);
57}
58
59void Action::propagateHostOffloadInfo(unsigned OKinds, const char *OArch) {
60 // Offload action set its own kinds on their dependences.
61 if (Kind == OffloadClass)
62 return;
63
64 assert(OffloadingDeviceKind == OFK_None &&
65 "Setting a host kind in a device action.");
66 ActiveOffloadKindMask |= OKinds;
67 OffloadingArch = OArch;
68
69 for (auto *A : Inputs)
70 A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
71}
72
73void Action::propagateOffloadInfo(const Action *A) {
74 if (unsigned HK = A->getOffloadingHostActiveKinds())
75 propagateHostOffloadInfo(HK, A->getOffloadingArch());
76 else
77 propagateDeviceOffloadInfo(A->getOffloadingDeviceKind(),
78 A->getOffloadingArch());
79}
80
81std::string Action::getOffloadingKindPrefix() const {
82 switch (OffloadingDeviceKind) {
83 case OFK_None:
84 break;
85 case OFK_Host:
86 llvm_unreachable("Host kind is not an offloading device kind.");
87 break;
88 case OFK_Cuda:
89 return "device-cuda";
90
91 // TODO: Add other programming models here.
92 }
93
94 if (!ActiveOffloadKindMask)
95 return "";
96
97 std::string Res("host");
98 if (ActiveOffloadKindMask & OFK_Cuda)
99 Res += "-cuda";
100
101 // TODO: Add other programming models here.
102
103 return Res;
104}
105
106std::string
Samuel Antao2fd32132016-07-15 23:51:21 +0000107Action::getOffloadingFileNamePrefix(llvm::StringRef NormalizedTriple) const {
Samuel Antaod06239d2016-07-15 23:13:27 +0000108 // A file prefix is only generated for device actions and consists of the
109 // offload kind and triple.
110 if (!OffloadingDeviceKind)
111 return "";
112
113 std::string Res("-");
114 Res += getOffloadingKindPrefix();
115 Res += "-";
116 Res += NormalizedTriple;
117 return Res;
118}
119
David Blaikie68e081d2011-12-20 02:48:34 +0000120void InputAction::anchor() {}
121
Mike Stump11289f42009-09-09 15:08:12 +0000122InputAction::InputAction(const Arg &_Input, types::ID _Type)
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000123 : Action(InputClass, _Type), Input(_Input) {
124}
125
David Blaikie68e081d2011-12-20 02:48:34 +0000126void BindArchAction::anchor() {}
127
Justin Lebar41094612016-01-11 23:07:27 +0000128BindArchAction::BindArchAction(Action *Input, const char *_ArchName)
129 : Action(BindArchClass, Input), ArchName(_ArchName) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000130
Samuel Antaod06239d2016-07-15 23:13:27 +0000131void OffloadAction::anchor() {}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000132
Samuel Antaod06239d2016-07-15 23:13:27 +0000133OffloadAction::OffloadAction(const HostDependence &HDep)
134 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
135 OffloadingArch = HDep.getBoundArch();
136 ActiveOffloadKindMask = HDep.getOffloadKinds();
137 HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
138 HDep.getBoundArch());
139};
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000140
Samuel Antaod06239d2016-07-15 23:13:27 +0000141OffloadAction::OffloadAction(const DeviceDependences &DDeps, types::ID Ty)
142 : Action(OffloadClass, DDeps.getActions(), Ty),
143 DevToolChains(DDeps.getToolChains()) {
144 auto &OKinds = DDeps.getOffloadKinds();
145 auto &BArchs = DDeps.getBoundArchs();
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000146
Samuel Antaod06239d2016-07-15 23:13:27 +0000147 // If all inputs agree on the same kind, use it also for this action.
148 if (llvm::all_of(OKinds, [&](OffloadKind K) { return K == OKinds.front(); }))
149 OffloadingDeviceKind = OKinds.front();
150
151 // If we have a single dependency, inherit the architecture from it.
152 if (OKinds.size() == 1)
153 OffloadingArch = BArchs.front();
154
155 // Propagate info to the dependencies.
156 for (unsigned i = 0, e = getInputs().size(); i != e; ++i)
157 getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]);
158}
159
160OffloadAction::OffloadAction(const HostDependence &HDep,
161 const DeviceDependences &DDeps)
162 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
163 DevToolChains(DDeps.getToolChains()) {
164 // We use the kinds of the host dependence for this action.
165 OffloadingArch = HDep.getBoundArch();
166 ActiveOffloadKindMask = HDep.getOffloadKinds();
167 HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
168 HDep.getBoundArch());
169
170 // Add device inputs and propagate info to the device actions. Do work only if
171 // we have dependencies.
172 for (unsigned i = 0, e = DDeps.getActions().size(); i != e; ++i)
173 if (auto *A = DDeps.getActions()[i]) {
174 getInputs().push_back(A);
175 A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i],
176 DDeps.getBoundArchs()[i]);
177 }
178}
179
180void OffloadAction::doOnHostDependence(const OffloadActionWorkTy &Work) const {
181 if (!HostTC)
182 return;
183 assert(!getInputs().empty() && "No dependencies for offload action??");
184 auto *A = getInputs().front();
185 Work(A, HostTC, A->getOffloadingArch());
186}
187
188void OffloadAction::doOnEachDeviceDependence(
189 const OffloadActionWorkTy &Work) const {
190 auto I = getInputs().begin();
191 auto E = getInputs().end();
192 if (I == E)
193 return;
194
195 // We expect to have the same number of input dependences and device tool
196 // chains, except if we also have a host dependence. In that case we have one
197 // more dependence than we have device tool chains.
198 assert(getInputs().size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
199 "Sizes of action dependences and toolchains are not consistent!");
200
201 // Skip host action
202 if (HostTC)
203 ++I;
204
205 auto TI = DevToolChains.begin();
206 for (; I != E; ++I, ++TI)
207 Work(*I, *TI, (*I)->getOffloadingArch());
208}
209
210void OffloadAction::doOnEachDependence(const OffloadActionWorkTy &Work) const {
211 doOnHostDependence(Work);
212 doOnEachDeviceDependence(Work);
213}
214
215void OffloadAction::doOnEachDependence(bool IsHostDependence,
216 const OffloadActionWorkTy &Work) const {
217 if (IsHostDependence)
218 doOnHostDependence(Work);
219 else
220 doOnEachDeviceDependence(Work);
221}
222
223bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; }
224
225Action *OffloadAction::getHostDependence() const {
226 assert(hasHostDependence() && "Host dependence does not exist!");
227 assert(!getInputs().empty() && "No dependencies for offload action??");
228 return HostTC ? getInputs().front() : nullptr;
229}
230
231bool OffloadAction::hasSingleDeviceDependence(
232 bool DoNotConsiderHostActions) const {
233 if (DoNotConsiderHostActions)
234 return getInputs().size() == (HostTC ? 2 : 1);
235 return !HostTC && getInputs().size() == 1;
236}
237
238Action *
239OffloadAction::getSingleDeviceDependence(bool DoNotConsiderHostActions) const {
240 assert(hasSingleDeviceDependence(DoNotConsiderHostActions) &&
241 "Single device dependence does not exist!");
242 // The previous assert ensures the number of entries in getInputs() is
243 // consistent with what we are doing here.
244 return HostTC ? getInputs()[1] : getInputs().front();
245}
246
247void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC,
248 const char *BoundArch,
249 OffloadKind OKind) {
250 DeviceActions.push_back(&A);
251 DeviceToolChains.push_back(&TC);
252 DeviceBoundArchs.push_back(BoundArch);
253 DeviceOffloadKinds.push_back(OKind);
254}
255
256OffloadAction::HostDependence::HostDependence(Action &A, const ToolChain &TC,
257 const char *BoundArch,
258 const DeviceDependences &DDeps)
259 : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) {
260 for (auto K : DDeps.getOffloadKinds())
261 HostOffloadKinds |= K;
262}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000263
David Blaikie68e081d2011-12-20 02:48:34 +0000264void JobAction::anchor() {}
265
Justin Lebar41094612016-01-11 23:07:27 +0000266JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
267 : Action(Kind, Input, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000268
Mike Stump11289f42009-09-09 15:08:12 +0000269JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000270 : Action(Kind, Inputs, Type) {
271}
272
David Blaikie68e081d2011-12-20 02:48:34 +0000273void PreprocessJobAction::anchor() {}
274
Justin Lebar41094612016-01-11 23:07:27 +0000275PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
276 : JobAction(PreprocessJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000277
David Blaikie68e081d2011-12-20 02:48:34 +0000278void PrecompileJobAction::anchor() {}
279
Justin Lebar41094612016-01-11 23:07:27 +0000280PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
281 : JobAction(PrecompileJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000282
David Blaikie68e081d2011-12-20 02:48:34 +0000283void AnalyzeJobAction::anchor() {}
284
Justin Lebar41094612016-01-11 23:07:27 +0000285AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
286 : JobAction(AnalyzeJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000287
Ted Kremenekf7639e12012-03-06 20:06:33 +0000288void MigrateJobAction::anchor() {}
289
Justin Lebar41094612016-01-11 23:07:27 +0000290MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
291 : JobAction(MigrateJobClass, Input, OutputType) {}
Ted Kremenekf7639e12012-03-06 20:06:33 +0000292
David Blaikie68e081d2011-12-20 02:48:34 +0000293void CompileJobAction::anchor() {}
294
Justin Lebar41094612016-01-11 23:07:27 +0000295CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
296 : JobAction(CompileJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000297
Bob Wilson23a55f12014-12-21 07:00:00 +0000298void BackendJobAction::anchor() {}
299
Justin Lebar41094612016-01-11 23:07:27 +0000300BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType)
301 : JobAction(BackendJobClass, Input, OutputType) {}
Bob Wilson23a55f12014-12-21 07:00:00 +0000302
David Blaikie68e081d2011-12-20 02:48:34 +0000303void AssembleJobAction::anchor() {}
304
Justin Lebar41094612016-01-11 23:07:27 +0000305AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
306 : JobAction(AssembleJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000307
David Blaikie68e081d2011-12-20 02:48:34 +0000308void LinkJobAction::anchor() {}
309
Mike Stump11289f42009-09-09 15:08:12 +0000310LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000311 : JobAction(LinkJobClass, Inputs, Type) {
312}
313
David Blaikie68e081d2011-12-20 02:48:34 +0000314void LipoJobAction::anchor() {}
315
Mike Stump11289f42009-09-09 15:08:12 +0000316LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000317 : JobAction(LipoJobClass, Inputs, Type) {
318}
Daniel Dunbar88299622010-06-04 18:28:36 +0000319
David Blaikie68e081d2011-12-20 02:48:34 +0000320void DsymutilJobAction::anchor() {}
321
Daniel Dunbar88299622010-06-04 18:28:36 +0000322DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
323 : JobAction(DsymutilJobClass, Inputs, Type) {
324}
Eric Christopher551ef452011-08-23 17:56:55 +0000325
David Blaikie68e081d2011-12-20 02:48:34 +0000326void VerifyJobAction::anchor() {}
327
Justin Lebar41094612016-01-11 23:07:27 +0000328VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
329 types::ID Type)
330 : JobAction(Kind, Input, Type) {
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000331 assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
332 "ActionClass is not a valid VerifyJobAction");
333}
334
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000335void VerifyDebugInfoJobAction::anchor() {}
336
Justin Lebar41094612016-01-11 23:07:27 +0000337VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
338 types::ID Type)
339 : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {}
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000340
341void VerifyPCHJobAction::anchor() {}
342
Justin Lebar41094612016-01-11 23:07:27 +0000343VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
344 : VerifyJobAction(VerifyPCHJobClass, Input, Type) {}