clang  10.0.0svn
Action.h
Go to the documentation of this file.
1 //===- Action.h - Abstract compilation steps --------------------*- C++ -*-===//
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 #ifndef LLVM_CLANG_DRIVER_ACTION_H
10 #define LLVM_CLANG_DRIVER_ACTION_H
11 
12 #include "clang/Basic/LLVM.h"
13 #include "clang/Driver/Types.h"
14 #include "clang/Driver/Util.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/iterator_range.h"
20 #include <string>
21 
22 namespace llvm {
23 namespace opt {
24 
25 class Arg;
26 
27 } // namespace opt
28 } // namespace llvm
29 
30 namespace clang {
31 namespace driver {
32 
33 class ToolChain;
34 
35 /// Action - Represent an abstract compilation step to perform.
36 ///
37 /// An action represents an edge in the compilation graph; typically
38 /// it is a job to transform an input using some tool.
39 ///
40 /// The current driver is hard wired to expect actions which produce a
41 /// single primary output, at least in terms of controlling the
42 /// compilation. Actions can produce auxiliary files, but can only
43 /// produce a single output to feed into subsequent actions.
44 ///
45 /// Actions are usually owned by a Compilation, which creates new
46 /// actions via MakeAction().
47 class Action {
48 public:
49  using size_type = ActionList::size_type;
50  using input_iterator = ActionList::iterator;
51  using input_const_iterator = ActionList::const_iterator;
52  using input_range = llvm::iterator_range<input_iterator>;
53  using input_const_range = llvm::iterator_range<input_const_iterator>;
54 
55  enum ActionClass {
56  InputClass = 0,
76 
77  JobClassFirst = PreprocessJobClass,
78  JobClassLast = OffloadWrapperJobClass
79  };
80 
81  // The offloading kind determines if this action is binded to a particular
82  // programming model. Each entry reserves one bit. We also have a special kind
83  // to designate the host offloading tool chain.
84  enum OffloadKind {
85  OFK_None = 0x00,
86 
87  // The host offloading tool chain.
88  OFK_Host = 0x01,
89 
90  // The device offloading tool chains - one bit for each programming model.
91  OFK_Cuda = 0x02,
92  OFK_OpenMP = 0x04,
93  OFK_HIP = 0x08,
94  };
95 
96  static const char *getClassName(ActionClass AC);
97 
98 private:
100 
101  /// The output type of this action.
102  types::ID Type;
103 
104  ActionList Inputs;
105 
106  /// Flag that is set to true if this action can be collapsed with others
107  /// actions that depend on it. This is true by default and set to false when
108  /// the action is used by two different tool chains, which is enabled by the
109  /// offloading support implementation.
110  bool CanBeCollapsedWithNextDependentAction = true;
111 
112 protected:
113  ///
114  /// Offload information.
115  ///
116 
117  /// The host offloading kind - a combination of kinds encoded in a mask.
118  /// Multiple programming models may be supported simultaneously by the same
119  /// host.
120  unsigned ActiveOffloadKindMask = 0u;
121 
122  /// Offloading kind of the device.
123  OffloadKind OffloadingDeviceKind = OFK_None;
124 
125  /// The Offloading architecture associated with this action.
126  const char *OffloadingArch = nullptr;
127 
128  Action(ActionClass Kind, types::ID Type) : Action(Kind, ActionList(), Type) {}
129  Action(ActionClass Kind, Action *Input, types::ID Type)
130  : Action(Kind, ActionList({Input}), Type) {}
131  Action(ActionClass Kind, Action *Input)
132  : Action(Kind, ActionList({Input}), Input->getType()) {}
133  Action(ActionClass Kind, const ActionList &Inputs, types::ID Type)
134  : Kind(Kind), Type(Type), Inputs(Inputs) {}
135 
136 public:
137  virtual ~Action();
138 
139  const char *getClassName() const { return Action::getClassName(getKind()); }
140 
141  ActionClass getKind() const { return Kind; }
142  types::ID getType() const { return Type; }
143 
144  ActionList &getInputs() { return Inputs; }
145  const ActionList &getInputs() const { return Inputs; }
146 
147  size_type size() const { return Inputs.size(); }
148 
149  input_iterator input_begin() { return Inputs.begin(); }
150  input_iterator input_end() { return Inputs.end(); }
151  input_range inputs() { return input_range(input_begin(), input_end()); }
152  input_const_iterator input_begin() const { return Inputs.begin(); }
153  input_const_iterator input_end() const { return Inputs.end(); }
155  return input_const_range(input_begin(), input_end());
156  }
157 
158  /// Mark this action as not legal to collapse.
160  CanBeCollapsedWithNextDependentAction = false;
161  }
162 
163  /// Return true if this function can be collapsed with others.
165  return CanBeCollapsedWithNextDependentAction;
166  }
167 
168  /// Return a string containing the offload kind of the action.
169  std::string getOffloadingKindPrefix() const;
170 
171  /// Return a string that can be used as prefix in order to generate unique
172  /// files for each offloading kind. By default, no prefix is used for
173  /// non-device kinds, except if \a CreatePrefixForHost is set.
174  static std::string
175  GetOffloadingFileNamePrefix(OffloadKind Kind,
176  StringRef NormalizedTriple,
177  bool CreatePrefixForHost = false);
178 
179  /// Return a string containing a offload kind name.
180  static StringRef GetOffloadKindName(OffloadKind Kind);
181 
182  /// Set the device offload info of this action and propagate it to its
183  /// dependences.
184  void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch);
185 
186  /// Append the host offload info of this action and propagate it to its
187  /// dependences.
188  void propagateHostOffloadInfo(unsigned OKinds, const char *OArch);
189 
190  /// Set the offload info of this action to be the same as the provided action,
191  /// and propagate it to its dependences.
192  void propagateOffloadInfo(const Action *A);
193 
194  unsigned getOffloadingHostActiveKinds() const {
195  return ActiveOffloadKindMask;
196  }
197 
198  OffloadKind getOffloadingDeviceKind() const { return OffloadingDeviceKind; }
199  const char *getOffloadingArch() const { return OffloadingArch; }
200 
201  /// Check if this action have any offload kinds. Note that host offload kinds
202  /// are only set if the action is a dependence to a host offload action.
203  bool isHostOffloading(OffloadKind OKind) const {
204  return ActiveOffloadKindMask & OKind;
205  }
206  bool isDeviceOffloading(OffloadKind OKind) const {
207  return OffloadingDeviceKind == OKind;
208  }
209  bool isOffloading(OffloadKind OKind) const {
210  return isHostOffloading(OKind) || isDeviceOffloading(OKind);
211  }
212 };
213 
214 class InputAction : public Action {
215  const llvm::opt::Arg &Input;
216 
217  virtual void anchor();
218 
219 public:
220  InputAction(const llvm::opt::Arg &Input, types::ID Type);
221 
222  const llvm::opt::Arg &getInputArg() const { return Input; }
223 
224  static bool classof(const Action *A) {
225  return A->getKind() == InputClass;
226  }
227 };
228 
229 class BindArchAction : public Action {
230  virtual void anchor();
231 
232  /// The architecture to bind, or 0 if the default architecture
233  /// should be bound.
234  StringRef ArchName;
235 
236 public:
237  BindArchAction(Action *Input, StringRef ArchName);
238 
239  StringRef getArchName() const { return ArchName; }
240 
241  static bool classof(const Action *A) {
242  return A->getKind() == BindArchClass;
243  }
244 };
245 
246 /// An offload action combines host or/and device actions according to the
247 /// programming model implementation needs and propagates the offloading kind to
248 /// its dependences.
249 class OffloadAction final : public Action {
250  virtual void anchor();
251 
252 public:
253  /// Type used to communicate device actions. It associates bound architecture,
254  /// toolchain, and offload kind to each action.
255  class DeviceDependences final {
256  public:
260 
261  private:
262  // Lists that keep the information for each dependency. All the lists are
263  // meant to be updated in sync. We are adopting separate lists instead of a
264  // list of structs, because that simplifies forwarding the actions list to
265  // initialize the inputs of the base Action class.
266 
267  /// The dependence actions.
268  ActionList DeviceActions;
269 
270  /// The offloading toolchains that should be used with the action.
271  ToolChainList DeviceToolChains;
272 
273  /// The architectures that should be used with this action.
274  BoundArchList DeviceBoundArchs;
275 
276  /// The offload kind of each dependence.
277  OffloadKindList DeviceOffloadKinds;
278 
279  public:
280  /// Add a action along with the associated toolchain, bound arch, and
281  /// offload kind.
282  void add(Action &A, const ToolChain &TC, const char *BoundArch,
283  OffloadKind OKind);
284 
285  /// Get each of the individual arrays.
286  const ActionList &getActions() const { return DeviceActions; }
287  const ToolChainList &getToolChains() const { return DeviceToolChains; }
288  const BoundArchList &getBoundArchs() const { return DeviceBoundArchs; }
290  return DeviceOffloadKinds;
291  }
292  };
293 
294  /// Type used to communicate host actions. It associates bound architecture,
295  /// toolchain, and offload kinds to the host action.
296  class HostDependence final {
297  /// The dependence action.
298  Action &HostAction;
299 
300  /// The offloading toolchain that should be used with the action.
301  const ToolChain &HostToolChain;
302 
303  /// The architectures that should be used with this action.
304  const char *HostBoundArch = nullptr;
305 
306  /// The offload kind of each dependence.
307  unsigned HostOffloadKinds = 0u;
308 
309  public:
310  HostDependence(Action &A, const ToolChain &TC, const char *BoundArch,
311  const unsigned OffloadKinds)
312  : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch),
313  HostOffloadKinds(OffloadKinds) {}
314 
315  /// Constructor version that obtains the offload kinds from the device
316  /// dependencies.
317  HostDependence(Action &A, const ToolChain &TC, const char *BoundArch,
318  const DeviceDependences &DDeps);
319  Action *getAction() const { return &HostAction; }
320  const ToolChain *getToolChain() const { return &HostToolChain; }
321  const char *getBoundArch() const { return HostBoundArch; }
322  unsigned getOffloadKinds() const { return HostOffloadKinds; }
323  };
324 
325  using OffloadActionWorkTy =
326  llvm::function_ref<void(Action *, const ToolChain *, const char *)>;
327 
328 private:
329  /// The host offloading toolchain that should be used with the action.
330  const ToolChain *HostTC = nullptr;
331 
332  /// The tool chains associated with the list of actions.
333  DeviceDependences::ToolChainList DevToolChains;
334 
335 public:
336  OffloadAction(const HostDependence &HDep);
337  OffloadAction(const DeviceDependences &DDeps, types::ID Ty);
338  OffloadAction(const HostDependence &HDep, const DeviceDependences &DDeps);
339 
340  /// Execute the work specified in \a Work on the host dependence.
341  void doOnHostDependence(const OffloadActionWorkTy &Work) const;
342 
343  /// Execute the work specified in \a Work on each device dependence.
344  void doOnEachDeviceDependence(const OffloadActionWorkTy &Work) const;
345 
346  /// Execute the work specified in \a Work on each dependence.
347  void doOnEachDependence(const OffloadActionWorkTy &Work) const;
348 
349  /// Execute the work specified in \a Work on each host or device dependence if
350  /// \a IsHostDependenceto is true or false, respectively.
351  void doOnEachDependence(bool IsHostDependence,
352  const OffloadActionWorkTy &Work) const;
353 
354  /// Return true if the action has a host dependence.
355  bool hasHostDependence() const;
356 
357  /// Return the host dependence of this action. This function is only expected
358  /// to be called if the host dependence exists.
359  Action *getHostDependence() const;
360 
361  /// Return true if the action has a single device dependence. If \a
362  /// DoNotConsiderHostActions is set, ignore the host dependence, if any, while
363  /// accounting for the number of dependences.
364  bool hasSingleDeviceDependence(bool DoNotConsiderHostActions = false) const;
365 
366  /// Return the single device dependence of this action. This function is only
367  /// expected to be called if a single device dependence exists. If \a
368  /// DoNotConsiderHostActions is set, a host dependence is allowed.
369  Action *
370  getSingleDeviceDependence(bool DoNotConsiderHostActions = false) const;
371 
372  static bool classof(const Action *A) { return A->getKind() == OffloadClass; }
373 };
374 
375 class JobAction : public Action {
376  virtual void anchor();
377 
378 protected:
380  JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
381 
382 public:
383  static bool classof(const Action *A) {
384  return (A->getKind() >= JobClassFirst &&
385  A->getKind() <= JobClassLast);
386  }
387 };
388 
390  void anchor() override;
391 
392 public:
393  PreprocessJobAction(Action *Input, types::ID OutputType);
394 
395  static bool classof(const Action *A) {
396  return A->getKind() == PreprocessJobClass;
397  }
398 };
399 
401  void anchor() override;
402 
403 protected:
404  PrecompileJobAction(ActionClass Kind, Action *Input, types::ID OutputType);
405 
406 public:
407  PrecompileJobAction(Action *Input, types::ID OutputType);
408 
409  static bool classof(const Action *A) {
410  return A->getKind() == PrecompileJobClass ||
411  A->getKind() == HeaderModulePrecompileJobClass;
412  }
413 };
414 
416  void anchor() override;
417 
418  const char *ModuleName;
419 
420 public:
422  const char *ModuleName);
423 
424  static bool classof(const Action *A) {
425  return A->getKind() == HeaderModulePrecompileJobClass;
426  }
427 
429  getInputs().push_back(Input);
430  }
431 
432  const char *getModuleName() const { return ModuleName; }
433 };
434 
435 class AnalyzeJobAction : public JobAction {
436  void anchor() override;
437 
438 public:
439  AnalyzeJobAction(Action *Input, types::ID OutputType);
440 
441  static bool classof(const Action *A) {
442  return A->getKind() == AnalyzeJobClass;
443  }
444 };
445 
446 class MigrateJobAction : public JobAction {
447  void anchor() override;
448 
449 public:
450  MigrateJobAction(Action *Input, types::ID OutputType);
451 
452  static bool classof(const Action *A) {
453  return A->getKind() == MigrateJobClass;
454  }
455 };
456 
457 class CompileJobAction : public JobAction {
458  void anchor() override;
459 
460 public:
461  CompileJobAction(Action *Input, types::ID OutputType);
462 
463  static bool classof(const Action *A) {
464  return A->getKind() == CompileJobClass;
465  }
466 };
467 
468 class BackendJobAction : public JobAction {
469  void anchor() override;
470 
471 public:
472  BackendJobAction(Action *Input, types::ID OutputType);
473 
474  static bool classof(const Action *A) {
475  return A->getKind() == BackendJobClass;
476  }
477 };
478 
479 class AssembleJobAction : public JobAction {
480  void anchor() override;
481 
482 public:
483  AssembleJobAction(Action *Input, types::ID OutputType);
484 
485  static bool classof(const Action *A) {
486  return A->getKind() == AssembleJobClass;
487  }
488 };
489 
490 class IfsMergeJobAction : public JobAction {
491  void anchor() override;
492 
493 public:
495 
496  static bool classof(const Action *A) {
497  return A->getKind() == IfsMergeJobClass;
498  }
499 };
500 
501 class LinkJobAction : public JobAction {
502  void anchor() override;
503 
504 public:
506 
507  static bool classof(const Action *A) {
508  return A->getKind() == LinkJobClass;
509  }
510 };
511 
512 class LipoJobAction : public JobAction {
513  void anchor() override;
514 
515 public:
517 
518  static bool classof(const Action *A) {
519  return A->getKind() == LipoJobClass;
520  }
521 };
522 
523 class DsymutilJobAction : public JobAction {
524  void anchor() override;
525 
526 public:
528 
529  static bool classof(const Action *A) {
530  return A->getKind() == DsymutilJobClass;
531  }
532 };
533 
534 class VerifyJobAction : public JobAction {
535  void anchor() override;
536 
537 public:
539 
540  static bool classof(const Action *A) {
541  return A->getKind() == VerifyDebugInfoJobClass ||
542  A->getKind() == VerifyPCHJobClass;
543  }
544 };
545 
547  void anchor() override;
548 
549 public:
551 
552  static bool classof(const Action *A) {
553  return A->getKind() == VerifyDebugInfoJobClass;
554  }
555 };
556 
558  void anchor() override;
559 
560 public:
562 
563  static bool classof(const Action *A) {
564  return A->getKind() == VerifyPCHJobClass;
565  }
566 };
567 
569  void anchor() override;
570 
571 public:
572  // Offloading bundling doesn't change the type of output.
574 
575  static bool classof(const Action *A) {
576  return A->getKind() == OffloadBundlingJobClass;
577  }
578 };
579 
580 class OffloadUnbundlingJobAction final : public JobAction {
581  void anchor() override;
582 
583 public:
584  /// Type that provides information about the actions that depend on this
585  /// unbundling action.
586  struct DependentActionInfo final {
587  /// The tool chain of the dependent action.
588  const ToolChain *DependentToolChain = nullptr;
589 
590  /// The bound architecture of the dependent action.
592 
593  /// The offload kind of the dependent action.
594  const OffloadKind DependentOffloadKind = OFK_None;
595 
596  DependentActionInfo(const ToolChain *DependentToolChain,
597  StringRef DependentBoundArch,
598  const OffloadKind DependentOffloadKind)
599  : DependentToolChain(DependentToolChain),
600  DependentBoundArch(DependentBoundArch),
601  DependentOffloadKind(DependentOffloadKind) {}
602  };
603 
604 private:
605  /// Container that keeps information about each dependence of this unbundling
606  /// action.
607  SmallVector<DependentActionInfo, 6> DependentActionInfoArray;
608 
609 public:
610  // Offloading unbundling doesn't change the type of output.
612 
613  /// Register information about a dependent action.
614  void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch,
615  OffloadKind Kind) {
616  DependentActionInfoArray.push_back({TC, BoundArch, Kind});
617  }
618 
619  /// Return the information about all depending actions.
621  return DependentActionInfoArray;
622  }
623 
624  static bool classof(const Action *A) {
625  return A->getKind() == OffloadUnbundlingJobClass;
626  }
627 };
628 
630  void anchor() override;
631 
632 public:
634 
635  static bool classof(const Action *A) {
636  return A->getKind() == OffloadWrapperJobClass;
637  }
638 };
639 
640 } // namespace driver
641 } // namespace clang
642 
643 #endif // LLVM_CLANG_DRIVER_ACTION_H
Type that provides information about the actions that depend on this unbundling action.
Definition: Action.h:586
static bool classof(const Action *A)
Definition: Action.h:395
Action(ActionClass Kind, Action *Input, types::ID Type)
Definition: Action.h:129
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
Definition: Action.h:164
const OffloadKindList & getOffloadKinds() const
Definition: Action.h:289
ActionList::size_type size_type
Definition: Action.h:49
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
Definition: Dominators.h:30
static bool classof(const Action *A)
Definition: Action.h:496
static bool classof(const Action *A)
Definition: Action.h:224
DependentActionInfo(const ToolChain *DependentToolChain, StringRef DependentBoundArch, const OffloadKind DependentOffloadKind)
Definition: Action.h:596
The base class of the type hierarchy.
Definition: Type.h:1436
input_range inputs()
Definition: Action.h:151
static bool classof(const Action *A)
Definition: Action.h:463
bool isHostOffloading(OffloadKind OKind) const
Check if this action have any offload kinds.
Definition: Action.h:203
Action(ActionClass Kind, types::ID Type)
Definition: Action.h:128
Type used to communicate device actions.
Definition: Action.h:255
const char * getClassName() const
Definition: Action.h:139
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Definition: Action.h:614
StringRef DependentBoundArch
The bound architecture of the dependent action.
Definition: Action.h:591
const llvm::opt::Arg & getInputArg() const
Definition: Action.h:222
llvm::iterator_range< input_const_iterator > input_const_range
Definition: Action.h:53
ActionList & getInputs()
Definition: Action.h:144
static bool classof(const Action *A)
Definition: Action.h:529
Type used to communicate host actions.
Definition: Action.h:296
const ToolChain * getToolChain() const
Definition: Action.h:320
bool isOffloading(OffloadKind OKind) const
Definition: Action.h:209
Action - Represent an abstract compilation step to perform.
Definition: Action.h:47
static bool classof(const Action *A)
Definition: Action.h:383
input_const_iterator input_begin() const
Definition: Action.h:152
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
types::ID getType() const
Definition: Action.h:142
static bool classof(const Action *A)
Definition: Action.h:507
bool isDeviceOffloading(OffloadKind OKind) const
Definition: Action.h:206
OffloadKind getOffloadingDeviceKind() const
Definition: Action.h:198
llvm::iterator_range< input_iterator > input_range
Definition: Action.h:52
static bool classof(const Action *A)
Definition: Action.h:552
input_iterator input_begin()
Definition: Action.h:149
input_iterator input_end()
Definition: Action.h:150
const ToolChainList & getToolChains() const
Definition: Action.h:287
static bool classof(const Action *A)
Definition: Action.h:624
static bool classof(const Action *A)
Definition: Action.h:409
ActionList::const_iterator input_const_iterator
Definition: Action.h:51
ActionClass getKind() const
Definition: Action.h:141
const ActionList & getInputs() const
Definition: Action.h:145
static bool classof(const Action *A)
Definition: Action.h:474
static bool classof(const Action *A)
Definition: Action.h:563
const BoundArchList & getBoundArchs() const
Definition: Action.h:288
input_const_iterator input_end() const
Definition: Action.h:153
static bool classof(const Action *A)
Definition: Action.h:635
size_type size() const
Definition: Action.h:147
static bool classof(const Action *A)
Definition: Action.h:372
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
Definition: Action.h:159
const ActionList & getActions() const
Get each of the individual arrays.
Definition: Action.h:286
HostDependence(Action &A, const ToolChain &TC, const char *BoundArch, const unsigned OffloadKinds)
Definition: Action.h:310
Action(ActionClass Kind, Action *Input)
Definition: Action.h:131
Kind
ArrayRef< DependentActionInfo > getDependentActionsInfo() const
Return the information about all depending actions.
Definition: Action.h:620
static bool classof(const Action *A)
Definition: Action.h:485
static bool classof(const Action *A)
Definition: Action.h:424
An offload action combines host or/and device actions according to the programming model implementati...
Definition: Action.h:249
input_const_range inputs() const
Definition: Action.h:154
static bool classof(const Action *A)
Definition: Action.h:518
unsigned getOffloadingHostActiveKinds() const
Definition: Action.h:194
Dataflow Directional Tag Classes.
llvm::function_ref< void(Action *, const ToolChain *, const char *)> OffloadActionWorkTy
Definition: Action.h:326
Action(ActionClass Kind, const ActionList &Inputs, types::ID Type)
Definition: Action.h:133
ActionList::iterator input_iterator
Definition: Action.h:50
static bool classof(const Action *A)
Definition: Action.h:441
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:945
static bool classof(const Action *A)
Definition: Action.h:452
static bool classof(const Action *A)
Definition: Action.h:241
static bool classof(const Action *A)
Definition: Action.h:540
const char * getOffloadingArch() const
Definition: Action.h:199
StringRef getArchName() const
Definition: Action.h:239
static bool classof(const Action *A)
Definition: Action.h:575
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:88