Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/Action.cpp
Line
Count
Source (jump to first uncovered line)
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
9
#include "clang/Driver/Action.h"
10
#include "llvm/Support/ErrorHandling.h"
11
#include <cassert>
12
#include <string>
13
14
using namespace clang;
15
using namespace driver;
16
using namespace llvm::opt;
17
18
127k
Action::~Action() = default;
19
20
659
const char *Action::getClassName(ActionClass AC) {
21
659
  switch (AC) {
22
115
  case InputClass: return "input";
23
24
  case BindArchClass: return "bind-arch";
24
80
  case OffloadClass:
25
80
    return "offload";
26
97
  case PreprocessJobClass: return "preprocessor";
27
1
  case PrecompileJobClass: return "precompiler";
28
0
  case HeaderModulePrecompileJobClass: return "header-module-precompiler";
29
1
  case AnalyzeJobClass: return "analyzer";
30
0
  case MigrateJobClass: return "migrator";
31
100
  case CompileJobClass: return "compiler";
32
92
  case BackendJobClass: return "backend";
33
74
  case AssembleJobClass: return "assembler";
34
0
  case IfsMergeJobClass: return "interface-stub-merger";
35
55
  case LinkJobClass: return "linker";
36
4
  case LipoJobClass: return "lipo";
37
2
  case DsymutilJobClass: return "dsymutil";
38
1
  case VerifyDebugInfoJobClass: return "verify-debug-info";
39
0
  case VerifyPCHJobClass: return "verify-pch";
40
5
  case OffloadBundlingJobClass:
41
5
    return "clang-offload-bundler";
42
2
  case OffloadUnbundlingJobClass:
43
2
    return "clang-offload-unbundler";
44
6
  case OffloadWrapperJobClass:
45
6
    return "clang-offload-wrapper";
46
0
  }
47
0
48
0
  llvm_unreachable("invalid class");
49
0
}
50
51
3.57k
void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch) {
52
3.57k
  // Offload action set its own kinds on their dependences.
53
3.57k
  if (Kind == OffloadClass)
54
507
    return;
55
3.06k
  // Unbundling actions use the host kinds.
56
3.06k
  if (Kind == OffloadUnbundlingJobClass)
57
26
    return;
58
3.04k
59
3.04k
  assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
60
3.04k
         "Setting device kind to a different device??");
61
3.04k
  assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??");
62
3.04k
  OffloadingDeviceKind = OKind;
63
3.04k
  OffloadingArch = OArch;
64
3.04k
65
3.04k
  for (auto *A : Inputs)
66
2.64k
    A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch);
