clang 24.0.0git
Action.cpp
Go to the documentation of this file.
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
10#include "llvm/Support/ErrorHandling.h"
11#include <cassert>
12#include <string>
13
14using namespace clang;
15using namespace driver;
16using namespace llvm::opt;
17
18Action::~Action() = default;
19
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";
29 return "api-extractor";
30 case AnalyzeJobClass:
31 return "analyzer";
32 case CompileJobClass: return "compiler";
33 case BackendJobClass: return "backend";
34 case AssembleJobClass: return "assembler";
35 case IfsMergeJobClass: return "interface-stub-merger";
36 case LinkJobClass: return "linker";
37 case LipoJobClass: return "lipo";
38 case DsymutilJobClass: return "dsymutil";
39 case VerifyDebugInfoJobClass: return "verify-debug-info";
40 case VerifyPCHJobClass: return "verify-pch";
42 return "clang-offload-bundler";
44 return "llvm-offload-binary";
46 return "clang-linker-wrapper";
48 return "static-lib-linker";
50 return "binary-analyzer";
52 return "binary-translator";
53 case ObjcopyJobClass:
54 return "objcopy";
55 }
56
57 llvm_unreachable("invalid class");
58}
59
61 const ToolChain *OToolChain) {
62 // Offload action set its own kinds on their dependences.
63 if (Kind == OffloadClass)
64 return;
65
66 assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
67 "Setting device kind to a different device??");
68 assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??");
70 OffloadingArch = OArch;
71 OffloadingToolChain = OToolChain;
72
73 for (auto *A : Inputs)
74 A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch, OToolChain);
75}
76
77void Action::propagateHostOffloadInfo(unsigned OKinds, BoundArch OArch) {
78 // Offload action set its own kinds on their dependences.
79 if (Kind == OffloadClass)
80 return;
81
83 "Setting a host kind in a device action.");
84 ActiveOffloadKindMask |= OKinds;
85 OffloadingArch = OArch;
86
87 for (auto *A : Inputs)
88 A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
89}
90
99
101 switch (OffloadingDeviceKind) {
102 case OFK_None:
103 break;
104 case OFK_Host:
105 llvm_unreachable("Host kind is not an offloading device kind.");
106 break;
107 case OFK_Cuda:
108 return "device-cuda";
109 case OFK_OpenMP:
110 return "device-openmp";
111 case OFK_HIP:
112 return "device-hip";
113 case OFK_SYCL:
114 return "device-sycl";
115
116 // TODO: Add other programming models here.
117 }
118
120 return {};
121
122 std::string Res("host");
123 assert(!((ActiveOffloadKindMask & OFK_Cuda) &&
125 "Cannot offload CUDA and HIP at the same time");
127 Res += "-cuda";
129 Res += "-hip";
131 Res += "-openmp";
133 Res += "-sycl";
134
135 // TODO: Add other programming models here.
136
137 return Res;
138}
139
140/// Return a string that can be used as prefix in order to generate unique files
141/// for each offloading kind.
142std::string
144 StringRef NormalizedTriple,
145 bool CreatePrefixForHost) {
146 // Don't generate prefix for host actions unless required.
147 if (!CreatePrefixForHost && (Kind == OFK_None || Kind == OFK_Host))
148 return {};
149
150 std::string Res("-");
151 Res += GetOffloadKindName(Kind);
152 Res += "-";
153 Res += NormalizedTriple;
154 return Res;
155}
156
157/// Return a string with the offload kind name. If that is not defined, we
158/// assume 'host'.
160 switch (Kind) {
161 case OFK_None:
162 case OFK_Host:
163 return "host";
164 case OFK_Cuda:
165 return "cuda";
166 case OFK_OpenMP:
167 return "openmp";
168 case OFK_HIP:
169 return "hip";
170 case OFK_SYCL:
171 return "sycl";
172
173 // TODO: Add other programming models here.
174 }
175
176 llvm_unreachable("invalid offload kind");
177}
178
179void InputAction::anchor() {}
180
181InputAction::InputAction(const Arg &_Input, types::ID _Type, StringRef _Id)
182 : Action(InputClass, _Type), Input(_Input), Id(_Id.str()) {}
183
184void BindArchAction::anchor() {}
185
187 : Action(BindArchClass, Input), ArchName(ArchName) {}
188
189void OffloadAction::anchor() {}
190
192 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
197}
198
200 : Action(OffloadClass, DDeps.getActions(), Ty),
201 DevToolChains(DDeps.getToolChains()) {
202 auto &OKinds = DDeps.getOffloadKinds();
203 auto &BArchs = DDeps.getBoundArchs();
204 auto &OTCs = DDeps.getToolChains();
205
206 // If all inputs agree on the same kind, use it also for this action.
207 if (llvm::all_equal(OKinds))
208 OffloadingDeviceKind = OKinds.front();
209
210 // If we have a single dependency, inherit the architecture from it.
211 if (OKinds.size() == 1)
212 OffloadingArch = BArchs.front();
213
214 // Propagate info to the dependencies.
215 for (unsigned i = 0, e = getInputs().size(); i != e; ++i)
216 getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i], OTCs[i]);
217}
218
220 const DeviceDependences &DDeps)
221 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
222 DevToolChains(DDeps.getToolChains()) {
223 // We use the kinds of the host dependence for this action.
224 BoundArch BA = HDep.getBoundArch();
227
228 // Add device inputs and propagate info to the device actions. Do work only if
229 // we have dependencies.
230 for (unsigned i = 0, e = DDeps.getActions().size(); i != e; ++i) {
231 if (auto *A = DDeps.getActions()[i]) {
232 getInputs().push_back(A);
233 A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i],
234 DDeps.getBoundArchs()[i],
235 DDeps.getToolChains()[i]);
236 // If this action is used to forward single dependency, set the toolchain.
237 if (DDeps.getActions().size() == 1)
238 OffloadingToolChain = DDeps.getToolChains()[i];
239 }
240 }
241}
242
244 if (!HostTC)
245 return;
246 assert(!getInputs().empty() && "No dependencies for offload action??");
247 auto *A = getInputs().front();
248 Work(A, HostTC, A->getOffloadingArch());
249}
250
252 const OffloadActionWorkTy &Work) const {
253 auto I = getInputs().begin();
254 auto E = getInputs().end();
255 if (I == E)
256 return;
257
258 // We expect to have the same number of input dependences and device tool
259 // chains, except if we also have a host dependence. In that case we have one
260 // more dependence than we have device tool chains.
261 assert(getInputs().size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
262 "Sizes of action dependences and toolchains are not consistent!");
263
264 // Skip host action
265 if (HostTC)
266 ++I;
267
268 auto TI = DevToolChains.begin();
269 for (; I != E; ++I, ++TI)
270 Work(*I, *TI, (*I)->getOffloadingArch());
271}
272
277
278void OffloadAction::doOnEachDependence(bool IsHostDependence,
279 const OffloadActionWorkTy &Work) const {
280 if (IsHostDependence)
281 doOnHostDependence(Work);
282 else
284}
285
286bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; }
287
289 assert(hasHostDependence() && "Host dependence does not exist!");
290 assert(!getInputs().empty() && "No dependencies for offload action??");
291 return HostTC ? getInputs().front() : nullptr;
292}
293
295 bool DoNotConsiderHostActions) const {
296 if (DoNotConsiderHostActions)
297 return getInputs().size() == (HostTC ? 2 : 1);
298 return !HostTC && getInputs().size() == 1;
299}
300
301Action *
302OffloadAction::getSingleDeviceDependence(bool DoNotConsiderHostActions) const {
303 assert(hasSingleDeviceDependence(DoNotConsiderHostActions) &&
304 "Single device dependence does not exist!");
305 // The previous assert ensures the number of entries in getInputs() is
306 // consistent with what we are doing here.
307 return HostTC ? getInputs()[1] : getInputs().front();
308}
309
311 BoundArch BA, OffloadKind OKind) {
312 DeviceActions.push_back(&A);
313 DeviceToolChains.push_back(&TC);
314 DeviceBoundArchs.push_back(BA);
315 DeviceOffloadKinds.push_back(OKind);
316}
317
319 BoundArch BA,
320 unsigned OffloadKindMask) {
321 DeviceActions.push_back(&A);
322 DeviceToolChains.push_back(&TC);
323 DeviceBoundArchs.push_back(BA);
324
325 // Add each active offloading kind from a mask.
327 if (OKind & OffloadKindMask)
328 DeviceOffloadKinds.push_back(OKind);
329}
330
332 BoundArch BA,
333 const DeviceDependences &DDeps)
334 : HostAction(A), HostToolChain(TC), HostBoundArch(BA) {
335 for (auto K : DDeps.getOffloadKinds())
336 HostOffloadKinds |= K;
337}
338
339void JobAction::anchor() {}
340
342 : Action(Kind, Input, Type) {}
343
345 : Action(Kind, Inputs, Type) {}
346
347void PreprocessJobAction::anchor() {}
348
351
352void PrecompileJobAction::anchor() {}
353
356
358 types::ID OutputType)
359 : JobAction(Kind, Input, OutputType) {
360 assert(isa<PrecompileJobAction>((Action*)this) && "invalid action kind");
361}
362
363void ExtractAPIJobAction::anchor() {}
364
367
368void AnalyzeJobAction::anchor() {}
369
371 : JobAction(AnalyzeJobClass, Input, OutputType) {}
372
373void CompileJobAction::anchor() {}
374
376 : JobAction(CompileJobClass, Input, OutputType) {}
377
378void BackendJobAction::anchor() {}
379
381 : JobAction(BackendJobClass, Input, OutputType) {}
382
383void AssembleJobAction::anchor() {}
384
386 : JobAction(AssembleJobClass, Input, OutputType) {}
387
388void IfsMergeJobAction::anchor() {}
389
392
393void LinkJobAction::anchor() {}
394
397
398void LipoJobAction::anchor() {}
399
402
403void DsymutilJobAction::anchor() {}
404
407
408void VerifyJobAction::anchor() {}
409
411 types::ID Type)
412 : JobAction(Kind, Input, Type) {
413 assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
414 "ActionClass is not a valid VerifyJobAction");
415}
416
417void VerifyDebugInfoJobAction::anchor() {}
418
422
423void VerifyPCHJobAction::anchor() {}
424
427
428void OffloadBundlingJobAction::anchor() {}
429
432
433void OffloadPackagerJobAction::anchor() {}
434
438
439void LinkerWrapperJobAction::anchor() {}
440
444
445void StaticLibJobAction::anchor() {}
446
449
450void BinaryAnalyzeJobAction::anchor() {}
451
454
455void BinaryTranslatorJobAction::anchor() {}
456
460
461void ObjcopyJobAction::anchor() {}
462
Action - Represent an abstract compilation step to perform.
Definition Action.h:48
OffloadKind OffloadingDeviceKind
Offloading kind of the device.
Definition Action.h:131
Action(ActionClass Kind, types::ID Type)
Definition Action.h:139
size_type size() const
Definition Action.h:158
types::ID getType() const
Definition Action.h:153
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
Definition Action.cpp:100
const ToolChain * getOffloadingToolChain() const
Definition Action.h:217
const ToolChain * OffloadingToolChain
The Offloading toolchain associated with this device action.
Definition Action.h:137
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
Definition Action.cpp:143
BoundArch getOffloadingArch() const
Definition Action.h:216
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...
Definition Action.cpp:91
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
Definition Action.cpp:159
const char * getClassName() const
Definition Action.h:150
OffloadKind getOffloadingDeviceKind() const
Definition Action.h:215
void propagateDeviceOffloadInfo(OffloadKind OKind, BoundArch OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
Definition Action.cpp:60
unsigned ActiveOffloadKindMask
Offload information.
Definition Action.h:128
void propagateHostOffloadInfo(unsigned OKinds, BoundArch OArch)
Append the host offload info of this action and propagate it to its dependences.
Definition Action.cpp:77
BoundArch OffloadingArch
The Offloading architecture associated with this action.
Definition Action.h:134
ActionList & getInputs()
Definition Action.h:155
unsigned getOffloadingHostActiveKinds() const
Definition Action.h:211
AnalyzeJobAction(Action *Input, types::ID OutputType)
Definition Action.cpp:370
AssembleJobAction(Action *Input, types::ID OutputType)
Definition Action.cpp:385
BackendJobAction(Action *Input, types::ID OutputType)
Definition Action.cpp:380
BinaryAnalyzeJobAction(Action *Input, types::ID Type)
Definition Action.cpp:452
BinaryTranslatorJobAction(Action *Input, types::ID Type)
Definition Action.cpp:457
BindArchAction(Action *Input, BoundArch ArchName)
Definition Action.cpp:186
CompileJobAction(Action *Input, types::ID OutputType)
Definition Action.cpp:375
DsymutilJobAction(ActionList &Inputs, types::ID Type)
Definition Action.cpp:405
ExtractAPIJobAction(Action *Input, types::ID OutputType)
Definition Action.cpp:365
IfsMergeJobAction(ActionList &Inputs, types::ID Type)
Definition Action.cpp:390
InputAction(const llvm::opt::Arg &Input, types::ID Type, StringRef Id=StringRef())
Definition Action.cpp:181
JobAction(ActionClass Kind, Action *Input, types::ID Type)
Definition Action.cpp:341
LinkJobAction(ActionList &Inputs, types::ID Type)
Definition Action.cpp:395
LinkerWrapperJobAction(ActionList &Inputs, types::ID Type)
Definition Action.cpp:441
LipoJobAction(ActionList &Inputs, types::ID Type)
Definition Action.cpp:400
ObjcopyJobAction(ActionList &Inputs, types::ID Type)
Definition Action.cpp:463
Type used to communicate device actions.
Definition Action.h:279
const BoundArchList & getBoundArchs() const
Definition Action.h:316
const OffloadKindList & getOffloadKinds() const
Definition Action.h:317
const ActionList & getActions() const
Get each of the individual arrays.
Definition Action.h:314
void add(Action &A, const ToolChain &TC, BoundArch BA, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
Definition Action.cpp:310
const ToolChainList & getToolChains() const
Definition Action.h:315
Type used to communicate host actions.
Definition Action.h:324
HostDependence(Action &A, const ToolChain &TC, BoundArch BA, const unsigned OffloadKinds)
Definition Action.h:338
void doOnEachDependence(const OffloadActionWorkTy &Work) const
Execute the work specified in Work on each dependence.
Definition Action.cpp:273
Action * getSingleDeviceDependence(bool DoNotConsiderHostActions=false) const
Return the single device dependence of this action.
Definition Action.cpp:302
bool hasSingleDeviceDependence(bool DoNotConsiderHostActions=false) const
Return true if the action has a single device dependence.
Definition Action.cpp:294
Action * getHostDependence() const
Return the host dependence of this action.
Definition Action.cpp:288
void doOnEachDeviceDependence(const OffloadActionWorkTy &Work) const
Execute the work specified in Work on each device dependence.
Definition Action.cpp:251
bool hasHostDependence() const
Return true if the action has a host dependence.
Definition Action.cpp:286
llvm::function_ref< void(Action *, const ToolChain *, BoundArch)> OffloadActionWorkTy
Definition Action.h:353
void doOnHostDependence(const OffloadActionWorkTy &Work) const
Execute the work specified in Work on the host dependence.
Definition Action.cpp:243
OffloadAction(const HostDependence &HDep)
Definition Action.cpp:191
OffloadBundlingJobAction(ActionList &Inputs)
Definition Action.cpp:430
OffloadPackagerJobAction(ActionList &Inputs, types::ID Type)
Definition Action.cpp:435
PrecompileJobAction(ActionClass Kind, Action *Input, types::ID OutputType)
Definition Action.cpp:357
PreprocessJobAction(Action *Input, types::ID OutputType)
Definition Action.cpp:349
StaticLibJobAction(ActionList &Inputs, types::ID Type)
Definition Action.cpp:447
ToolChain - Access to tools for a single platform.
Definition ToolChain.h:92
VerifyDebugInfoJobAction(Action *Input, types::ID Type)
Definition Action.cpp:419
VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type)
Definition Action.cpp:410
VerifyPCHJobAction(Action *Input, types::ID Type)
Definition Action.cpp:425
SmallVector< Action *, 3 > ActionList
ActionList - Type used for lists of actions.
Definition Util.h:25
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
for(const auto &A :T->param_types())
Represents a bound architecture for offload / multiple architecture compilation.