]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Driver/Action.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Driver / Action.cpp
1 //===- Action.cpp - Abstract compilation steps ----------------------------===//
2 //
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"
11 #include "llvm/Support/ErrorHandling.h"
12 #include <cassert>
13 #include <string>
14
15 using namespace clang;
16 using namespace driver;
17 using namespace llvm::opt;
18
19 Action::~Action() = default;
20
21 const char *Action::getClassName(ActionClass AC) {
22   switch (AC) {
23   case InputClass: return "input";
24   case BindArchClass: return "bind-arch";
25   case OffloadClass:
26     return "offload";
27   case PreprocessJobClass: return "preprocessor";
28   case PrecompileJobClass: return "precompiler";
29   case HeaderModulePrecompileJobClass: return "header-module-precompiler";
30   case AnalyzeJobClass: return "analyzer";
31   case MigrateJobClass: return "migrator";
32   case CompileJobClass: return "compiler";
33   case BackendJobClass: return "backend";
34   case AssembleJobClass: return "assembler";
35   case LinkJobClass: return "linker";
36   case LipoJobClass: return "lipo";
37   case DsymutilJobClass: return "dsymutil";
38   case VerifyDebugInfoJobClass: return "verify-debug-info";
39   case VerifyPCHJobClass: return "verify-pch";
40   case OffloadBundlingJobClass:
41     return "clang-offload-bundler";
42   case OffloadUnbundlingJobClass:
43     return "clang-offload-unbundler";
44   }
45
46   llvm_unreachable("invalid class");
47 }
48
49 void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch) {
50   // Offload action set its own kinds on their dependences.
51   if (Kind == OffloadClass)
52     return;
53   // Unbundling actions use the host kinds.
54   if (Kind == OffloadUnbundlingJobClass)
55     return;
56
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
67 void 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
81 void 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
89 std::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";
98   case OFK_OpenMP:
99     return "device-openmp";
100   case OFK_HIP:
101     return "device-hip";
102
103     // TODO: Add other programming models here.
104   }
105
106   if (!ActiveOffloadKindMask)
107     return {};
108
109   std::string Res("host");
110   assert(!((ActiveOffloadKindMask & OFK_Cuda) &&
111            (ActiveOffloadKindMask & OFK_HIP)) &&
112          "Cannot offload CUDA and HIP at the same time");
113   if (ActiveOffloadKindMask & OFK_Cuda)
114     Res += "-cuda";
115   if (ActiveOffloadKindMask & OFK_HIP)
116     Res += "-hip";
117   if (ActiveOffloadKindMask & OFK_OpenMP)
118     Res += "-openmp";
119
120   // TODO: Add other programming models here.
121
122   return Res;
123 }
124
125 /// Return a string that can be used as prefix in order to generate unique files
126 /// for each offloading kind.
127 std::string
128 Action::GetOffloadingFileNamePrefix(OffloadKind Kind,
129                                     StringRef NormalizedTriple,
130                                     bool CreatePrefixForHost) {
131   // Don't generate prefix for host actions unless required.
132   if (!CreatePrefixForHost && (Kind == OFK_None || Kind == OFK_Host))
133     return {};
134
135   std::string Res("-");
136   Res += GetOffloadKindName(Kind);
137   Res += "-";
138   Res += NormalizedTriple;
139   return Res;
140 }
141
142 /// Return a string with the offload kind name. If that is not defined, we
143 /// assume 'host'.
144 StringRef Action::GetOffloadKindName(OffloadKind Kind) {
145   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";
153   case OFK_HIP:
154     return "hip";
155
156     // TODO: Add other programming models here.
157   }
158
159   llvm_unreachable("invalid offload kind");
160 }
161
162 void InputAction::anchor() {}
163
164 InputAction::InputAction(const Arg &_Input, types::ID _Type)
165     : Action(InputClass, _Type), Input(_Input) {}
166
167 void BindArchAction::anchor() {}
168
169 BindArchAction::BindArchAction(Action *Input, StringRef ArchName)
170     : Action(BindArchClass, Input), ArchName(ArchName) {}
171
172 void OffloadAction::anchor() {}
173
174 OffloadAction::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());
180 }
181
182 OffloadAction::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();
187
188   // 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
201 OffloadAction::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
221 void 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
229 void 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
251 void OffloadAction::doOnEachDependence(const OffloadActionWorkTy &Work) const {
252   doOnHostDependence(Work);
253   doOnEachDeviceDependence(Work);
254 }
255
256 void OffloadAction::doOnEachDependence(bool IsHostDependence,
257                                        const OffloadActionWorkTy &Work) const {
258   if (IsHostDependence)
259     doOnHostDependence(Work);
260   else
261     doOnEachDeviceDependence(Work);
262 }
263
264 bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; }
265
266 Action *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
272 bool OffloadAction::hasSingleDeviceDependence(
273     bool DoNotConsiderHostActions) const {
274   if (DoNotConsiderHostActions)
275     return getInputs().size() == (HostTC ? 2 : 1);
276   return !HostTC && getInputs().size() == 1;
277 }
278
279 Action *
280 OffloadAction::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
288 void 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
297 OffloadAction::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 }
304
305 void JobAction::anchor() {}
306
307 JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
308     : Action(Kind, Input, Type) {}
309
310 JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
311     : Action(Kind, Inputs, Type) {}
312
313 void PreprocessJobAction::anchor() {}
314
315 PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
316     : JobAction(PreprocessJobClass, Input, OutputType) {}
317
318 void PrecompileJobAction::anchor() {}
319
320 PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
321     : JobAction(PrecompileJobClass, Input, OutputType) {}
322
323 PrecompileJobAction::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
329 void HeaderModulePrecompileJobAction::anchor() {}
330
331 HeaderModulePrecompileJobAction::HeaderModulePrecompileJobAction(
332     Action *Input, types::ID OutputType, const char *ModuleName)
333     : PrecompileJobAction(HeaderModulePrecompileJobClass, Input, OutputType),
334       ModuleName(ModuleName) {}
335
336 void AnalyzeJobAction::anchor() {}
337
338 AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
339     : JobAction(AnalyzeJobClass, Input, OutputType) {}
340
341 void MigrateJobAction::anchor() {}
342
343 MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
344     : JobAction(MigrateJobClass, Input, OutputType) {}
345
346 void CompileJobAction::anchor() {}
347
348 CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
349     : JobAction(CompileJobClass, Input, OutputType) {}
350
351 void BackendJobAction::anchor() {}
352
353 BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType)
354     : JobAction(BackendJobClass, Input, OutputType) {}
355
356 void AssembleJobAction::anchor() {}
357
358 AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
359     : JobAction(AssembleJobClass, Input, OutputType) {}
360
361 void LinkJobAction::anchor() {}
362
363 LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
364     : JobAction(LinkJobClass, Inputs, Type) {}
365
366 void LipoJobAction::anchor() {}
367
368 LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
369     : JobAction(LipoJobClass, Inputs, Type) {}
370
371 void DsymutilJobAction::anchor() {}
372
373 DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
374     : JobAction(DsymutilJobClass, Inputs, Type) {}
375
376 void VerifyJobAction::anchor() {}
377
378 VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
379                                  types::ID Type)
380     : JobAction(Kind, Input, Type) {
381   assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
382          "ActionClass is not a valid VerifyJobAction");
383 }
384
385 void VerifyDebugInfoJobAction::anchor() {}
386
387 VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
388                                                    types::ID Type)
389     : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {}
390
391 void VerifyPCHJobAction::anchor() {}
392
393 VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
394     : VerifyJobAction(VerifyPCHJobClass, Input, Type) {}
395
396 void OffloadBundlingJobAction::anchor() {}
397
398 OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs)
399     : JobAction(OffloadBundlingJobClass, Inputs, Inputs.back()->getType()) {}
400
401 void OffloadUnbundlingJobAction::anchor() {}
402
403 OffloadUnbundlingJobAction::OffloadUnbundlingJobAction(Action *Input)
404     : JobAction(OffloadUnbundlingJobClass, Input, Input->getType()) {}