blob: 90bc149fd3397ccb783841fe242f8c0283851ad3 [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";
Samuel Antao69d6f312016-10-27 17:50:43 +000039 case OffloadBundlingJobClass:
40 return "clang-offload-bundler";
Daniel Dunbar80665fb2009-03-13 12:17:08 +000041 }
Mike Stump11289f42009-09-09 15:08:12 +000042
David Blaikie83d382b2011-09-23 05:06:16 +000043 llvm_unreachable("invalid class");
Daniel Dunbar80665fb2009-03-13 12:17:08 +000044}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +000045
Samuel Antaod06239d2016-07-15 23:13:27 +000046void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch) {
47 // Offload action set its own kinds on their dependences.
48 if (Kind == OffloadClass)
49 return;
50
51 assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
52 "Setting device kind to a different device??");
53 assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??");
54 OffloadingDeviceKind = OKind;
55 OffloadingArch = OArch;
56
57 for (auto *A : Inputs)
58 A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch);
59}
60
61void Action::propagateHostOffloadInfo(unsigned OKinds, const char *OArch) {
62 // Offload action set its own kinds on their dependences.
63 if (Kind == OffloadClass)
64 return;
65
66 assert(OffloadingDeviceKind == OFK_None &&
67 "Setting a host kind in a device action.");
68 ActiveOffloadKindMask |= OKinds;
69 OffloadingArch = OArch;
70
71 for (auto *A : Inputs)
72 A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
73}
74
75void Action::propagateOffloadInfo(const Action *A) {
76 if (unsigned HK = A->getOffloadingHostActiveKinds())
77 propagateHostOffloadInfo(HK, A->getOffloadingArch());
78 else
79 propagateDeviceOffloadInfo(A->getOffloadingDeviceKind(),
80 A->getOffloadingArch());
81}
82
83std::string Action::getOffloadingKindPrefix() const {
84 switch (OffloadingDeviceKind) {
85 case OFK_None:
86 break;
87 case OFK_Host:
88 llvm_unreachable("Host kind is not an offloading device kind.");
89 break;
90 case OFK_Cuda:
91 return "device-cuda";
Samuel Antao39f9da22016-10-27 16:38:05 +000092 case OFK_OpenMP:
93 return "device-openmp";
Samuel Antaod06239d2016-07-15 23:13:27 +000094
95 // TODO: Add other programming models here.
96 }
97
98 if (!ActiveOffloadKindMask)
99 return "";
100
101 std::string Res("host");
102 if (ActiveOffloadKindMask & OFK_Cuda)
103 Res += "-cuda";
Samuel Antao39f9da22016-10-27 16:38:05 +0000104 if (ActiveOffloadKindMask & OFK_OpenMP)
105 Res += "-openmp";
Samuel Antaod06239d2016-07-15 23:13:27 +0000106
107 // TODO: Add other programming models here.
108
109 return Res;
110}
111
112std::string
Samuel Antao2fd32132016-07-15 23:51:21 +0000113Action::getOffloadingFileNamePrefix(llvm::StringRef NormalizedTriple) const {
Samuel Antaod06239d2016-07-15 23:13:27 +0000114 // A file prefix is only generated for device actions and consists of the
115 // offload kind and triple.
116 if (!OffloadingDeviceKind)
117 return "";
118
119 std::string Res("-");
120 Res += getOffloadingKindPrefix();
121 Res += "-";
122 Res += NormalizedTriple;
123 return Res;
124}
125
David Blaikie68e081d2011-12-20 02:48:34 +0000126void InputAction::anchor() {}
127
Mike Stump11289f42009-09-09 15:08:12 +0000128InputAction::InputAction(const Arg &_Input, types::ID _Type)
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000129 : Action(InputClass, _Type), Input(_Input) {
130}
131
David Blaikie68e081d2011-12-20 02:48:34 +0000132void BindArchAction::anchor() {}
133
Mehdi Amini087f1fb2016-10-07 22:03:03 +0000134BindArchAction::BindArchAction(Action *Input, llvm::StringRef ArchName)
135 : Action(BindArchClass, Input), ArchName(ArchName) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000136
Samuel Antaod06239d2016-07-15 23:13:27 +0000137void OffloadAction::anchor() {}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000138
Samuel Antaod06239d2016-07-15 23:13:27 +0000139OffloadAction::OffloadAction(const HostDependence &HDep)
140 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
141 OffloadingArch = HDep.getBoundArch();
142 ActiveOffloadKindMask = HDep.getOffloadKinds();
143 HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
144 HDep.getBoundArch());
Eric Christopher2a7248f2016-07-16 00:58:34 +0000145}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000146
Samuel Antaod06239d2016-07-15 23:13:27 +0000147OffloadAction::OffloadAction(const DeviceDependences &DDeps, types::ID Ty)
148 : Action(OffloadClass, DDeps.getActions(), Ty),
149 DevToolChains(DDeps.getToolChains()) {
150 auto &OKinds = DDeps.getOffloadKinds();
151 auto &BArchs = DDeps.getBoundArchs();
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000152
Samuel Antaod06239d2016-07-15 23:13:27 +0000153 // If all inputs agree on the same kind, use it also for this action.
154 if (llvm::all_of(OKinds, [&](OffloadKind K) { return K == OKinds.front(); }))
155 OffloadingDeviceKind = OKinds.front();
156
157 // If we have a single dependency, inherit the architecture from it.
158 if (OKinds.size() == 1)
159 OffloadingArch = BArchs.front();
160
161 // Propagate info to the dependencies.
162 for (unsigned i = 0, e = getInputs().size(); i != e; ++i)
163 getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]);
164}
165
166OffloadAction::OffloadAction(const HostDependence &HDep,
167 const DeviceDependences &DDeps)
168 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
169 DevToolChains(DDeps.getToolChains()) {
170 // We use the kinds of the host dependence for this action.
171 OffloadingArch = HDep.getBoundArch();
172 ActiveOffloadKindMask = HDep.getOffloadKinds();
173 HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
174 HDep.getBoundArch());
175
176 // Add device inputs and propagate info to the device actions. Do work only if
177 // we have dependencies.
178 for (unsigned i = 0, e = DDeps.getActions().size(); i != e; ++i)
179 if (auto *A = DDeps.getActions()[i]) {
180 getInputs().push_back(A);
181 A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i],
182 DDeps.getBoundArchs()[i]);
183 }
184}
185
186void OffloadAction::doOnHostDependence(const OffloadActionWorkTy &Work) const {
187 if (!HostTC)
188 return;
189 assert(!getInputs().empty() && "No dependencies for offload action??");
190 auto *A = getInputs().front();
191 Work(A, HostTC, A->getOffloadingArch());
192}
193
194void OffloadAction::doOnEachDeviceDependence(
195 const OffloadActionWorkTy &Work) const {
196 auto I = getInputs().begin();
197 auto E = getInputs().end();
198 if (I == E)
199 return;
200
201 // We expect to have the same number of input dependences and device tool
202 // chains, except if we also have a host dependence. In that case we have one
203 // more dependence than we have device tool chains.
204 assert(getInputs().size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
205 "Sizes of action dependences and toolchains are not consistent!");
206
207 // Skip host action
208 if (HostTC)
209 ++I;
210
211 auto TI = DevToolChains.begin();
212 for (; I != E; ++I, ++TI)
213 Work(*I, *TI, (*I)->getOffloadingArch());
214}
215
216void OffloadAction::doOnEachDependence(const OffloadActionWorkTy &Work) const {
217 doOnHostDependence(Work);
218 doOnEachDeviceDependence(Work);
219}
220
221void OffloadAction::doOnEachDependence(bool IsHostDependence,
222 const OffloadActionWorkTy &Work) const {
223 if (IsHostDependence)
224 doOnHostDependence(Work);
225 else
226 doOnEachDeviceDependence(Work);
227}
228
229bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; }
230
231Action *OffloadAction::getHostDependence() const {
232 assert(hasHostDependence() && "Host dependence does not exist!");
233 assert(!getInputs().empty() && "No dependencies for offload action??");
234 return HostTC ? getInputs().front() : nullptr;
235}
236
237bool OffloadAction::hasSingleDeviceDependence(
238 bool DoNotConsiderHostActions) const {
239 if (DoNotConsiderHostActions)
240 return getInputs().size() == (HostTC ? 2 : 1);
241 return !HostTC && getInputs().size() == 1;
242}
243
244Action *
245OffloadAction::getSingleDeviceDependence(bool DoNotConsiderHostActions) const {
246 assert(hasSingleDeviceDependence(DoNotConsiderHostActions) &&
247 "Single device dependence does not exist!");
248 // The previous assert ensures the number of entries in getInputs() is
249 // consistent with what we are doing here.
250 return HostTC ? getInputs()[1] : getInputs().front();
251}
252
253void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC,
254 const char *BoundArch,
255 OffloadKind OKind) {
256 DeviceActions.push_back(&A);
257 DeviceToolChains.push_back(&TC);
258 DeviceBoundArchs.push_back(BoundArch);
259 DeviceOffloadKinds.push_back(OKind);
260}
261
262OffloadAction::HostDependence::HostDependence(Action &A, const ToolChain &TC,
263 const char *BoundArch,
264 const DeviceDependences &DDeps)
265 : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) {
266 for (auto K : DDeps.getOffloadKinds())
267 HostOffloadKinds |= K;
268}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000269
David Blaikie68e081d2011-12-20 02:48:34 +0000270void JobAction::anchor() {}
271
Justin Lebar41094612016-01-11 23:07:27 +0000272JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
273 : Action(Kind, Input, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000274
Mike Stump11289f42009-09-09 15:08:12 +0000275JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000276 : Action(Kind, Inputs, Type) {
277}
278
David Blaikie68e081d2011-12-20 02:48:34 +0000279void PreprocessJobAction::anchor() {}
280
Justin Lebar41094612016-01-11 23:07:27 +0000281PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
282 : JobAction(PreprocessJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000283
David Blaikie68e081d2011-12-20 02:48:34 +0000284void PrecompileJobAction::anchor() {}
285
Justin Lebar41094612016-01-11 23:07:27 +0000286PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
287 : JobAction(PrecompileJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000288
David Blaikie68e081d2011-12-20 02:48:34 +0000289void AnalyzeJobAction::anchor() {}
290
Justin Lebar41094612016-01-11 23:07:27 +0000291AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
292 : JobAction(AnalyzeJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000293
Ted Kremenekf7639e12012-03-06 20:06:33 +0000294void MigrateJobAction::anchor() {}
295
Justin Lebar41094612016-01-11 23:07:27 +0000296MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
297 : JobAction(MigrateJobClass, Input, OutputType) {}
Ted Kremenekf7639e12012-03-06 20:06:33 +0000298
David Blaikie68e081d2011-12-20 02:48:34 +0000299void CompileJobAction::anchor() {}
300
Justin Lebar41094612016-01-11 23:07:27 +0000301CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
302 : JobAction(CompileJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000303
Bob Wilson23a55f12014-12-21 07:00:00 +0000304void BackendJobAction::anchor() {}
305
Justin Lebar41094612016-01-11 23:07:27 +0000306BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType)
307 : JobAction(BackendJobClass, Input, OutputType) {}
Bob Wilson23a55f12014-12-21 07:00:00 +0000308
David Blaikie68e081d2011-12-20 02:48:34 +0000309void AssembleJobAction::anchor() {}
310
Justin Lebar41094612016-01-11 23:07:27 +0000311AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
312 : JobAction(AssembleJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000313
David Blaikie68e081d2011-12-20 02:48:34 +0000314void LinkJobAction::anchor() {}
315
Mike Stump11289f42009-09-09 15:08:12 +0000316LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000317 : JobAction(LinkJobClass, Inputs, Type) {
318}
319
David Blaikie68e081d2011-12-20 02:48:34 +0000320void LipoJobAction::anchor() {}
321
Mike Stump11289f42009-09-09 15:08:12 +0000322LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000323 : JobAction(LipoJobClass, Inputs, Type) {
324}
Daniel Dunbar88299622010-06-04 18:28:36 +0000325
David Blaikie68e081d2011-12-20 02:48:34 +0000326void DsymutilJobAction::anchor() {}
327
Daniel Dunbar88299622010-06-04 18:28:36 +0000328DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
329 : JobAction(DsymutilJobClass, Inputs, Type) {
330}
Eric Christopher551ef452011-08-23 17:56:55 +0000331
David Blaikie68e081d2011-12-20 02:48:34 +0000332void VerifyJobAction::anchor() {}
333
Justin Lebar41094612016-01-11 23:07:27 +0000334VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
335 types::ID Type)
336 : JobAction(Kind, Input, Type) {
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000337 assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
338 "ActionClass is not a valid VerifyJobAction");
339}
340
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000341void VerifyDebugInfoJobAction::anchor() {}
342
Justin Lebar41094612016-01-11 23:07:27 +0000343VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
344 types::ID Type)
345 : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {}
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000346
347void VerifyPCHJobAction::anchor() {}
348
Justin Lebar41094612016-01-11 23:07:27 +0000349VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
350 : VerifyJobAction(VerifyPCHJobClass, Input, Type) {}
Samuel Antao69d6f312016-10-27 17:50:43 +0000351
352void OffloadBundlingJobAction::anchor() {}
353
354OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs)
355 : JobAction(OffloadBundlingJobClass, Inputs, Inputs.front()->getType()) {}