12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/Support/ErrorHandling.h"
15 #include "llvm/Support/Regex.h"
17 using namespace clang::driver;
18 using namespace llvm::opt;
24 case InputClass:
return "input";
25 case BindArchClass:
return "bind-arch";
28 case PreprocessJobClass:
return "preprocessor";
29 case PrecompileJobClass:
return "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";
46 llvm_unreachable(
"invalid class");
51 if (
Kind == OffloadClass)
54 if (
Kind == OffloadUnbundlingJobClass)
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;
63 for (
auto *A : Inputs)
64 A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch);
69 if (
Kind == OffloadClass)
72 assert(OffloadingDeviceKind == OFK_None &&
73 "Setting a host kind in a device action.");
74 ActiveOffloadKindMask |= OKinds;
75 OffloadingArch = OArch;
77 for (
auto *A : Inputs)
78 A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
90 switch (OffloadingDeviceKind) {
94 llvm_unreachable(
"Host kind is not an offloading device kind.");
99 return "device-openmp";
104 if (!ActiveOffloadKindMask)
107 std::string Res(
"host");
108 if (ActiveOffloadKindMask & OFK_Cuda)
110 if (ActiveOffloadKindMask & OFK_OpenMP)
122 llvm::StringRef NormalizedTriple,
123 bool CreatePrefixForHost) {
125 if (!CreatePrefixForHost && (Kind == OFK_None || Kind == OFK_Host))
128 std::string Res(
"-");
129 Res += GetOffloadKindName(Kind);
131 Res += NormalizedTriple;
150 llvm_unreachable(
"invalid offload kind");
153 void InputAction::anchor() {}
159 void BindArchAction::anchor() {}
162 :
Action(BindArchClass, Input), ArchName(ArchName) {}
164 void OffloadAction::anchor() {}
167 :
Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
175 :
Action(OffloadClass, DDeps.getActions(), Ty),
176 DevToolChains(DDeps.getToolChains()) {
181 if (llvm::all_of(OKinds, [&](
OffloadKind K) {
return K == OKinds.front(); }))
185 if (OKinds.size() == 1)
190 getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]);
195 :
Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
196 DevToolChains(DDeps.getToolChains()) {
205 for (
unsigned i = 0, e = DDeps.
getActions().size(); i != e; ++i)
216 assert(!
getInputs().empty() &&
"No dependencies for offload action??");
218 Work(A, HostTC, A->getOffloadingArch());
231 assert(
getInputs().
size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
232 "Sizes of action dependences and toolchains are not consistent!");
238 auto TI = DevToolChains.begin();
239 for (;
I !=
E; ++
I, ++TI)
240 Work(*
I, *TI, (*I)->getOffloadingArch());
250 if (IsHostDependence)
260 assert(!
getInputs().empty() &&
"No dependencies for offload action??");
261 return HostTC ?
getInputs().front() :
nullptr;
265 bool DoNotConsiderHostActions)
const {
266 if (DoNotConsiderHostActions)
267 return getInputs().size() == (HostTC ? 2 : 1);
268 return !HostTC &&
getInputs().size() == 1;
274 "Single device dependence does not exist!");
281 const char *BoundArch,
283 DeviceActions.push_back(&A);
284 DeviceToolChains.push_back(&TC);
285 DeviceBoundArchs.push_back(BoundArch);
286 DeviceOffloadKinds.push_back(OKind);
290 const char *BoundArch,
292 : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) {
294 HostOffloadKinds |= K;
297 void JobAction::anchor() {}
300 :
Action(Kind, Input, Type) {}
303 :
Action(Kind, Inputs, Type) {
306 void PreprocessJobAction::anchor() {}
309 :
JobAction(PreprocessJobClass, Input, OutputType) {}
311 void PrecompileJobAction::anchor() {}
314 :
JobAction(PrecompileJobClass, Input, OutputType) {}
316 void AnalyzeJobAction::anchor() {}
319 :
JobAction(AnalyzeJobClass, Input, OutputType) {}
321 void MigrateJobAction::anchor() {}
324 :
JobAction(MigrateJobClass, Input, OutputType) {}
326 void CompileJobAction::anchor() {}
329 :
JobAction(CompileJobClass, Input, OutputType) {}
331 void BackendJobAction::anchor() {}
334 :
JobAction(BackendJobClass, Input, OutputType) {}
336 void AssembleJobAction::anchor() {}
339 :
JobAction(AssembleJobClass, Input, OutputType) {}
341 void LinkJobAction::anchor() {}
344 :
JobAction(LinkJobClass, Inputs, Type) {
347 void LipoJobAction::anchor() {}
350 :
JobAction(LipoJobClass, Inputs, Type) {
353 void DsymutilJobAction::anchor() {}
356 :
JobAction(DsymutilJobClass, Inputs, Type) {
359 void VerifyJobAction::anchor() {}
365 "ActionClass is not a valid VerifyJobAction");
368 void VerifyDebugInfoJobAction::anchor() {}
374 void VerifyPCHJobAction::anchor() {}
379 void OffloadBundlingJobAction::anchor() {}
382 :
JobAction(OffloadBundlingJobClass, Inputs, Inputs.front()->getType()) {}
384 void OffloadUnbundlingJobAction::anchor() {}
387 :
JobAction(OffloadUnbundlingJobClass, Input, Input->getType()) {}
const ActionList & getActions() const
Get each of the individual arrays.
AssembleJobAction(Action *Input, types::ID OutputType)
OffloadAction(const HostDependence &HDep)
PrecompileJobAction(Action *Input, types::ID OutputType)
BackendJobAction(Action *Input, types::ID OutputType)
const char * getBoundArch() const
MigrateJobAction(Action *Input, types::ID OutputType)
bool hasSingleDeviceDependence(bool DoNotConsiderHostActions=false) const
Return true if the action has a single device dependence.
The base class of the type hierarchy.
unsigned getOffloadKinds() const
LinkJobAction(ActionList &Inputs, types::ID Type)
Type used to communicate device actions.
llvm::function_ref< void(Action *, const ToolChain *, const char *)> OffloadActionWorkTy
VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type)
VerifyDebugInfoJobAction(Action *Input, types::ID Type)
CompileJobAction(Action *Input, types::ID OutputType)
JobAction(ActionClass Kind, Action *Input, types::ID Type)
Action * getAction() const
OffloadKind OffloadingDeviceKind
Offloading kind of the device.
OffloadKind getOffloadingDeviceKind() const
LipoJobAction(ActionList &Inputs, types::ID Type)
Type used to communicate host actions.
unsigned getOffloadingHostActiveKinds() const
Action - Represent an abstract compilation step to perform.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateOffloadInfo(const Action *A)
Set the offload info of this action to be the same as the provided action, and propagate it to its de...
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, llvm::StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
void doOnHostDependence(const OffloadActionWorkTy &Work) const
Execute the work specified in Work on the host dependence.
DsymutilJobAction(ActionList &Inputs, types::ID Type)
PreprocessJobAction(Action *Input, types::ID OutputType)
detail::InMemoryDirectory::const_iterator I
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch)
Set the device offload info of this action and propagate it to its dependences.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add a action along with the associated toolchain, bound arch, and offload kind.
unsigned ActiveOffloadKindMask
Offload information.
void doOnEachDeviceDependence(const OffloadActionWorkTy &Work) const
Execute the work specified in Work on each device dependence.
const OffloadKindList & getOffloadKinds() const
VerifyPCHJobAction(Action *Input, types::ID Type)
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getOffloadingArch() const
HostDependence(Action &A, const ToolChain &TC, const char *BoundArch, const unsigned OffloadKinds)
const char * OffloadingArch
The Offloading architecture associated with this action.
BindArchAction(Action *Input, StringRef ArchName)
void doOnEachDependence(const OffloadActionWorkTy &Work) const
Execute the work specified in Work on each dependence.
OffloadUnbundlingJobAction(Action *Input)
AnalyzeJobAction(Action *Input, types::ID OutputType)
OffloadBundlingJobAction(ActionList &Inputs)
Action * getHostDependence() const
Return the host dependence of this action.
const char * getClassName() const
const BoundArchList & getBoundArchs() const
detail::InMemoryDirectory::const_iterator E
Action * getSingleDeviceDependence(bool DoNotConsiderHostActions=false) const
Return the single device dependence of this action.
bool hasHostDependence() const
Return true if the action has a host dependence.
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.