67
3.04k
}
68
69
105k
void Action::propagateHostOffloadInfo(unsigned OKinds, const char *OArch) {
70
105k
  // Offload action set its own kinds on their dependences.
71
105k
  if (Kind == OffloadClass)
72
313
    return;
73
104k
74
104k
  assert(OffloadingDeviceKind == OFK_None &&
75
104k
         "Setting a host kind in a device action.");
76
104k
  ActiveOffloadKindMask |= OKinds;
77
104k
  OffloadingArch = OArch;
78
104k
79
104k
  for (auto *A : Inputs)
80
75.9k
    A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
81
104k
}
82
83
0
void Action::propagateOffloadInfo(const Action *A) {
84
0
  if (unsigned HK = A->getOffloadingHostActiveKinds())
85
0
    propagateHostOffloadInfo(HK, A->getOffloadingArch());
86
0
  else
87
0
    propagateDeviceOffloadInfo(A->getOffloadingDeviceKind(),
88
0
                               A->getOffloadingArch());
89
0
}
90
91
687
std::string Action::getOffloadingKindPrefix() const {
92
687
  switch (OffloadingDeviceKind) {
93
373
  case OFK_None:
94
373
    break;
95
0
  case OFK_Host:
96
0
    llvm_unreachable("Host kind is not an offloading device kind.");
97
0
    break;
98
118
  case OFK_Cuda:
99
118
    return "device-cuda";
100
110
  case OFK_OpenMP:
101
110
    return "device-openmp";
102
86
  case OFK_HIP:
103
86
    return "device-hip";
104
373
105
373
    // TODO: Add other programming models here.
106
373
  }
107
373
108
373
  if (!ActiveOffloadKindMask)
109
151
    return {};
110
222
111
222
  std::string Res("host");
112
222
  assert(!((ActiveOffloadKindMask & OFK_Cuda) &&
113
222
           (ActiveOffloadKindMask & OFK_HIP)) &&
114
222
         "Cannot offload CUDA and HIP at the same time");
115
222
  if (ActiveOffloadKindMask & OFK_Cuda)
116
75
    Res += "-cuda";
117
222
  if (ActiveOffloadKindMask & OFK_HIP)
118
68
    Res += "-hip";
119
222
  if (ActiveOffloadKindMask & OFK_OpenMP)
120
90
    Res += "-openmp";
121
222
122
222
  // TODO: Add other programming models here.
123
222
124
222
  return Res;
125
222
}
126
127
/// Return a string that can be used as prefix in order to generate unique files
128
/// for each offloading kind.
129
std::string
130
Action::GetOffloadingFileNamePrefix(OffloadKind Kind,
131
                                    StringRef NormalizedTriple,
132
22.6k
                                    bool CreatePrefixForHost) {
133
22.6k
  // Don't generate prefix for host actions unless required.
134
22.6k
  if (!CreatePrefixForHost && 
(22.1k
Kind == OFK_None22.1k
||
Kind == OFK_Host976
))
135
21.1k
    return {};
136
1.45k
137
1.45k
  std::string Res("-");
138
1.45k
  Res += GetOffloadKindName(Kind);
139
1.45k
  Res += "-";
140
1.45k
  Res += NormalizedTriple;
141
1.45k
  return Res;
142
1.45k
}
143
144
/// Return a string with the offload kind name. If that is not defined, we
145
/// assume 'host'.
146
87.1k
StringRef Action::GetOffloadKindName(OffloadKind Kind) {
147
87.1k
  switch (Kind) {
148
84.0k
  case OFK_None:
149
84.0k
  case OFK_Host:
150
84.0k
    return "host";
151
84.0k
  case OFK_Cuda:
152
2.11k
    return "cuda";
153
84.0k
  case OFK_OpenMP:
154
591
    return "openmp";
155
84.0k
  case OFK_HIP:
156
367
    return "hip";
157
0
158
0
    // TODO: Add other programming models here.
159
0
  }
160
0
161
0
  llvm_unreachable("invalid offload kind");
162
0
}
163
164
0
void InputAction::anchor() {}
165
166
InputAction::InputAction(const Arg &_Input, types::ID _Type)
167
30.8k
    : Action(InputClass, _Type), Input(_Input) {}
168
169
0
void BindArchAction::anchor() {}
170
171
BindArchAction::BindArchAction(Action *Input, StringRef ArchName)
172
19.7k
    : Action(BindArchClass, Input), ArchName(ArchName) {}
173
174
0
void OffloadAction::anchor() {}
175
176
OffloadAction::OffloadAction(const HostDependence &HDep)
177
0
    : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
178
0
  OffloadingArch = HDep.getBoundArch();
179
0
  ActiveOffloadKindMask = HDep.getOffloadKinds();
180
0
  HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
181
0
                                             HDep.getBoundArch());
182
0
}
183
184
OffloadAction::OffloadAction(const DeviceDependences &DDeps, types::ID Ty)
185
    : Action(OffloadClass, DDeps.getActions(), Ty),
186
636
      DevToolChains(DDeps.getToolChains()) {
187
636
  auto &OKinds = DDeps.getOffloadKinds();
188
636
  auto &BArchs = DDeps.getBoundArchs();
189
636
190
636
  // If all inputs agree on the same kind, use it also for this action.
191
636
  if (llvm::all_of(OKinds, [&](OffloadKind K) { return K == OKinds.front(); }))
192
636
    OffloadingDeviceKind = OKinds.front();
193
636
194
636
  // If we have a single dependency, inherit the architecture from it.
195
636
  if (OKinds.size() == 1)
196
636
    OffloadingArch = BArchs.front();
197
636
198
636
  // Propagate info to the dependencies.
199
1.27k
  for (unsigned i = 0, e = getInputs().size(); i != e; 
++i636
)
200
636
    getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]);
201
636
}
202
203
OffloadAction::OffloadAction(const HostDependence &HDep,
204
                             const DeviceDependences &DDeps)
205
    : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
