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