blob: d4c7040a233c79b300c88eefbcdec32b21605c12 [file] [log] [blame]
Eugene Zelenko5e4511c2018-03-20 21:08:59 +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"
David Blaikie79000202011-09-23 05:57:42 +000011#include "llvm/Support/ErrorHandling.h"
Daniel Dunbarf479c122009-03-12 18:40:18 +000012#include <cassert>
Eugene Zelenko5e4511c2018-03-20 21:08:59 +000013#include <string>
14
15using namespace clang;
16using namespace driver;
Reid Kleckner898229a2013-06-14 17:17:23 +000017using namespace llvm::opt;
Daniel Dunbarf479c122009-03-12 18:40:18 +000018
Eugene Zelenko5e4511c2018-03-20 21:08:59 +000019Action::~Action() = default;
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";
Richard Smithcd35eff2018-09-15 01:21:16 +000029 case HeaderModulePrecompileJobClass: return "header-module-precompiler";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000030 case AnalyzeJobClass: return "analyzer";
Ted Kremenekf7639e12012-03-06 20:06:33 +000031 case MigrateJobClass: return "migrator";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000032 case CompileJobClass: return "compiler";
Bob Wilson23a55f12014-12-21 07:00:00 +000033 case BackendJobClass: return "backend";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000034 case AssembleJobClass: return "assembler";
35 case LinkJobClass: return "linker";
Daniel Dunbar80665fb2009-03-13 12:17:08 +000036 case LipoJobClass: return "lipo";
Daniel Dunbar88299622010-06-04 18:28:36 +000037 case DsymutilJobClass: return "dsymutil";
Ben Langmuir9b9a8d32014-02-06 18:53:25 +000038 case VerifyDebugInfoJobClass: return "verify-debug-info";
39 case VerifyPCHJobClass: return "verify-pch";
Samuel Antao69d6f312016-10-27 17:50:43 +000040 case OffloadBundlingJobClass:
41 return "clang-offload-bundler";
Samuel Antaofab4f372016-10-27 18:00:51 +000042 case OffloadUnbundlingJobClass:
43 return "clang-offload-unbundler";
Daniel Dunbar80665fb2009-03-13 12:17:08 +000044 }
Mike Stump11289f42009-09-09 15:08:12 +000045
David Blaikie83d382b2011-09-23 05:06:16 +000046 llvm_unreachable("invalid class");
Daniel Dunbar80665fb2009-03-13 12:17:08 +000047}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +000048
Samuel Antaod06239d2016-07-15 23:13:27 +000049void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch) {
50 // Offload action set its own kinds on their dependences.
51 if (Kind == OffloadClass)
52 return;
Samuel Antaofab4f372016-10-27 18:00:51 +000053 // Unbundling actions use the host kinds.
54 if (Kind == OffloadUnbundlingJobClass)
55 return;
Samuel Antaod06239d2016-07-15 23:13:27 +000056
57 assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
58 "Setting device kind to a different device??");
59 assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??");
60 OffloadingDeviceKind = OKind;
61 OffloadingArch = OArch;
62
63 for (auto *A : Inputs)
64 A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch);
65}
66
67void Action::propagateHostOffloadInfo(unsigned OKinds, const char *OArch) {
68 // Offload action set its own kinds on their dependences.
69 if (Kind == OffloadClass)
70 return;
71
72 assert(OffloadingDeviceKind == OFK_None &&
73 "Setting a host kind in a device action.");
74 ActiveOffloadKindMask |= OKinds;
75 OffloadingArch = OArch;
76
77 for (auto *A : Inputs)
78 A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
79}
80
81void Action::propagateOffloadInfo(const Action *A) {
82 if (unsigned HK = A->getOffloadingHostActiveKinds())
83 propagateHostOffloadInfo(HK, A->getOffloadingArch());
84 else
85 propagateDeviceOffloadInfo(A->getOffloadingDeviceKind(),
86 A->getOffloadingArch());
87}
88
89std::string Action::getOffloadingKindPrefix() const {
90 switch (OffloadingDeviceKind) {
91 case OFK_None:
92 break;
93 case OFK_Host:
94 llvm_unreachable("Host kind is not an offloading device kind.");
95 break;
96 case OFK_Cuda:
97 return "device-cuda";
Samuel Antao39f9da22016-10-27 16:38:05 +000098 case OFK_OpenMP:
99 return "device-openmp";
Yaxun Liu398612b2018-05-08 21:02:12 +0000100 case OFK_HIP:
101 return "device-hip";
Samuel Antaod06239d2016-07-15 23:13:27 +0000102
103 // TODO: Add other programming models here.
104 }
105
106 if (!ActiveOffloadKindMask)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000107 return {};
Samuel Antaod06239d2016-07-15 23:13:27 +0000108
109 std::string Res("host");
Yaxun Liu398612b2018-05-08 21:02:12 +0000110 assert(!((ActiveOffloadKindMask & OFK_Cuda) &&
111 (ActiveOffloadKindMask & OFK_HIP)) &&
112 "Cannot offload CUDA and HIP at the same time");
Samuel Antaod06239d2016-07-15 23:13:27 +0000113 if (ActiveOffloadKindMask & OFK_Cuda)
114 Res += "-cuda";
Yaxun Liu398612b2018-05-08 21:02:12 +0000115 if (ActiveOffloadKindMask & OFK_HIP)
116 Res += "-hip";
Samuel Antao39f9da22016-10-27 16:38:05 +0000117 if (ActiveOffloadKindMask & OFK_OpenMP)
118 Res += "-openmp";
Samuel Antaod06239d2016-07-15 23:13:27 +0000119
120 // TODO: Add other programming models here.
121
122 return Res;
123}
124
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000125/// Return a string that can be used as prefix in order to generate unique files
126/// for each offloading kind.
Samuel Antaod06239d2016-07-15 23:13:27 +0000127std::string
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000128Action::GetOffloadingFileNamePrefix(OffloadKind Kind,
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000129 StringRef NormalizedTriple,
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000130 bool CreatePrefixForHost) {
131 // Don't generate prefix for host actions unless required.
132 if (!CreatePrefixForHost && (Kind == OFK_None || Kind == OFK_Host))
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000133 return {};
Samuel Antaod06239d2016-07-15 23:13:27 +0000134
135 std::string Res("-");
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000136 Res += GetOffloadKindName(Kind);
Samuel Antaod06239d2016-07-15 23:13:27 +0000137 Res += "-";
138 Res += NormalizedTriple;
139 return Res;
140}
141
Samuel Antao7cab8f12016-10-27 18:04:42 +0000142/// Return a string with the offload kind name. If that is not defined, we
143/// assume 'host'.
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000144StringRef Action::GetOffloadKindName(OffloadKind Kind) {
Samuel Antao7cab8f12016-10-27 18:04:42 +0000145 switch (Kind) {
146 case OFK_None:
147 case OFK_Host:
148 return "host";
149 case OFK_Cuda:
150 return "cuda";
151 case OFK_OpenMP:
152 return "openmp";
Yaxun Liu398612b2018-05-08 21:02:12 +0000153 case OFK_HIP:
154 return "hip";
Samuel Antao7cab8f12016-10-27 18:04:42 +0000155
156 // TODO: Add other programming models here.
157 }
Simon Pilgrim3315a6a2016-10-28 10:09:35 +0000158
159 llvm_unreachable("invalid offload kind");
Samuel Antao7cab8f12016-10-27 18:04:42 +0000160}
161
David Blaikie68e081d2011-12-20 02:48:34 +0000162void InputAction::anchor() {}
163
Mike Stump11289f42009-09-09 15:08:12 +0000164InputAction::InputAction(const Arg &_Input, types::ID _Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000165 : Action(InputClass, _Type), Input(_Input) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000166
David Blaikie68e081d2011-12-20 02:48:34 +0000167void BindArchAction::anchor() {}
168
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000169BindArchAction::BindArchAction(Action *Input, StringRef ArchName)
Mehdi Amini087f1fb2016-10-07 22:03:03 +0000170 : Action(BindArchClass, Input), ArchName(ArchName) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000171
Samuel Antaod06239d2016-07-15 23:13:27 +0000172void OffloadAction::anchor() {}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000173
Samuel Antaod06239d2016-07-15 23:13:27 +0000174OffloadAction::OffloadAction(const HostDependence &HDep)
175 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
176 OffloadingArch = HDep.getBoundArch();
177 ActiveOffloadKindMask = HDep.getOffloadKinds();
178 HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
179 HDep.getBoundArch());
Eric Christopher2a7248f2016-07-16 00:58:34 +0000180}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000181
Samuel Antaod06239d2016-07-15 23:13:27 +0000182OffloadAction::OffloadAction(const DeviceDependences &DDeps, types::ID Ty)
183 : Action(OffloadClass, DDeps.getActions(), Ty),
184 DevToolChains(DDeps.getToolChains()) {
185 auto &OKinds = DDeps.getOffloadKinds();
186 auto &BArchs = DDeps.getBoundArchs();
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000187
Samuel Antaod06239d2016-07-15 23:13:27 +0000188 // If all inputs agree on the same kind, use it also for this action.
189 if (llvm::all_of(OKinds, [&](OffloadKind K) { return K == OKinds.front(); }))
190 OffloadingDeviceKind = OKinds.front();
191
192 // If we have a single dependency, inherit the architecture from it.
193 if (OKinds.size() == 1)
194 OffloadingArch = BArchs.front();
195
196 // Propagate info to the dependencies.
197 for (unsigned i = 0, e = getInputs().size(); i != e; ++i)
198 getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]);
199}
200
201OffloadAction::OffloadAction(const HostDependence &HDep,
202 const DeviceDependences &DDeps)
203 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
204 DevToolChains(DDeps.getToolChains()) {
205 // We use the kinds of the host dependence for this action.
206 OffloadingArch = HDep.getBoundArch();
207 ActiveOffloadKindMask = HDep.getOffloadKinds();
208 HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
209 HDep.getBoundArch());
210
211 // Add device inputs and propagate info to the device actions. Do work only if
212 // we have dependencies.
213 for (unsigned i = 0, e = DDeps.getActions().size(); i != e; ++i)
214 if (auto *A = DDeps.getActions()[i]) {
215 getInputs().push_back(A);
216 A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i],
217 DDeps.getBoundArchs()[i]);
218 }
219}
220
221void OffloadAction::doOnHostDependence(const OffloadActionWorkTy &Work) const {
222 if (!HostTC)
223 return;
224 assert(!getInputs().empty() && "No dependencies for offload action??");
225 auto *A = getInputs().front();
226 Work(A, HostTC, A->getOffloadingArch());
227}
228
229void OffloadAction::doOnEachDeviceDependence(
230 const OffloadActionWorkTy &Work) const {
231 auto I = getInputs().begin();
232 auto E = getInputs().end();
233 if (I == E)
234 return;
235
236 // We expect to have the same number of input dependences and device tool
237 // chains, except if we also have a host dependence. In that case we have one
238 // more dependence than we have device tool chains.
239 assert(getInputs().size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
240 "Sizes of action dependences and toolchains are not consistent!");
241
242 // Skip host action
243 if (HostTC)
244 ++I;
245
246 auto TI = DevToolChains.begin();
247 for (; I != E; ++I, ++TI)
248 Work(*I, *TI, (*I)->getOffloadingArch());
249}
250
251void OffloadAction::doOnEachDependence(const OffloadActionWorkTy &Work) const {
252 doOnHostDependence(Work);
253 doOnEachDeviceDependence(Work);
254}
255
256void OffloadAction::doOnEachDependence(bool IsHostDependence,
257 const OffloadActionWorkTy &Work) const {
258 if (IsHostDependence)
259 doOnHostDependence(Work);
260 else
261 doOnEachDeviceDependence(Work);
262}
263
264bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; }
265
266Action *OffloadAction::getHostDependence() const {
267 assert(hasHostDependence() && "Host dependence does not exist!");
268 assert(!getInputs().empty() && "No dependencies for offload action??");
269 return HostTC ? getInputs().front() : nullptr;
270}
271
272bool OffloadAction::hasSingleDeviceDependence(
273 bool DoNotConsiderHostActions) const {
274 if (DoNotConsiderHostActions)
275 return getInputs().size() == (HostTC ? 2 : 1);
276 return !HostTC && getInputs().size() == 1;
277}
278
279Action *
280OffloadAction::getSingleDeviceDependence(bool DoNotConsiderHostActions) const {
281 assert(hasSingleDeviceDependence(DoNotConsiderHostActions) &&
282 "Single device dependence does not exist!");
283 // The previous assert ensures the number of entries in getInputs() is
284 // consistent with what we are doing here.
285 return HostTC ? getInputs()[1] : getInputs().front();
286}
287
288void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC,
289 const char *BoundArch,
290 OffloadKind OKind) {
291 DeviceActions.push_back(&A);
292 DeviceToolChains.push_back(&TC);
293 DeviceBoundArchs.push_back(BoundArch);
294 DeviceOffloadKinds.push_back(OKind);
295}
296
297OffloadAction::HostDependence::HostDependence(Action &A, const ToolChain &TC,
298 const char *BoundArch,
299 const DeviceDependences &DDeps)
300 : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) {
301 for (auto K : DDeps.getOffloadKinds())
302 HostOffloadKinds |= K;
303}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000304
David Blaikie68e081d2011-12-20 02:48:34 +0000305void JobAction::anchor() {}
306
Justin Lebar41094612016-01-11 23:07:27 +0000307JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
308 : Action(Kind, Input, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000309
Mike Stump11289f42009-09-09 15:08:12 +0000310JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000311 : Action(Kind, Inputs, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000312
David Blaikie68e081d2011-12-20 02:48:34 +0000313void PreprocessJobAction::anchor() {}
314
Justin Lebar41094612016-01-11 23:07:27 +0000315PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
316 : JobAction(PreprocessJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000317
David Blaikie68e081d2011-12-20 02:48:34 +0000318void PrecompileJobAction::anchor() {}
319
Justin Lebar41094612016-01-11 23:07:27 +0000320PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
321 : JobAction(PrecompileJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000322
Richard Smithcd35eff2018-09-15 01:21:16 +0000323PrecompileJobAction::PrecompileJobAction(ActionClass Kind, Action *Input,
324 types::ID OutputType)
325 : JobAction(Kind, Input, OutputType) {
326 assert(isa<PrecompileJobAction>((Action*)this) && "invalid action kind");
327}
328
329void HeaderModulePrecompileJobAction::anchor() {}
330
331HeaderModulePrecompileJobAction::HeaderModulePrecompileJobAction(
332 Action *Input, types::ID OutputType, const char *ModuleName)
333 : PrecompileJobAction(HeaderModulePrecompileJobClass, Input, OutputType),
334 ModuleName(ModuleName) {}
335
David Blaikie68e081d2011-12-20 02:48:34 +0000336void AnalyzeJobAction::anchor() {}
337
Justin Lebar41094612016-01-11 23:07:27 +0000338AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
339 : JobAction(AnalyzeJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000340
Ted Kremenekf7639e12012-03-06 20:06:33 +0000341void MigrateJobAction::anchor() {}
342
Justin Lebar41094612016-01-11 23:07:27 +0000343MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
344 : JobAction(MigrateJobClass, Input, OutputType) {}
Ted Kremenekf7639e12012-03-06 20:06:33 +0000345
David Blaikie68e081d2011-12-20 02:48:34 +0000346void CompileJobAction::anchor() {}
347
Justin Lebar41094612016-01-11 23:07:27 +0000348CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
349 : JobAction(CompileJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000350
Bob Wilson23a55f12014-12-21 07:00:00 +0000351void BackendJobAction::anchor() {}
352
Justin Lebar41094612016-01-11 23:07:27 +0000353BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType)
354 : JobAction(BackendJobClass, Input, OutputType) {}
Bob Wilson23a55f12014-12-21 07:00:00 +0000355
David Blaikie68e081d2011-12-20 02:48:34 +0000356void AssembleJobAction::anchor() {}
357
Justin Lebar41094612016-01-11 23:07:27 +0000358AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
359 : JobAction(AssembleJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000360
David Blaikie68e081d2011-12-20 02:48:34 +0000361void LinkJobAction::anchor() {}
362
Mike Stump11289f42009-09-09 15:08:12 +0000363LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000364 : JobAction(LinkJobClass, Inputs, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000365
David Blaikie68e081d2011-12-20 02:48:34 +0000366void LipoJobAction::anchor() {}
367
Mike Stump11289f42009-09-09 15:08:12 +0000368LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000369 : JobAction(LipoJobClass, Inputs, Type) {}
Daniel Dunbar88299622010-06-04 18:28:36 +0000370
David Blaikie68e081d2011-12-20 02:48:34 +0000371void DsymutilJobAction::anchor() {}
372
Daniel Dunbar88299622010-06-04 18:28:36 +0000373DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000374 : JobAction(DsymutilJobClass, Inputs, Type) {}
Eric Christopher551ef452011-08-23 17:56:55 +0000375
David Blaikie68e081d2011-12-20 02:48:34 +0000376void VerifyJobAction::anchor() {}
377
Justin Lebar41094612016-01-11 23:07:27 +0000378VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
379 types::ID Type)
380 : JobAction(Kind, Input, Type) {
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000381 assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
382 "ActionClass is not a valid VerifyJobAction");
383}
384
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000385void VerifyDebugInfoJobAction::anchor() {}
386
Justin Lebar41094612016-01-11 23:07:27 +0000387VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
388 types::ID Type)
389 : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {}
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000390
391void VerifyPCHJobAction::anchor() {}
392
Justin Lebar41094612016-01-11 23:07:27 +0000393VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
394 : VerifyJobAction(VerifyPCHJobClass, Input, Type) {}
Samuel Antao69d6f312016-10-27 17:50:43 +0000395
396void OffloadBundlingJobAction::anchor() {}
397
398OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs)
Yaxun Liuac8ccd52018-08-28 21:09:09 +0000399 : JobAction(OffloadBundlingJobClass, Inputs, Inputs.back()->getType()) {}
Samuel Antaofab4f372016-10-27 18:00:51 +0000400
401void OffloadUnbundlingJobAction::anchor() {}
402
403OffloadUnbundlingJobAction::OffloadUnbundlingJobAction(Action *Input)
404 : JobAction(OffloadUnbundlingJobClass, Input, Input->getType()) {}