206
293
      DevToolChains(DDeps.getToolChains()) {
207
293
  // We use the kinds of the host dependence for this action.
208
293
  OffloadingArch = HDep.getBoundArch();
209
293
  ActiveOffloadKindMask = HDep.getOffloadKinds();
210
293
  HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
211
293
                                             HDep.getBoundArch());
212
293
213
293
  // Add device inputs and propagate info to the device actions. Do work only if
214
293
  // we have dependencies.
215
590
  for (unsigned i = 0, e = DDeps.getActions().size(); i != e; 
++i297
)
216
297
    if (auto *A = DDeps.getActions()[i]) {
217
297
      getInputs().push_back(A);
218
297
      A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i],
219
297
                                    DDeps.getBoundArchs()[i]);
220
297
    }
221
293
}
222
223
204
void OffloadAction::doOnHostDependence(const OffloadActionWorkTy &Work) const {
224
204
  if (!HostTC)
225
109
    return;
226
95
  assert(!getInputs().empty() && "No dependencies for offload action??");
227
95
  auto *A = getInputs().front();
228
95
  Work(A, HostTC, A->getOffloadingArch());
229
95
}
230
231
void OffloadAction::doOnEachDeviceDependence(
232
917
    const OffloadActionWorkTy &Work) const {
233
917
  auto I = getInputs().begin();
234
917
  auto E = getInputs().end();
235
917
  if (I == E)
236
0
    return;
237
917
238
917
  // We expect to have the same number of input dependences and device tool
239
917
  // chains, except if we also have a host dependence. In that case we have one
240
917
  // more dependence than we have device tool chains.
241
917
  assert(getInputs().size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
242
917
         "Sizes of action dependences and toolchains are not consistent!");
243
917
244
917
  // Skip host action
245
917
  if (HostTC)
246
225
    ++I;
247
917
248
917
  auto TI = DevToolChains.begin();
249
1.83k
  for (; I != E; 
++I, ++TI921
)
250
921
    Work(*I, *TI, (*I)->getOffloadingArch());
251
917
}
252
253
136
void OffloadAction::doOnEachDependence(const OffloadActionWorkTy &Work) const {
254
136
  doOnHostDependence(Work);
255
136
  doOnEachDeviceDependence(Work);
256
136
}
257
258
void OffloadAction::doOnEachDependence(bool IsHostDependence,
259
266
                                       const OffloadActionWorkTy &Work) const {
260
266
  if (IsHostDependence)
261
68
    doOnHostDependence(Work);
262
198
  else
263
198
    doOnEachDeviceDependence(Work);
264
266
}
265
266
653
bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; }
267
268
279
Action *OffloadAction::getHostDependence() const {
269
279
  assert(hasHostDependence() && "Host dependence does not exist!");
270
279
  assert(!getInputs().empty() && "No dependencies for offload action??");
271
279
  return HostTC ? getInputs().front() : 
nullptr0
;
272
279
}
273
274
bool OffloadAction::hasSingleDeviceDependence(
275
1.01k
    bool DoNotConsiderHostActions) const {
276
1.01k
  if (DoNotConsiderHostActions)
277
407
    return getInputs().size() == (HostTC ? 
2359
:
148
);
278
612
  return !HostTC && 
getInputs().size() == 1583
;
279
612
}
280
281
Action *
282
212
OffloadAction::getSingleDeviceDependence(bool DoNotConsiderHostActions) const {
283
212
  assert(hasSingleDeviceDependence(DoNotConsiderHostActions) &&
284
212
         "Single device dependence does not exist!");
285
212
  // The previous assert ensures the number of entries in getInputs() is
286
212
  // consistent with what we are doing here.
287
212
  return HostTC ? 
getInputs()[1]188
:
getInputs().front()24
;
288
212
}
289
290
void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC,
291
                                           const char *BoundArch,
292
933
                                           OffloadKind OKind) {
293
933
  DeviceActions.push_back(&A);
294
933
  DeviceToolChains.push_back(&TC);
295
933
  DeviceBoundArchs.push_back(BoundArch);
296
933
  DeviceOffloadKinds.push_back(OKind);
297
933
}
298
299
OffloadAction::HostDependence::HostDependence(Action &A, const ToolChain &TC,
300
                                              const char *BoundArch,
301
                                              const DeviceDependences &DDeps)
