Coverage Report

Created: 2019-07-24 05:18

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