xref: /freebsd/contrib/llvm-project/clang/lib/Driver/Action.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===- Action.cpp - Abstract compilation steps ----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "clang/Driver/Action.h"
100b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
110b57cec5SDimitry Andric #include <cassert>
120b57cec5SDimitry Andric #include <string>
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric using namespace clang;
150b57cec5SDimitry Andric using namespace driver;
160b57cec5SDimitry Andric using namespace llvm::opt;
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric Action::~Action() = default;
190b57cec5SDimitry Andric 
getClassName(ActionClass AC)200b57cec5SDimitry Andric const char *Action::getClassName(ActionClass AC) {
210b57cec5SDimitry Andric   switch (AC) {
220b57cec5SDimitry Andric   case InputClass: return "input";
230b57cec5SDimitry Andric   case BindArchClass: return "bind-arch";
240b57cec5SDimitry Andric   case OffloadClass:
250b57cec5SDimitry Andric     return "offload";
260b57cec5SDimitry Andric   case PreprocessJobClass: return "preprocessor";
270b57cec5SDimitry Andric   case PrecompileJobClass: return "precompiler";
2881ad6265SDimitry Andric   case ExtractAPIJobClass:
2981ad6265SDimitry Andric     return "api-extractor";
300b57cec5SDimitry Andric   case AnalyzeJobClass: return "analyzer";
310b57cec5SDimitry Andric   case MigrateJobClass: return "migrator";
320b57cec5SDimitry Andric   case CompileJobClass: return "compiler";
330b57cec5SDimitry Andric   case BackendJobClass: return "backend";
340b57cec5SDimitry Andric   case AssembleJobClass: return "assembler";
35a7dea167SDimitry Andric   case IfsMergeJobClass: return "interface-stub-merger";
360b57cec5SDimitry Andric   case LinkJobClass: return "linker";
370b57cec5SDimitry Andric   case LipoJobClass: return "lipo";
380b57cec5SDimitry Andric   case DsymutilJobClass: return "dsymutil";
390b57cec5SDimitry Andric   case VerifyDebugInfoJobClass: return "verify-debug-info";
400b57cec5SDimitry Andric   case VerifyPCHJobClass: return "verify-pch";
410b57cec5SDimitry Andric   case OffloadBundlingJobClass:
420b57cec5SDimitry Andric     return "clang-offload-bundler";
430b57cec5SDimitry Andric   case OffloadUnbundlingJobClass:
440b57cec5SDimitry Andric     return "clang-offload-unbundler";
4581ad6265SDimitry Andric   case OffloadPackagerJobClass:
4681ad6265SDimitry Andric     return "clang-offload-packager";
471fd87a68SDimitry Andric   case LinkerWrapperJobClass:
481fd87a68SDimitry Andric     return "clang-linker-wrapper";
495ffd83dbSDimitry Andric   case StaticLibJobClass:
505ffd83dbSDimitry Andric     return "static-lib-linker";
51*06c3fb27SDimitry Andric   case BinaryAnalyzeJobClass:
52*06c3fb27SDimitry Andric     return "binary-analyzer";
530b57cec5SDimitry Andric   }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   llvm_unreachable("invalid class");
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric 
propagateDeviceOffloadInfo(OffloadKind OKind,const char * OArch,const ToolChain * OToolChain)5881ad6265SDimitry Andric void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch,
5981ad6265SDimitry Andric                                         const ToolChain *OToolChain) {
600b57cec5SDimitry Andric   // Offload action set its own kinds on their dependences.
610b57cec5SDimitry Andric   if (Kind == OffloadClass)
620b57cec5SDimitry Andric     return;
630b57cec5SDimitry Andric   // Unbundling actions use the host kinds.
640b57cec5SDimitry Andric   if (Kind == OffloadUnbundlingJobClass)
650b57cec5SDimitry Andric     return;
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
680b57cec5SDimitry Andric          "Setting device kind to a different device??");
690b57cec5SDimitry Andric   assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??");
700b57cec5SDimitry Andric   OffloadingDeviceKind = OKind;
710b57cec5SDimitry Andric   OffloadingArch = OArch;
7281ad6265SDimitry Andric   OffloadingToolChain = OToolChain;
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   for (auto *A : Inputs)
7581ad6265SDimitry Andric     A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch, OToolChain);
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric 
propagateHostOffloadInfo(unsigned OKinds,const char * OArch)780b57cec5SDimitry Andric void Action::propagateHostOffloadInfo(unsigned OKinds, const char *OArch) {
790b57cec5SDimitry Andric   // Offload action set its own kinds on their dependences.
800b57cec5SDimitry Andric   if (Kind == OffloadClass)
810b57cec5SDimitry Andric     return;
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   assert(OffloadingDeviceKind == OFK_None &&
840b57cec5SDimitry Andric          "Setting a host kind in a device action.");
850b57cec5SDimitry Andric   ActiveOffloadKindMask |= OKinds;
860b57cec5SDimitry Andric   OffloadingArch = OArch;
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   for (auto *A : Inputs)
890b57cec5SDimitry Andric     A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric 
propagateOffloadInfo(const Action * A)920b57cec5SDimitry Andric void Action::propagateOffloadInfo(const Action *A) {
930b57cec5SDimitry Andric   if (unsigned HK = A->getOffloadingHostActiveKinds())
940b57cec5SDimitry Andric     propagateHostOffloadInfo(HK, A->getOffloadingArch());
950b57cec5SDimitry Andric   else
960b57cec5SDimitry Andric     propagateDeviceOffloadInfo(A->getOffloadingDeviceKind(),
9781ad6265SDimitry Andric                                A->getOffloadingArch(),
9881ad6265SDimitry Andric                                A->getOffloadingToolChain());
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric 
getOffloadingKindPrefix() const1010b57cec5SDimitry Andric std::string Action::getOffloadingKindPrefix() const {
1020b57cec5SDimitry Andric   switch (OffloadingDeviceKind) {
1030b57cec5SDimitry Andric   case OFK_None:
1040b57cec5SDimitry Andric     break;
1050b57cec5SDimitry Andric   case OFK_Host:
1060b57cec5SDimitry Andric     llvm_unreachable("Host kind is not an offloading device kind.");
1070b57cec5SDimitry Andric     break;
1080b57cec5SDimitry Andric   case OFK_Cuda:
1090b57cec5SDimitry Andric     return "device-cuda";
1100b57cec5SDimitry Andric   case OFK_OpenMP:
1110b57cec5SDimitry Andric     return "device-openmp";
1120b57cec5SDimitry Andric   case OFK_HIP:
1130b57cec5SDimitry Andric     return "device-hip";
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric     // TODO: Add other programming models here.
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   if (!ActiveOffloadKindMask)
1190b57cec5SDimitry Andric     return {};
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   std::string Res("host");
1220b57cec5SDimitry Andric   assert(!((ActiveOffloadKindMask & OFK_Cuda) &&
1230b57cec5SDimitry Andric            (ActiveOffloadKindMask & OFK_HIP)) &&
1240b57cec5SDimitry Andric          "Cannot offload CUDA and HIP at the same time");
1250b57cec5SDimitry Andric   if (ActiveOffloadKindMask & OFK_Cuda)
1260b57cec5SDimitry Andric     Res += "-cuda";
1270b57cec5SDimitry Andric   if (ActiveOffloadKindMask & OFK_HIP)
1280b57cec5SDimitry Andric     Res += "-hip";
1290b57cec5SDimitry Andric   if (ActiveOffloadKindMask & OFK_OpenMP)
1300b57cec5SDimitry Andric     Res += "-openmp";
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric   // TODO: Add other programming models here.
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric   return Res;
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric /// Return a string that can be used as prefix in order to generate unique files
1380b57cec5SDimitry Andric /// for each offloading kind.
1390b57cec5SDimitry Andric std::string
GetOffloadingFileNamePrefix(OffloadKind Kind,StringRef NormalizedTriple,bool CreatePrefixForHost)1400b57cec5SDimitry Andric Action::GetOffloadingFileNamePrefix(OffloadKind Kind,
1410b57cec5SDimitry Andric                                     StringRef NormalizedTriple,
1420b57cec5SDimitry Andric                                     bool CreatePrefixForHost) {
1430b57cec5SDimitry Andric   // Don't generate prefix for host actions unless required.
1440b57cec5SDimitry Andric   if (!CreatePrefixForHost && (Kind == OFK_None || Kind == OFK_Host))
1450b57cec5SDimitry Andric     return {};
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   std::string Res("-");
1480b57cec5SDimitry Andric   Res += GetOffloadKindName(Kind);
1490b57cec5SDimitry Andric   Res += "-";
1500b57cec5SDimitry Andric   Res += NormalizedTriple;
1510b57cec5SDimitry Andric   return Res;
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric /// Return a string with the offload kind name. If that is not defined, we
1550b57cec5SDimitry Andric /// assume 'host'.
GetOffloadKindName(OffloadKind Kind)1560b57cec5SDimitry Andric StringRef Action::GetOffloadKindName(OffloadKind Kind) {
1570b57cec5SDimitry Andric   switch (Kind) {
1580b57cec5SDimitry Andric   case OFK_None:
1590b57cec5SDimitry Andric   case OFK_Host:
1600b57cec5SDimitry Andric     return "host";
1610b57cec5SDimitry Andric   case OFK_Cuda:
1620b57cec5SDimitry Andric     return "cuda";
1630b57cec5SDimitry Andric   case OFK_OpenMP:
1640b57cec5SDimitry Andric     return "openmp";
1650b57cec5SDimitry Andric   case OFK_HIP:
1660b57cec5SDimitry Andric     return "hip";
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric     // TODO: Add other programming models here.
1690b57cec5SDimitry Andric   }
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric   llvm_unreachable("invalid offload kind");
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric 
anchor()1740b57cec5SDimitry Andric void InputAction::anchor() {}
1750b57cec5SDimitry Andric 
InputAction(const Arg & _Input,types::ID _Type,StringRef _Id)176fe6060f1SDimitry Andric InputAction::InputAction(const Arg &_Input, types::ID _Type, StringRef _Id)
177fe6060f1SDimitry Andric     : Action(InputClass, _Type), Input(_Input), Id(_Id.str()) {}
1780b57cec5SDimitry Andric 
anchor()1790b57cec5SDimitry Andric void BindArchAction::anchor() {}
1800b57cec5SDimitry Andric 
BindArchAction(Action * Input,StringRef ArchName)1810b57cec5SDimitry Andric BindArchAction::BindArchAction(Action *Input, StringRef ArchName)
1820b57cec5SDimitry Andric     : Action(BindArchClass, Input), ArchName(ArchName) {}
1830b57cec5SDimitry Andric 
anchor()1840b57cec5SDimitry Andric void OffloadAction::anchor() {}
1850b57cec5SDimitry Andric 
OffloadAction(const HostDependence & HDep)1860b57cec5SDimitry Andric OffloadAction::OffloadAction(const HostDependence &HDep)
1870b57cec5SDimitry Andric     : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
1880b57cec5SDimitry Andric   OffloadingArch = HDep.getBoundArch();
1890b57cec5SDimitry Andric   ActiveOffloadKindMask = HDep.getOffloadKinds();
1900b57cec5SDimitry Andric   HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
1910b57cec5SDimitry Andric                                              HDep.getBoundArch());
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric 
OffloadAction(const DeviceDependences & DDeps,types::ID Ty)1940b57cec5SDimitry Andric OffloadAction::OffloadAction(const DeviceDependences &DDeps, types::ID Ty)
1950b57cec5SDimitry Andric     : Action(OffloadClass, DDeps.getActions(), Ty),
1960b57cec5SDimitry Andric       DevToolChains(DDeps.getToolChains()) {
1970b57cec5SDimitry Andric   auto &OKinds = DDeps.getOffloadKinds();
1980b57cec5SDimitry Andric   auto &BArchs = DDeps.getBoundArchs();
19981ad6265SDimitry Andric   auto &OTCs = DDeps.getToolChains();
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   // If all inputs agree on the same kind, use it also for this action.
202bdd1243dSDimitry Andric   if (llvm::all_equal(OKinds))
2030b57cec5SDimitry Andric     OffloadingDeviceKind = OKinds.front();
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric   // If we have a single dependency, inherit the architecture from it.
2060b57cec5SDimitry Andric   if (OKinds.size() == 1)
2070b57cec5SDimitry Andric     OffloadingArch = BArchs.front();
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   // Propagate info to the dependencies.
2100b57cec5SDimitry Andric   for (unsigned i = 0, e = getInputs().size(); i != e; ++i)
21181ad6265SDimitry Andric     getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i], OTCs[i]);
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
OffloadAction(const HostDependence & HDep,const DeviceDependences & DDeps)2140b57cec5SDimitry Andric OffloadAction::OffloadAction(const HostDependence &HDep,
2150b57cec5SDimitry Andric                              const DeviceDependences &DDeps)
2160b57cec5SDimitry Andric     : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
2170b57cec5SDimitry Andric       DevToolChains(DDeps.getToolChains()) {
2180b57cec5SDimitry Andric   // We use the kinds of the host dependence for this action.
2190b57cec5SDimitry Andric   OffloadingArch = HDep.getBoundArch();
2200b57cec5SDimitry Andric   ActiveOffloadKindMask = HDep.getOffloadKinds();
2210b57cec5SDimitry Andric   HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
2220b57cec5SDimitry Andric                                              HDep.getBoundArch());
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   // Add device inputs and propagate info to the device actions. Do work only if
2250b57cec5SDimitry Andric   // we have dependencies.
226bdd1243dSDimitry Andric   for (unsigned i = 0, e = DDeps.getActions().size(); i != e; ++i) {
2270b57cec5SDimitry Andric     if (auto *A = DDeps.getActions()[i]) {
2280b57cec5SDimitry Andric       getInputs().push_back(A);
2290b57cec5SDimitry Andric       A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i],
23081ad6265SDimitry Andric                                     DDeps.getBoundArchs()[i],
23181ad6265SDimitry Andric                                     DDeps.getToolChains()[i]);
232bdd1243dSDimitry Andric       // If this action is used to forward single dependency, set the toolchain.
233bdd1243dSDimitry Andric       if (DDeps.getActions().size() == 1)
234bdd1243dSDimitry Andric         OffloadingToolChain = DDeps.getToolChains()[i];
235bdd1243dSDimitry Andric     }
2360b57cec5SDimitry Andric   }
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric 
doOnHostDependence(const OffloadActionWorkTy & Work) const2390b57cec5SDimitry Andric void OffloadAction::doOnHostDependence(const OffloadActionWorkTy &Work) const {
2400b57cec5SDimitry Andric   if (!HostTC)
2410b57cec5SDimitry Andric     return;
2420b57cec5SDimitry Andric   assert(!getInputs().empty() && "No dependencies for offload action??");
2430b57cec5SDimitry Andric   auto *A = getInputs().front();
2440b57cec5SDimitry Andric   Work(A, HostTC, A->getOffloadingArch());
2450b57cec5SDimitry Andric }
2460b57cec5SDimitry Andric 
doOnEachDeviceDependence(const OffloadActionWorkTy & Work) const2470b57cec5SDimitry Andric void OffloadAction::doOnEachDeviceDependence(
2480b57cec5SDimitry Andric     const OffloadActionWorkTy &Work) const {
2490b57cec5SDimitry Andric   auto I = getInputs().begin();
2500b57cec5SDimitry Andric   auto E = getInputs().end();
2510b57cec5SDimitry Andric   if (I == E)
2520b57cec5SDimitry Andric     return;
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   // We expect to have the same number of input dependences and device tool
2550b57cec5SDimitry Andric   // chains, except if we also have a host dependence. In that case we have one
2560b57cec5SDimitry Andric   // more dependence than we have device tool chains.
2570b57cec5SDimitry Andric   assert(getInputs().size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
2580b57cec5SDimitry Andric          "Sizes of action dependences and toolchains are not consistent!");
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   // Skip host action
2610b57cec5SDimitry Andric   if (HostTC)
2620b57cec5SDimitry Andric     ++I;
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   auto TI = DevToolChains.begin();
2650b57cec5SDimitry Andric   for (; I != E; ++I, ++TI)
2660b57cec5SDimitry Andric     Work(*I, *TI, (*I)->getOffloadingArch());
2670b57cec5SDimitry Andric }
2680b57cec5SDimitry Andric 
doOnEachDependence(const OffloadActionWorkTy & Work) const2690b57cec5SDimitry Andric void OffloadAction::doOnEachDependence(const OffloadActionWorkTy &Work) const {
2700b57cec5SDimitry Andric   doOnHostDependence(Work);
2710b57cec5SDimitry Andric   doOnEachDeviceDependence(Work);
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric 
doOnEachDependence(bool IsHostDependence,const OffloadActionWorkTy & Work) const2740b57cec5SDimitry Andric void OffloadAction::doOnEachDependence(bool IsHostDependence,
2750b57cec5SDimitry Andric                                        const OffloadActionWorkTy &Work) const {
2760b57cec5SDimitry Andric   if (IsHostDependence)
2770b57cec5SDimitry Andric     doOnHostDependence(Work);
2780b57cec5SDimitry Andric   else
2790b57cec5SDimitry Andric     doOnEachDeviceDependence(Work);
2800b57cec5SDimitry Andric }
2810b57cec5SDimitry Andric 
hasHostDependence() const2820b57cec5SDimitry Andric bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; }
2830b57cec5SDimitry Andric 
getHostDependence() const2840b57cec5SDimitry Andric Action *OffloadAction::getHostDependence() const {
2850b57cec5SDimitry Andric   assert(hasHostDependence() && "Host dependence does not exist!");
2860b57cec5SDimitry Andric   assert(!getInputs().empty() && "No dependencies for offload action??");
2870b57cec5SDimitry Andric   return HostTC ? getInputs().front() : nullptr;
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
hasSingleDeviceDependence(bool DoNotConsiderHostActions) const2900b57cec5SDimitry Andric bool OffloadAction::hasSingleDeviceDependence(
2910b57cec5SDimitry Andric     bool DoNotConsiderHostActions) const {
2920b57cec5SDimitry Andric   if (DoNotConsiderHostActions)
2930b57cec5SDimitry Andric     return getInputs().size() == (HostTC ? 2 : 1);
2940b57cec5SDimitry Andric   return !HostTC && getInputs().size() == 1;
2950b57cec5SDimitry Andric }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric Action *
getSingleDeviceDependence(bool DoNotConsiderHostActions) const2980b57cec5SDimitry Andric OffloadAction::getSingleDeviceDependence(bool DoNotConsiderHostActions) const {
2990b57cec5SDimitry Andric   assert(hasSingleDeviceDependence(DoNotConsiderHostActions) &&
3000b57cec5SDimitry Andric          "Single device dependence does not exist!");
3010b57cec5SDimitry Andric   // The previous assert ensures the number of entries in getInputs() is
3020b57cec5SDimitry Andric   // consistent with what we are doing here.
3030b57cec5SDimitry Andric   return HostTC ? getInputs()[1] : getInputs().front();
3040b57cec5SDimitry Andric }
3050b57cec5SDimitry Andric 
add(Action & A,const ToolChain & TC,const char * BoundArch,OffloadKind OKind)3060b57cec5SDimitry Andric void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC,
3070b57cec5SDimitry Andric                                            const char *BoundArch,
3080b57cec5SDimitry Andric                                            OffloadKind OKind) {
3090b57cec5SDimitry Andric   DeviceActions.push_back(&A);
3100b57cec5SDimitry Andric   DeviceToolChains.push_back(&TC);
3110b57cec5SDimitry Andric   DeviceBoundArchs.push_back(BoundArch);
3120b57cec5SDimitry Andric   DeviceOffloadKinds.push_back(OKind);
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric 
add(Action & A,const ToolChain & TC,const char * BoundArch,unsigned OffloadKindMask)315bdd1243dSDimitry Andric void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC,
316bdd1243dSDimitry Andric                                            const char *BoundArch,
317bdd1243dSDimitry Andric                                            unsigned OffloadKindMask) {
318bdd1243dSDimitry Andric   DeviceActions.push_back(&A);
319bdd1243dSDimitry Andric   DeviceToolChains.push_back(&TC);
320bdd1243dSDimitry Andric   DeviceBoundArchs.push_back(BoundArch);
321bdd1243dSDimitry Andric 
322bdd1243dSDimitry Andric   // Add each active offloading kind from a mask.
323bdd1243dSDimitry Andric   for (OffloadKind OKind : {OFK_OpenMP, OFK_Cuda, OFK_HIP})
324bdd1243dSDimitry Andric     if (OKind & OffloadKindMask)
325bdd1243dSDimitry Andric       DeviceOffloadKinds.push_back(OKind);
326bdd1243dSDimitry Andric }
327bdd1243dSDimitry Andric 
HostDependence(Action & A,const ToolChain & TC,const char * BoundArch,const DeviceDependences & DDeps)3280b57cec5SDimitry Andric OffloadAction::HostDependence::HostDependence(Action &A, const ToolChain &TC,
3290b57cec5SDimitry Andric                                               const char *BoundArch,
3300b57cec5SDimitry Andric                                               const DeviceDependences &DDeps)
3310b57cec5SDimitry Andric     : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) {
3320b57cec5SDimitry Andric   for (auto K : DDeps.getOffloadKinds())
3330b57cec5SDimitry Andric     HostOffloadKinds |= K;
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric 
anchor()3360b57cec5SDimitry Andric void JobAction::anchor() {}
3370b57cec5SDimitry Andric 
JobAction(ActionClass Kind,Action * Input,types::ID Type)3380b57cec5SDimitry Andric JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
3390b57cec5SDimitry Andric     : Action(Kind, Input, Type) {}
3400b57cec5SDimitry Andric 
JobAction(ActionClass Kind,const ActionList & Inputs,types::ID Type)3410b57cec5SDimitry Andric JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
3420b57cec5SDimitry Andric     : Action(Kind, Inputs, Type) {}
3430b57cec5SDimitry Andric 
anchor()3440b57cec5SDimitry Andric void PreprocessJobAction::anchor() {}
3450b57cec5SDimitry Andric 
PreprocessJobAction(Action * Input,types::ID OutputType)3460b57cec5SDimitry Andric PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
3470b57cec5SDimitry Andric     : JobAction(PreprocessJobClass, Input, OutputType) {}
3480b57cec5SDimitry Andric 
anchor()3490b57cec5SDimitry Andric void PrecompileJobAction::anchor() {}
3500b57cec5SDimitry Andric 
PrecompileJobAction(Action * Input,types::ID OutputType)3510b57cec5SDimitry Andric PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
3520b57cec5SDimitry Andric     : JobAction(PrecompileJobClass, Input, OutputType) {}
3530b57cec5SDimitry Andric 
PrecompileJobAction(ActionClass Kind,Action * Input,types::ID OutputType)3540b57cec5SDimitry Andric PrecompileJobAction::PrecompileJobAction(ActionClass Kind, Action *Input,
3550b57cec5SDimitry Andric                                          types::ID OutputType)
3560b57cec5SDimitry Andric     : JobAction(Kind, Input, OutputType) {
3570b57cec5SDimitry Andric   assert(isa<PrecompileJobAction>((Action*)this) && "invalid action kind");
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric 
anchor()36081ad6265SDimitry Andric void ExtractAPIJobAction::anchor() {}
36181ad6265SDimitry Andric 
ExtractAPIJobAction(Action * Inputs,types::ID OutputType)36281ad6265SDimitry Andric ExtractAPIJobAction::ExtractAPIJobAction(Action *Inputs, types::ID OutputType)
36381ad6265SDimitry Andric     : JobAction(ExtractAPIJobClass, Inputs, OutputType) {}
36481ad6265SDimitry Andric 
anchor()3650b57cec5SDimitry Andric void AnalyzeJobAction::anchor() {}
3660b57cec5SDimitry Andric 
AnalyzeJobAction(Action * Input,types::ID OutputType)3670b57cec5SDimitry Andric AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
3680b57cec5SDimitry Andric     : JobAction(AnalyzeJobClass, Input, OutputType) {}
3690b57cec5SDimitry Andric 
anchor()3700b57cec5SDimitry Andric void MigrateJobAction::anchor() {}
3710b57cec5SDimitry Andric 
MigrateJobAction(Action * Input,types::ID OutputType)3720b57cec5SDimitry Andric MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
3730b57cec5SDimitry Andric     : JobAction(MigrateJobClass, Input, OutputType) {}
3740b57cec5SDimitry Andric 
anchor()3750b57cec5SDimitry Andric void CompileJobAction::anchor() {}
3760b57cec5SDimitry Andric 
CompileJobAction(Action * Input,types::ID OutputType)3770b57cec5SDimitry Andric CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
3780b57cec5SDimitry Andric     : JobAction(CompileJobClass, Input, OutputType) {}
3790b57cec5SDimitry Andric 
anchor()3800b57cec5SDimitry Andric void BackendJobAction::anchor() {}
3810b57cec5SDimitry Andric 
BackendJobAction(Action * Input,types::ID OutputType)3820b57cec5SDimitry Andric BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType)
3830b57cec5SDimitry Andric     : JobAction(BackendJobClass, Input, OutputType) {}
3840b57cec5SDimitry Andric 
anchor()3850b57cec5SDimitry Andric void AssembleJobAction::anchor() {}
3860b57cec5SDimitry Andric 
AssembleJobAction(Action * Input,types::ID OutputType)3870b57cec5SDimitry Andric AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
3880b57cec5SDimitry Andric     : JobAction(AssembleJobClass, Input, OutputType) {}
3890b57cec5SDimitry Andric 
anchor()390a7dea167SDimitry Andric void IfsMergeJobAction::anchor() {}
391a7dea167SDimitry Andric 
IfsMergeJobAction(ActionList & Inputs,types::ID Type)392a7dea167SDimitry Andric IfsMergeJobAction::IfsMergeJobAction(ActionList &Inputs, types::ID Type)
393a7dea167SDimitry Andric     : JobAction(IfsMergeJobClass, Inputs, Type) {}
394a7dea167SDimitry Andric 
anchor()3950b57cec5SDimitry Andric void LinkJobAction::anchor() {}
3960b57cec5SDimitry Andric 
LinkJobAction(ActionList & Inputs,types::ID Type)3970b57cec5SDimitry Andric LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
3980b57cec5SDimitry Andric     : JobAction(LinkJobClass, Inputs, Type) {}
3990b57cec5SDimitry Andric 
anchor()4000b57cec5SDimitry Andric void LipoJobAction::anchor() {}
4010b57cec5SDimitry Andric 
LipoJobAction(ActionList & Inputs,types::ID Type)4020b57cec5SDimitry Andric LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
4030b57cec5SDimitry Andric     : JobAction(LipoJobClass, Inputs, Type) {}
4040b57cec5SDimitry Andric 
anchor()4050b57cec5SDimitry Andric void DsymutilJobAction::anchor() {}
4060b57cec5SDimitry Andric 
DsymutilJobAction(ActionList & Inputs,types::ID Type)4070b57cec5SDimitry Andric DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
4080b57cec5SDimitry Andric     : JobAction(DsymutilJobClass, Inputs, Type) {}
4090b57cec5SDimitry Andric 
anchor()4100b57cec5SDimitry Andric void VerifyJobAction::anchor() {}
4110b57cec5SDimitry Andric 
VerifyJobAction(ActionClass Kind,Action * Input,types::ID Type)4120b57cec5SDimitry Andric VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
4130b57cec5SDimitry Andric                                  types::ID Type)
4140b57cec5SDimitry Andric     : JobAction(Kind, Input, Type) {
4150b57cec5SDimitry Andric   assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
4160b57cec5SDimitry Andric          "ActionClass is not a valid VerifyJobAction");
4170b57cec5SDimitry Andric }
4180b57cec5SDimitry Andric 
anchor()4190b57cec5SDimitry Andric void VerifyDebugInfoJobAction::anchor() {}
4200b57cec5SDimitry Andric 
VerifyDebugInfoJobAction(Action * Input,types::ID Type)4210b57cec5SDimitry Andric VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
4220b57cec5SDimitry Andric                                                    types::ID Type)
4230b57cec5SDimitry Andric     : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {}
4240b57cec5SDimitry Andric 
anchor()4250b57cec5SDimitry Andric void VerifyPCHJobAction::anchor() {}
4260b57cec5SDimitry Andric 
VerifyPCHJobAction(Action * Input,types::ID Type)4270b57cec5SDimitry Andric VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
4280b57cec5SDimitry Andric     : VerifyJobAction(VerifyPCHJobClass, Input, Type) {}
4290b57cec5SDimitry Andric 
anchor()4300b57cec5SDimitry Andric void OffloadBundlingJobAction::anchor() {}
4310b57cec5SDimitry Andric 
OffloadBundlingJobAction(ActionList & Inputs)4320b57cec5SDimitry Andric OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs)
4330b57cec5SDimitry Andric     : JobAction(OffloadBundlingJobClass, Inputs, Inputs.back()->getType()) {}
4340b57cec5SDimitry Andric 
anchor()4350b57cec5SDimitry Andric void OffloadUnbundlingJobAction::anchor() {}
4360b57cec5SDimitry Andric 
OffloadUnbundlingJobAction(Action * Input)4370b57cec5SDimitry Andric OffloadUnbundlingJobAction::OffloadUnbundlingJobAction(Action *Input)
4380b57cec5SDimitry Andric     : JobAction(OffloadUnbundlingJobClass, Input, Input->getType()) {}
439a7dea167SDimitry Andric 
anchor()44081ad6265SDimitry Andric void OffloadPackagerJobAction::anchor() {}
44181ad6265SDimitry Andric 
OffloadPackagerJobAction(ActionList & Inputs,types::ID Type)44281ad6265SDimitry Andric OffloadPackagerJobAction::OffloadPackagerJobAction(ActionList &Inputs,
44381ad6265SDimitry Andric                                                    types::ID Type)
44481ad6265SDimitry Andric     : JobAction(OffloadPackagerJobClass, Inputs, Type) {}
44581ad6265SDimitry Andric 
anchor()4461fd87a68SDimitry Andric void LinkerWrapperJobAction::anchor() {}
4471fd87a68SDimitry Andric 
LinkerWrapperJobAction(ActionList & Inputs,types::ID Type)4481fd87a68SDimitry Andric LinkerWrapperJobAction::LinkerWrapperJobAction(ActionList &Inputs,
4491fd87a68SDimitry Andric                                                types::ID Type)
4501fd87a68SDimitry Andric     : JobAction(LinkerWrapperJobClass, Inputs, Type) {}
4511fd87a68SDimitry Andric 
anchor()4525ffd83dbSDimitry Andric void StaticLibJobAction::anchor() {}
4535ffd83dbSDimitry Andric 
StaticLibJobAction(ActionList & Inputs,types::ID Type)4545ffd83dbSDimitry Andric StaticLibJobAction::StaticLibJobAction(ActionList &Inputs, types::ID Type)
4555ffd83dbSDimitry Andric     : JobAction(StaticLibJobClass, Inputs, Type) {}
456*06c3fb27SDimitry Andric 
anchor()457*06c3fb27SDimitry Andric void BinaryAnalyzeJobAction::anchor() {}
458*06c3fb27SDimitry Andric 
BinaryAnalyzeJobAction(Action * Input,types::ID Type)459*06c3fb27SDimitry Andric BinaryAnalyzeJobAction::BinaryAnalyzeJobAction(Action *Input, types::ID Type)
460*06c3fb27SDimitry Andric     : JobAction(BinaryAnalyzeJobClass, Input, Type) {}
461