Coverage Report

Created: 2018-11-16 02:38

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