]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/lib/Driver/Action.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / lib / Driver / Action.cpp
1 //===- Action.cpp - Abstract compilation steps ----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "clang/Driver/Action.h"
10 #include "llvm/Support/ErrorHandling.h"
11 #include <cassert>
12 #include <string>
13
14 using namespace clang;
15 using namespace driver;
16 using namespace llvm::opt;
17
18 Action::~Action() = default;
19
20 const char *Action::getClassName(ActionClass AC) {
21   switch (AC) {
22   case InputClass: return "input";
23   case BindArchClass: return "bind-arch";
24   case OffloadClass:
25     return "offload";
26   case PreprocessJobClass: return "preprocessor";
27   case PrecompileJobClass: return "precompiler";
28   case HeaderModulePrecompileJobClass: return "header-module-precompiler";
29   case AnalyzeJobClass: return "analyzer";
30   case MigrateJobClass: return "migrator";
31   case CompileJobClass: return "compiler";
32   case BackendJobClass: return "backend";
33   case AssembleJobClass: return "assembler";
34   case IfsMergeJobClass: return "interface-stub-merger";
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   case OffloadWrapperJobClass:
45     return "clang-offload-wrapper";
46   }
47
48   llvm_unreachable("invalid class");
49 }
50
51 void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch) {
52   // Offload action set its own kinds on their dependences.
53   if (Kind == OffloadClass)
54     return;
55   // Unbundling actions use the host kinds.
56   if (Kind == OffloadUnbundlingJobClass)
57     return;
58
59   assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
60          "Setting device kind to a different device??");
61   assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??");
62   OffloadingDeviceKind = OKind;
63   OffloadingArch = OArch;
64
65   for (auto *A : Inputs)
66     A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch);
67 }
68
69 void Action::propagateHostOffloadInfo(unsigned OKinds, const char *OArch) {
70   // Offload action set its own kinds on their dependences.
71   if (Kind == OffloadClass)
72     return;
73
74   assert(OffloadingDeviceKind == OFK_None &&
75          "Setting a host kind in a device action.");
76   ActiveOffloadKindMask |= OKinds;
77   OffloadingArch = OArch;
78
79   for (auto *A : Inputs)
80     A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
81 }
82
83 void Action::propagateOffloadInfo(const Action *A) {
84   if (unsigned HK = A->getOffloadingHostActiveKinds())
85     propagateHostOffloadInfo(HK, A->getOffloadingArch());
86   else
87     propagateDeviceOffloadInfo(A->getOffloadingDeviceKind(),
88                                A->getOffloadingArch());
89 }
90
91 std::string Action::getOffloadingKindPrefix() const {
92   switch (OffloadingDeviceKind) {
93   case OFK_None:
94     break;
95   case OFK_Host:
96     llvm_unreachable("Host kind is not an offloading device kind.");
97     break;
98   case OFK_Cuda:
99     return "device-cuda";
100   case OFK_OpenMP:
101     return "device-openmp";
102   case OFK_HIP:
103     return "device-hip";
104
105     // TODO: Add other programming models here.
106   }
107
108   if (!ActiveOffloadKindMask)
109     return {};
110
111   std::string Res("host");
112   assert(!((ActiveOffloadKindMask & OFK_Cuda) &&
113            (ActiveOffloadKindMask & OFK_HIP)) &&
114          "Cannot offload CUDA and HIP at the same time");
115   if (ActiveOffloadKindMask & OFK_Cuda)
116     Res += "-cuda";
117   if (ActiveOffloadKindMask & OFK_HIP)
118     Res += "-hip";
119   if (ActiveOffloadKindMask & OFK_OpenMP)
120     Res += "-openmp";
121
122   // TODO: Add other programming models here.
123
124   return Res;
125 }
126
127 /// Return a string that can be used as prefix in order to generate unique files
128 /// for each offloading kind.
129 std::string
130 Action::GetOffloadingFileNamePrefix(OffloadKind Kind,
131                                     StringRef NormalizedTriple,
132                                     bool CreatePrefixForHost) {
133   // Don't generate prefix for host actions unless required.
134   if (!CreatePrefixForHost && (Kind == OFK_None || Kind == OFK_Host))
135     return {};
136
137   std::string Res("-");
138   Res += GetOffloadKindName(Kind);
139   Res += "-";
140   Res += NormalizedTriple;
141   return Res;
142 }
143
144 /// Return a string with the offload kind name. If that is not defined, we
145 /// assume 'host'.
146 StringRef Action::GetOffloadKindName(OffloadKind Kind) {
147   switch (Kind) {
148   case OFK_None:
149   case OFK_Host:
150     return "host";
151   case OFK_Cuda:
152     return "cuda";
153   case OFK_OpenMP:
154     return "openmp";
155   case OFK_HIP:
156     return "hip";
157
158     // TODO: Add other programming models here.
159   }
160
161   llvm_unreachable("invalid offload kind");
162 }
163
164 void InputAction::anchor() {}
165
166 InputAction::InputAction(const Arg &_Input, types::ID _Type)
167     : Action(InputClass, _Type), Input(_Input) {}
168
169 void BindArchAction::anchor() {}
170
171 BindArchAction::BindArchAction(Action *Input, StringRef ArchName)
172     : Action(BindArchClass, Input), ArchName(ArchName) {}
173
174 void OffloadAction::anchor() {}
175
176 OffloadAction::OffloadAction(const HostDependence &HDep)
177     : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
178   OffloadingArch = HDep.getBoundArch();
179   ActiveOffloadKindMask = HDep.getOffloadKinds();
180   HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
181                                              HDep.getBoundArch());
182 }
183
184 OffloadAction::OffloadAction(const DeviceDependences &DDeps, types::ID Ty)
185     : Action(OffloadClass, DDeps.getActions(), Ty),
186       DevToolChains(DDeps.getToolChains()) {
187   auto &OKinds = DDeps.getOffloadKinds();
188   auto &BArchs = DDeps.getBoundArchs();
189
190   // If all inputs agree on the same kind, use it also for this action.
191   if (llvm::all_of(OKinds, [&](OffloadKind K) { return K == OKinds.front(); }))
192     OffloadingDeviceKind = OKinds.front();
193
194   // If we have a single dependency, inherit the architecture from it.
195   if (OKinds.size() == 1)
196     OffloadingArch = BArchs.front();
197
198   // Propagate info to the dependencies.
199   for (unsigned i = 0, e = getInputs().size(); i != e; ++i)
200     getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]);
201 }
202
203 OffloadAction::OffloadAction(const HostDependence &HDep,
204                              const DeviceDependences &DDeps)
205     : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
206       DevToolChains(DDeps.getToolChains()) {
207   // We use the kinds of the host dependence for this action.
208   OffloadingArch = HDep.getBoundArch();
209   ActiveOffloadKindMask = HDep.getOffloadKinds();
210   HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
211                                              HDep.getBoundArch());
212
213   // Add device inputs and propagate info to the device actions. Do work only if
214   // we have dependencies.
215   for (unsigned i = 0, e = DDeps.getActions().size(); i != e; ++i)
216     if (auto *A = DDeps.getActions()[i]) {
217       getInputs().push_back(A);
218       A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i],
219                                     DDeps.getBoundArchs()[i]);
220     }
221 }
222
223 void OffloadAction::doOnHostDependence(const OffloadActionWorkTy &Work) const {
224   if (!HostTC)
225     return;
226   assert(!getInputs().empty() && "No dependencies for offload action??");
227   auto *A = getInputs().front();
228   Work(A, HostTC, A->getOffloadingArch());
229 }
230
231 void OffloadAction::doOnEachDeviceDependence(
232     const OffloadActionWorkTy &Work) const {
233   auto I = getInputs().begin();
234   auto E = getInputs().end();
235   if (I == E)
236     return;
237
238   // We expect to have the same number of input dependences and device tool
239   // chains, except if we also have a host dependence. In that case we have one
240   // more dependence than we have device tool chains.
241   assert(getInputs().size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
242          "Sizes of action dependences and toolchains are not consistent!");
243
244   // Skip host action
245   if (HostTC)
246     ++I;
247
248   auto TI = DevToolChains.begin();
249   for (; I != E; ++I, ++TI)
250     Work(*I, *TI, (*I)->getOffloadingArch());
251 }
252
253 void OffloadAction::doOnEachDependence(const OffloadActionWorkTy &Work) const {
254   doOnHostDependence(Work);
255   doOnEachDeviceDependence(Work);
256 }
257
258 void OffloadAction::doOnEachDependence(bool IsHostDependence,
259                                        const OffloadActionWorkTy &Work) const {
260   if (IsHostDependence)
261     doOnHostDependence(Work);
262   else
263     doOnEachDeviceDependence(Work);
264 }
265
266 bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; }
267
268 Action *OffloadAction::getHostDependence() const {
269   assert(hasHostDependence() && "Host dependence does not exist!");
270   assert(!getInputs().empty() && "No dependencies for offload action??");
271   return HostTC ? getInputs().front() : nullptr;
272 }
273
274 bool OffloadAction::hasSingleDeviceDependence(
275     bool DoNotConsiderHostActions) const {
276   if (DoNotConsiderHostActions)
277     return getInputs().size() == (HostTC ? 2 : 1);
278   return !HostTC && getInputs().size() == 1;
279 }
280
281 Action *
282 OffloadAction::getSingleDeviceDependence(bool DoNotConsiderHostActions) const {
283   assert(hasSingleDeviceDependence(DoNotConsiderHostActions) &&
284          "Single device dependence does not exist!");
285   // The previous assert ensures the number of entries in getInputs() is
286   // consistent with what we are doing here.
287   return HostTC ? getInputs()[1] : getInputs().front();
288 }
289
290 void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC,
291                                            const char *BoundArch,
292                                            OffloadKind OKind) {
293   DeviceActions.push_back(&A);
294   DeviceToolChains.push_back(&TC);
295   DeviceBoundArchs.push_back(BoundArch);
296   DeviceOffloadKinds.push_back(OKind);
297 }
298
299 OffloadAction::HostDependence::HostDependence(Action &A, const ToolChain &TC,
300                                               const char *BoundArch,
301                                               const DeviceDependences &DDeps)
302     : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) {
303   for (auto K : DDeps.getOffloadKinds())
304     HostOffloadKinds |= K;
305 }
306
307 void JobAction::anchor() {}
308
309 JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
310     : Action(Kind, Input, Type) {}
311
312 JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
313     : Action(Kind, Inputs, Type) {}
314
315 void PreprocessJobAction::anchor() {}
316
317 PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
318     : JobAction(PreprocessJobClass, Input, OutputType) {}
319
320 void PrecompileJobAction::anchor() {}
321
322 PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
323     : JobAction(PrecompileJobClass, Input, OutputType) {}
324
325 PrecompileJobAction::PrecompileJobAction(ActionClass Kind, Action *Input,
326                                          types::ID OutputType)
327     : JobAction(Kind, Input, OutputType) {
328   assert(isa<PrecompileJobAction>((Action*)this) && "invalid action kind");
329 }
330
331 void HeaderModulePrecompileJobAction::anchor() {}
332
333 HeaderModulePrecompileJobAction::HeaderModulePrecompileJobAction(
334     Action *Input, types::ID OutputType, const char *ModuleName)
335     : PrecompileJobAction(HeaderModulePrecompileJobClass, Input, OutputType),
336       ModuleName(ModuleName) {}
337
338 void AnalyzeJobAction::anchor() {}
339
340 AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
341     : JobAction(AnalyzeJobClass, Input, OutputType) {}
342
343 void MigrateJobAction::anchor() {}
344
345 MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
346     : JobAction(MigrateJobClass, Input, OutputType) {}
347
348 void CompileJobAction::anchor() {}
349
350 CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
351     : JobAction(CompileJobClass, Input, OutputType) {}
352
353 void BackendJobAction::anchor() {}
354
355 BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType)
356     : JobAction(BackendJobClass, Input, OutputType) {}
357
358 void AssembleJobAction::anchor() {}
359
360 AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
361     : JobAction(AssembleJobClass, Input, OutputType) {}
362
363 void IfsMergeJobAction::anchor() {}
364
365 IfsMergeJobAction::IfsMergeJobAction(ActionList &Inputs, types::ID Type)
366     : JobAction(IfsMergeJobClass, Inputs, Type) {}
367
368 void LinkJobAction::anchor() {}
369
370 LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
371     : JobAction(LinkJobClass, Inputs, Type) {}
372
373 void LipoJobAction::anchor() {}
374
375 LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
376     : JobAction(LipoJobClass, Inputs, Type) {}
377
378 void DsymutilJobAction::anchor() {}
379
380 DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
381     : JobAction(DsymutilJobClass, Inputs, Type) {}
382
383 void VerifyJobAction::anchor() {}
384
385 VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
386                                  types::ID Type)
387     : JobAction(Kind, Input, Type) {
388   assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
389          "ActionClass is not a valid VerifyJobAction");
390 }
391
392 void VerifyDebugInfoJobAction::anchor() {}
393
394 VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
395                                                    types::ID Type)
396     : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {}
397
398 void VerifyPCHJobAction::anchor() {}
399
400 VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
401     : VerifyJobAction(VerifyPCHJobClass, Input, Type) {}
402
403 void OffloadBundlingJobAction::anchor() {}
404
405 OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs)
406     : JobAction(OffloadBundlingJobClass, Inputs, Inputs.back()->getType()) {}
407
408 void OffloadUnbundlingJobAction::anchor() {}
409
410 OffloadUnbundlingJobAction::OffloadUnbundlingJobAction(Action *Input)
411     : JobAction(OffloadUnbundlingJobClass, Input, Input->getType()) {}
412
413 void OffloadWrapperJobAction::anchor() {}
414
415 OffloadWrapperJobAction::OffloadWrapperJobAction(ActionList &Inputs,
416                                                  types::ID Type)
417   : JobAction(OffloadWrapperJobClass, Inputs, Type) {}