12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/Support/ErrorHandling.h"
14 #include "llvm/Support/Regex.h"
16 using namespace clang::driver;
17 using namespace llvm::opt;
23 case InputClass:
return "input";
24 case BindArchClass:
return "bind-arch";
27 case PreprocessJobClass:
return "preprocessor";
28 case PrecompileJobClass:
return "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 LinkJobClass:
return "linker";
35 case LipoJobClass:
return "lipo";
36 case DsymutilJobClass:
return "dsymutil";
37 case VerifyDebugInfoJobClass:
return "verify-debug-info";
38 case VerifyPCHJobClass:
return "verify-pch";
41 llvm_unreachable(
"invalid class");
46 if (
Kind == OffloadClass)
49 assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
50 "Setting device kind to a different device??");
51 assert(!ActiveOffloadKindMask &&
"Setting a device kind in a host action??");
52 OffloadingDeviceKind = OKind;
53 OffloadingArch = OArch;
55 for (
auto *A : Inputs)
56 A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch);
61 if (
Kind == OffloadClass)
64 assert(OffloadingDeviceKind == OFK_None &&
65 "Setting a host kind in a device action.");
66 ActiveOffloadKindMask |= OKinds;
67 OffloadingArch = OArch;
69 for (
auto *A : Inputs)
70 A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
82 switch (OffloadingDeviceKind) {
86 llvm_unreachable(
"Host kind is not an offloading device kind.");
94 if (!ActiveOffloadKindMask)
97 std::string Res(
"host");
98 if (ActiveOffloadKindMask & OFK_Cuda)
110 if (!OffloadingDeviceKind)
113 std::string Res(
"-");
114 Res += getOffloadingKindPrefix();
116 Res += NormalizedTriple;
120 void InputAction::anchor() {}
126 void BindArchAction::anchor() {}
129 :
Action(BindArchClass, Input), ArchName(_ArchName) {}
131 void OffloadAction::anchor() {}
134 :
Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
142 :
Action(OffloadClass, DDeps.getActions(), Ty),
143 DevToolChains(DDeps.getToolChains()) {
148 if (llvm::all_of(OKinds, [&](
OffloadKind K) {
return K == OKinds.front(); }))
152 if (OKinds.size() == 1)
157 getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]);
162 :
Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
163 DevToolChains(DDeps.getToolChains()) {
172 for (
unsigned i = 0, e = DDeps.
getActions().size(); i != e; ++i)
183 assert(!
getInputs().empty() &&
"No dependencies for offload action??");
185 Work(A, HostTC, A->getOffloadingArch());
198 assert(
getInputs().
size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
199 "Sizes of action dependences and toolchains are not consistent!");
205 auto TI = DevToolChains.begin();
206 for (;
I !=
E; ++
I, ++TI)
207 Work(*
I, *TI, (*I)->getOffloadingArch());
217 if (IsHostDependence)
227 assert(!
getInputs().empty() &&
"No dependencies for offload action??");
228 return HostTC ?
getInputs().front() :
nullptr;
232 bool DoNotConsiderHostActions)
const {
233 if (DoNotConsiderHostActions)
234 return getInputs().size() == (HostTC ? 2 : 1);
235 return !HostTC &&
getInputs().size() == 1;
241 "Single device dependence does not exist!");
248 const char *BoundArch,
250 DeviceActions.push_back(&A);
251 DeviceToolChains.push_back(&TC);
252 DeviceBoundArchs.push_back(BoundArch);
253 DeviceOffloadKinds.push_back(OKind);
257 const char *BoundArch,
259 : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) {
261 HostOffloadKinds |= K;
264 void JobAction::anchor() {}
267 :
Action(Kind, Input, Type) {}
270 :
Action(Kind, Inputs, Type) {
273 void PreprocessJobAction::anchor() {}
276 :
JobAction(PreprocessJobClass, Input, OutputType) {}
278 void PrecompileJobAction::anchor() {}
281 :
JobAction(PrecompileJobClass, Input, OutputType) {}
283 void AnalyzeJobAction::anchor() {}
286 :
JobAction(AnalyzeJobClass, Input, OutputType) {}
288 void MigrateJobAction::anchor() {}
291 :
JobAction(MigrateJobClass, Input, OutputType) {}
293 void CompileJobAction::anchor() {}
296 :
JobAction(CompileJobClass, Input, OutputType) {}
298 void BackendJobAction::anchor() {}
301 :
JobAction(BackendJobClass, Input, OutputType) {}
303 void AssembleJobAction::anchor() {}
306 :
JobAction(AssembleJobClass, Input, OutputType) {}
308 void LinkJobAction::anchor() {}
311 :
JobAction(LinkJobClass, Inputs, Type) {
314 void LipoJobAction::anchor() {}
317 :
JobAction(LipoJobClass, Inputs, Type) {
320 void DsymutilJobAction::anchor() {}
323 :
JobAction(DsymutilJobClass, Inputs, Type) {
326 void VerifyJobAction::anchor() {}
332 "ActionClass is not a valid VerifyJobAction");
335 void VerifyDebugInfoJobAction::anchor() {}
341 void VerifyPCHJobAction::anchor() {}
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...
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)
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.
void doOnEachDependence(const OffloadActionWorkTy &Work) const
Execute the work specified in Work on each dependence.
AnalyzeJobAction(Action *Input, types::ID OutputType)
Action * getHostDependence() const
Return the host dependence of this action.
const char * getClassName() const
BindArchAction(Action *Input, const char *ArchName)
const BoundArchList & getBoundArchs() const
detail::InMemoryDirectory::const_iterator E
Action * getSingleDeviceDependence(bool DoNotConsiderHostActions=false) const
Return the single device dependence of this action.
std::string getOffloadingFileNamePrefix(llvm::StringRef NormalizedTriple) const
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
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.