302
203
    : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) {
303
203
  for (auto K : DDeps.getOffloadKinds())
304
203
    HostOffloadKinds |= K;
305
203
}
306
307
0
void JobAction::anchor() {}
308
309
JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
310
69.7k
    : Action(Kind, Input, Type) {}
311
312
JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
313
6.56k
    : Action(Kind, Inputs, Type) {}
314
315
0
void PreprocessJobAction::anchor() {}
316
317
PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
318
26.4k
    : JobAction(PreprocessJobClass, Input, OutputType) {}
319
320
0
void PrecompileJobAction::anchor() {}
321
322
PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
323
68
    : JobAction(PrecompileJobClass, Input, OutputType) {}
324
325
PrecompileJobAction::PrecompileJobAction(ActionClass Kind, Action *Input,
326
                                         types::ID OutputType)
327
3
    : JobAction(Kind, Input, OutputType) {
328
3
  assert(isa<PrecompileJobAction>((Action*)this) && "invalid action kind");
329
3
}
330
331
0
void HeaderModulePrecompileJobAction::anchor() {}
332
333
HeaderModulePrecompileJobAction::HeaderModulePrecompileJobAction(
334
    Action *Input, types::ID OutputType, const char *ModuleName)
335
    : PrecompileJobAction(HeaderModulePrecompileJobClass, Input, OutputType),
336
3
      ModuleName(ModuleName) {}
337
338
0
void AnalyzeJobAction::anchor() {}
339
340
AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
341
36
    : JobAction(AnalyzeJobClass, Input, OutputType) {}
342
343
0
void MigrateJobAction::anchor() {}
344
345
MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
346
0
    : JobAction(MigrateJobClass, Input, OutputType) {}
347
348
0
void CompileJobAction::anchor() {}
349
350
CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
351
22.5k
    : JobAction(CompileJobClass, Input, OutputType) {}
352
353
0
void BackendJobAction::anchor() {}
354
355
BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType)
356
10.8k
    : JobAction(BackendJobClass, Input, OutputType) {}
357
358
0
void AssembleJobAction::anchor() {}
359
360
AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
361
9.85k
    : JobAction(AssembleJobClass, Input, OutputType) {}
362
363
0
void IfsMergeJobAction::anchor() {}
364
365
IfsMergeJobAction::IfsMergeJobAction(ActionList &Inputs, types::ID Type)
366
20
    : JobAction(IfsMergeJobClass, Inputs, Type) {}
367
368
0
void LinkJobAction::anchor() {}
369
370
LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
371
6.35k
    : JobAction(LinkJobClass, Inputs, Type) {}
372
373
0
void LipoJobAction::anchor() {}
374
375
LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
376
14
    : JobAction(LipoJobClass, Inputs, Type) {}
377
378
0
void DsymutilJobAction::anchor() {}
379
380
DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
381
90
    : JobAction(DsymutilJobClass, Inputs, Type) {}
382
383
0
void VerifyJobAction::anchor() {}
384
385
VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
386
                                 types::ID Type)
387
5
    : JobAction(Kind, Input, Type) {
388
5
  assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
389
5
         "ActionClass is not a valid VerifyJobAction");
390
5
}
391
392
0
void VerifyDebugInfoJobAction::anchor() {}
393
394
VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
395
                                                   types::ID Type)
396
3
    : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {}
397
398
0
void VerifyPCHJobAction::anchor() {}
399
400
VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
401
2
    : VerifyJobAction(VerifyPCHJobClass, Input, Type) {}
402
403
0
void OffloadBundlingJobAction::anchor() {}
404
405
OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs)
406
22
    : JobAction(OffloadBundlingJobClass, Inputs, Inputs.back()->getType()) {}
407
408
0
void OffloadUnbundlingJobAction::anchor() {}
409
410
OffloadUnbundlingJobAction::OffloadUnbundlingJobAction(Action *Input)
411
20
    : JobAction(OffloadUnbundlingJobClass, Input, Input->getType()) {}
412
413
0
void OffloadWrapperJobAction::anchor() {}
414
415
OffloadWrapperJobAction::OffloadWrapperJobAction(ActionList &Inputs,
416
                                                 types::ID Type)
417
63
  : JobAction(OffloadWrapperJobClass, Inputs, Type) {}