blob: f90904387511e75a39089009ce7a4dc5743562e2 [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";
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";
Samuel Antaofab4f372016-10-27 18:00:51 +000041 case OffloadUnbundlingJobClass:
42 return "clang-offload-unbundler";
Daniel Dunbar80665fb2009-03-13 12:17:08 +000043 }
Mike Stump11289f42009-09-09 15:08:12 +000044
David Blaikie83d382b2011-09-23 05:06:16 +000045 llvm_unreachable("invalid class");
Daniel Dunbar80665fb2009-03-13 12:17:08 +000046}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +000047
Samuel Antaod06239d2016-07-15 23:13:27 +000048void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch) {
49 // Offload action set its own kinds on their dependences.
50 if (Kind == OffloadClass)
51 return;
Samuel Antaofab4f372016-10-27 18:00:51 +000052 // Unbundling actions use the host kinds.
53 if (Kind == OffloadUnbundlingJobClass)
54 return;
Samuel Antaod06239d2016-07-15 23:13:27 +000055
56 assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
57 "Setting device kind to a different device??");
58 assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??");
59 OffloadingDeviceKind = OKind;
60 OffloadingArch = OArch;
61
62 for (auto *A : Inputs)
63 A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch);
64}
65
66void Action::propagateHostOffloadInfo(unsigned OKinds, const char *OArch) {
67 // Offload action set its own kinds on their dependences.
68 if (Kind == OffloadClass)
69 return;
70
71 assert(OffloadingDeviceKind == OFK_None &&
72 "Setting a host kind in a device action.");
73 ActiveOffloadKindMask |= OKinds;
74 OffloadingArch = OArch;
75
76 for (auto *A : Inputs)
77 A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
78}
79
80void Action::propagateOffloadInfo(const Action *A) {
81 if (unsigned HK = A->getOffloadingHostActiveKinds())
82 propagateHostOffloadInfo(HK, A->getOffloadingArch());
83 else
84 propagateDeviceOffloadInfo(A->getOffloadingDeviceKind(),
85 A->getOffloadingArch());
86}
87
88std::string Action::getOffloadingKindPrefix() const {
89 switch (OffloadingDeviceKind) {
90 case OFK_None:
91 break;
92 case OFK_Host:
93 llvm_unreachable("Host kind is not an offloading device kind.");
94 break;
95 case OFK_Cuda:
96 return "device-cuda";
Samuel Antao39f9da22016-10-27 16:38:05 +000097 case OFK_OpenMP:
98 return "device-openmp";
Yaxun Liu398612b2018-05-08 21:02:12 +000099 case OFK_HIP:
100 return "device-hip";
Samuel Antaod06239d2016-07-15 23:13:27 +0000101
102 // TODO: Add other programming models here.
103 }
104
105 if (!ActiveOffloadKindMask)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000106 return {};
Samuel Antaod06239d2016-07-15 23:13:27 +0000107
108 std::string Res("host");
Yaxun Liu398612b2018-05-08 21:02:12 +0000109 assert(!((ActiveOffloadKindMask & OFK_Cuda) &&
110 (ActiveOffloadKindMask & OFK_HIP)) &&
111 "Cannot offload CUDA and HIP at the same time");
Samuel Antaod06239d2016-07-15 23:13:27 +0000112 if (ActiveOffloadKindMask & OFK_Cuda)
113 Res += "-cuda";
Yaxun Liu398612b2018-05-08 21:02:12 +0000114 if (ActiveOffloadKindMask & OFK_HIP)
115 Res += "-hip";
Samuel Antao39f9da22016-10-27 16:38:05 +0000116 if (ActiveOffloadKindMask & OFK_OpenMP)
117 Res += "-openmp";
Samuel Antaod06239d2016-07-15 23:13:27 +0000118
119 // TODO: Add other programming models here.
120
121 return Res;
122}
123
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000124/// Return a string that can be used as prefix in order to generate unique files
125/// for each offloading kind.
Samuel Antaod06239d2016-07-15 23:13:27 +0000126std::string
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000127Action::GetOffloadingFileNamePrefix(OffloadKind Kind,
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000128 StringRef NormalizedTriple,
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000129 bool CreatePrefixForHost) {
130 // Don't generate prefix for host actions unless required.
131 if (!CreatePrefixForHost && (Kind == OFK_None || Kind == OFK_Host))
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000132 return {};
Samuel Antaod06239d2016-07-15 23:13:27 +0000133
134 std::string Res("-");
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000135 Res += GetOffloadKindName(Kind);
Samuel Antaod06239d2016-07-15 23:13:27 +0000136 Res += "-";
137 Res += NormalizedTriple;
138 return Res;
139}
140
Samuel Antao7cab8f12016-10-27 18:04:42 +0000141/// Return a string with the offload kind name. If that is not defined, we
142/// assume 'host'.
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000143StringRef Action::GetOffloadKindName(OffloadKind Kind) {
Samuel Antao7cab8f12016-10-27 18:04:42 +0000144 switch (Kind) {
145 case OFK_None:
146 case OFK_Host:
147 return "host";
148 case OFK_Cuda:
149 return "cuda";
150 case OFK_OpenMP:
151 return "openmp";
Yaxun Liu398612b2018-05-08 21:02:12 +0000152 case OFK_HIP:
153 return "hip";
Samuel Antao7cab8f12016-10-27 18:04:42 +0000154
155 // TODO: Add other programming models here.
156 }
Simon Pilgrim3315a6a2016-10-28 10:09:35 +0000157
158 llvm_unreachable("invalid offload kind");
Samuel Antao7cab8f12016-10-27 18:04:42 +0000159}
160
David Blaikie68e081d2011-12-20 02:48:34 +0000161void InputAction::anchor() {}
162
Mike Stump11289f42009-09-09 15:08:12 +0000163InputAction::InputAction(const Arg &_Input, types::ID _Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000164 : Action(InputClass, _Type), Input(_Input) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000165
David Blaikie68e081d2011-12-20 02:48:34 +0000166void BindArchAction::anchor() {}
167
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000168BindArchAction::BindArchAction(Action *Input, StringRef ArchName)
Mehdi Amini087f1fb2016-10-07 22:03:03 +0000169 : Action(BindArchClass, Input), ArchName(ArchName) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000170
Samuel Antaod06239d2016-07-15 23:13:27 +0000171void OffloadAction::anchor() {}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000172
Samuel Antaod06239d2016-07-15 23:13:27 +0000173OffloadAction::OffloadAction(const HostDependence &HDep)
174 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
175 OffloadingArch = HDep.getBoundArch();
176 ActiveOffloadKindMask = HDep.getOffloadKinds();
177 HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
178 HDep.getBoundArch());
Eric Christopher2a7248f2016-07-16 00:58:34 +0000179}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000180
Samuel Antaod06239d2016-07-15 23:13:27 +0000181OffloadAction::OffloadAction(const DeviceDependences &DDeps, types::ID Ty)
182 : Action(OffloadClass, DDeps.getActions(), Ty),
183 DevToolChains(DDeps.getToolChains()) {
184 auto &OKinds = DDeps.getOffloadKinds();
185 auto &BArchs = DDeps.getBoundArchs();
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000186
Samuel Antaod06239d2016-07-15 23:13:27 +0000187 // If all inputs agree on the same kind, use it also for this action.
188 if (llvm::all_of(OKinds, [&](OffloadKind K) { return K == OKinds.front(); }))
189 OffloadingDeviceKind = OKinds.front();
190
191 // If we have a single dependency, inherit the architecture from it.
192 if (OKinds.size() == 1)
193 OffloadingArch = BArchs.front();
194
195 // Propagate info to the dependencies.
196 for (unsigned i = 0, e = getInputs().size(); i != e; ++i)
197 getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]);
198}
199
200OffloadAction::OffloadAction(const HostDependence &HDep,
201 const DeviceDependences &DDeps)
202 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
203 DevToolChains(DDeps.getToolChains()) {
204 // We use the kinds of the host dependence for this action.
205 OffloadingArch = HDep.getBoundArch();
206 ActiveOffloadKindMask = HDep.getOffloadKinds();
207 HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
208 HDep.getBoundArch());
209
210 // Add device inputs and propagate info to the device actions. Do work only if
211 // we have dependencies.
212 for (unsigned i = 0, e = DDeps.getActions().size(); i != e; ++i)
213 if (auto *A = DDeps.getActions()[i]) {
214 getInputs().push_back(A);
215 A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i],
216 DDeps.getBoundArchs()[i]);
217 }
218}
219
220void OffloadAction::doOnHostDependence(const OffloadActionWorkTy &Work) const {
221 if (!HostTC)
222 return;
223 assert(!getInputs().empty() && "No dependencies for offload action??");
224 auto *A = getInputs().front();
225 Work(A, HostTC, A->getOffloadingArch());
226}
227
228void OffloadAction::doOnEachDeviceDependence(
229 const OffloadActionWorkTy &Work) const {
230 auto I = getInputs().begin();
231 auto E = getInputs().end();
232 if (I == E)
233 return;
234
235 // We expect to have the same number of input dependences and device tool
236 // chains, except if we also have a host dependence. In that case we have one
237 // more dependence than we have device tool chains.
238 assert(getInputs().size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
239 "Sizes of action dependences and toolchains are not consistent!");
240
241 // Skip host action
242 if (HostTC)
243 ++I;
244
245 auto TI = DevToolChains.begin();
246 for (; I != E; ++I, ++TI)
247 Work(*I, *TI, (*I)->getOffloadingArch());
248}
249
250void OffloadAction::doOnEachDependence(const OffloadActionWorkTy &Work) const {
251 doOnHostDependence(Work);
252 doOnEachDeviceDependence(Work);
253}
254
255void OffloadAction::doOnEachDependence(bool IsHostDependence,
256 const OffloadActionWorkTy &Work) const {
257 if (IsHostDependence)
258 doOnHostDependence(Work);
259 else
260 doOnEachDeviceDependence(Work);
261}
262
263bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; }
264
265Action *OffloadAction::getHostDependence() const {
266 assert(hasHostDependence() && "Host dependence does not exist!");
267 assert(!getInputs().empty() && "No dependencies for offload action??");
268 return HostTC ? getInputs().front() : nullptr;
269}
270
271bool OffloadAction::hasSingleDeviceDependence(
272 bool DoNotConsiderHostActions) const {
273 if (DoNotConsiderHostActions)
274 return getInputs().size() == (HostTC ? 2 : 1);
275 return !HostTC && getInputs().size() == 1;
276}
277
278Action *
279OffloadAction::getSingleDeviceDependence(bool DoNotConsiderHostActions) const {
280 assert(hasSingleDeviceDependence(DoNotConsiderHostActions) &&
281 "Single device dependence does not exist!");
282 // The previous assert ensures the number of entries in getInputs() is
283 // consistent with what we are doing here.
284 return HostTC ? getInputs()[1] : getInputs().front();
285}
286
287void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC,
288 const char *BoundArch,
289 OffloadKind OKind) {
290 DeviceActions.push_back(&A);
291 DeviceToolChains.push_back(&TC);
292 DeviceBoundArchs.push_back(BoundArch);
293 DeviceOffloadKinds.push_back(OKind);
294}
295
296OffloadAction::HostDependence::HostDependence(Action &A, const ToolChain &TC,
297 const char *BoundArch,
298 const DeviceDependences &DDeps)
299 : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) {
300 for (auto K : DDeps.getOffloadKinds())
301 HostOffloadKinds |= K;
302}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000303
David Blaikie68e081d2011-12-20 02:48:34 +0000304void JobAction::anchor() {}
305
Justin Lebar41094612016-01-11 23:07:27 +0000306JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
307 : Action(Kind, Input, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000308
Mike Stump11289f42009-09-09 15:08:12 +0000309JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000310 : Action(Kind, Inputs, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000311
David Blaikie68e081d2011-12-20 02:48:34 +0000312void PreprocessJobAction::anchor() {}
313
Justin Lebar41094612016-01-11 23:07:27 +0000314PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
315 : JobAction(PreprocessJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000316
David Blaikie68e081d2011-12-20 02:48:34 +0000317void PrecompileJobAction::anchor() {}
318
Justin Lebar41094612016-01-11 23:07:27 +0000319PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
320 : JobAction(PrecompileJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000321
David Blaikie68e081d2011-12-20 02:48:34 +0000322void AnalyzeJobAction::anchor() {}
323
Justin Lebar41094612016-01-11 23:07:27 +0000324AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
325 : JobAction(AnalyzeJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000326
Ted Kremenekf7639e12012-03-06 20:06:33 +0000327void MigrateJobAction::anchor() {}
328
Justin Lebar41094612016-01-11 23:07:27 +0000329MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
330 : JobAction(MigrateJobClass, Input, OutputType) {}
Ted Kremenekf7639e12012-03-06 20:06:33 +0000331
David Blaikie68e081d2011-12-20 02:48:34 +0000332void CompileJobAction::anchor() {}
333
Justin Lebar41094612016-01-11 23:07:27 +0000334CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
335 : JobAction(CompileJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000336
Bob Wilson23a55f12014-12-21 07:00:00 +0000337void BackendJobAction::anchor() {}
338
Justin Lebar41094612016-01-11 23:07:27 +0000339BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType)
340 : JobAction(BackendJobClass, Input, OutputType) {}
Bob Wilson23a55f12014-12-21 07:00:00 +0000341
David Blaikie68e081d2011-12-20 02:48:34 +0000342void AssembleJobAction::anchor() {}
343
Justin Lebar41094612016-01-11 23:07:27 +0000344AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
345 : JobAction(AssembleJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000346
David Blaikie68e081d2011-12-20 02:48:34 +0000347void LinkJobAction::anchor() {}
348
Mike Stump11289f42009-09-09 15:08:12 +0000349LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000350 : JobAction(LinkJobClass, Inputs, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000351
David Blaikie68e081d2011-12-20 02:48:34 +0000352void LipoJobAction::anchor() {}
353
Mike Stump11289f42009-09-09 15:08:12 +0000354LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000355 : JobAction(LipoJobClass, Inputs, Type) {}
Daniel Dunbar88299622010-06-04 18:28:36 +0000356
David Blaikie68e081d2011-12-20 02:48:34 +0000357void DsymutilJobAction::anchor() {}
358
Daniel Dunbar88299622010-06-04 18:28:36 +0000359DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000360 : JobAction(DsymutilJobClass, Inputs, Type) {}
Eric Christopher551ef452011-08-23 17:56:55 +0000361
David Blaikie68e081d2011-12-20 02:48:34 +0000362void VerifyJobAction::anchor() {}
363
Justin Lebar41094612016-01-11 23:07:27 +0000364VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
365 types::ID Type)
366 : JobAction(Kind, Input, Type) {
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000367 assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
368 "ActionClass is not a valid VerifyJobAction");
369}
370
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000371void VerifyDebugInfoJobAction::anchor() {}
372
Justin Lebar41094612016-01-11 23:07:27 +0000373VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
374 types::ID Type)
375 : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {}
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000376
377void VerifyPCHJobAction::anchor() {}
378
Justin Lebar41094612016-01-11 23:07:27 +0000379VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
380 : VerifyJobAction(VerifyPCHJobClass, Input, Type) {}
Samuel Antao69d6f312016-10-27 17:50:43 +0000381
382void OffloadBundlingJobAction::anchor() {}
383
384OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs)
Yaxun Liuac8ccd52018-08-28 21:09:09 +0000385 : JobAction(OffloadBundlingJobClass, Inputs, Inputs.back()->getType()) {}
Samuel Antaofab4f372016-10-27 18:00:51 +0000386
387void OffloadUnbundlingJobAction::anchor() {}
388
389OffloadUnbundlingJobAction::OffloadUnbundlingJobAction(Action *Input)
390 : JobAction(OffloadUnbundlingJobClass, Input, Input->getType()) {}