blob: 0eb4c7257e7a8a88a47075c97950dfa03288fd00 [file] [log] [blame]
Eugene Zelenko5e4511c2018-03-20 21:08:59 +00001//===- Action.cpp - Abstract compilation steps ----------------------------===//
Daniel Dunbarf479c122009-03-12 18:40:18 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Daniel Dunbarf479c122009-03-12 18:40:18 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "clang/Driver/Action.h"
David Blaikie79000202011-09-23 05:57:42 +000010#include "llvm/Support/ErrorHandling.h"
Daniel Dunbarf479c122009-03-12 18:40:18 +000011#include <cassert>
Eugene Zelenko5e4511c2018-03-20 21:08:59 +000012#include <string>
13
14using namespace clang;
15using namespace driver;
Reid Kleckner898229a2013-06-14 17:17:23 +000016using namespace llvm::opt;
Daniel Dunbarf479c122009-03-12 18:40:18 +000017
Eugene Zelenko5e4511c2018-03-20 21:08:59 +000018Action::~Action() = default;
Daniel Dunbar80665fb2009-03-13 12:17:08 +000019
20const char *Action::getClassName(ActionClass AC) {
21 switch (AC) {
22 case InputClass: return "input";
23 case BindArchClass: return "bind-arch";
Samuel Antaod06239d2016-07-15 23:13:27 +000024 case OffloadClass:
25 return "offload";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000026 case PreprocessJobClass: return "preprocessor";
27 case PrecompileJobClass: return "precompiler";
Richard Smithcd35eff2018-09-15 01:21:16 +000028 case HeaderModulePrecompileJobClass: return "header-module-precompiler";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000029 case AnalyzeJobClass: return "analyzer";
Ted Kremenekf7639e12012-03-06 20:06:33 +000030 case MigrateJobClass: return "migrator";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000031 case CompileJobClass: return "compiler";
Bob Wilson23a55f12014-12-21 07:00:00 +000032 case BackendJobClass: return "backend";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000033 case AssembleJobClass: return "assembler";
Puyan Lotfic382d032019-10-08 15:23:14 +000034 case IfsMergeJobClass: return "interface-stub-merger";
Daniel Dunbar7326ad52009-03-13 17:52:07 +000035 case LinkJobClass: return "linker";
Daniel Dunbar80665fb2009-03-13 12:17:08 +000036 case LipoJobClass: return "lipo";
Daniel Dunbar88299622010-06-04 18:28:36 +000037 case DsymutilJobClass: return "dsymutil";
Ben Langmuir9b9a8d32014-02-06 18:53:25 +000038 case VerifyDebugInfoJobClass: return "verify-debug-info";
39 case VerifyPCHJobClass: return "verify-pch";
Samuel Antao69d6f312016-10-27 17:50:43 +000040 case OffloadBundlingJobClass:
41 return "clang-offload-bundler";
Samuel Antaofab4f372016-10-27 18:00:51 +000042 case OffloadUnbundlingJobClass:
43 return "clang-offload-unbundler";
Sergey Dmitrieva0d83762019-10-09 20:42:58 +000044 case OffloadWrapperJobClass:
45 return "clang-offload-wrapper";
Daniel Dunbar80665fb2009-03-13 12:17:08 +000046 }
Mike Stump11289f42009-09-09 15:08:12 +000047
David Blaikie83d382b2011-09-23 05:06:16 +000048 llvm_unreachable("invalid class");
Daniel Dunbar80665fb2009-03-13 12:17:08 +000049}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +000050
Samuel Antaod06239d2016-07-15 23:13:27 +000051void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch) {
52 // Offload action set its own kinds on their dependences.
53 if (Kind == OffloadClass)
54 return;
Samuel Antaofab4f372016-10-27 18:00:51 +000055 // Unbundling actions use the host kinds.
56 if (Kind == OffloadUnbundlingJobClass)
57 return;
Samuel Antaod06239d2016-07-15 23:13:27 +000058
59 assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
60 "Setting device kind to a different device??");
61 assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??");
62 OffloadingDeviceKind = OKind;
63 OffloadingArch = OArch;
64
65 for (auto *A : Inputs)
66 A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch);
67}
68
69void Action::propagateHostOffloadInfo(unsigned OKinds, const char *OArch) {
70 // Offload action set its own kinds on their dependences.
71 if (Kind == OffloadClass)
72 return;
73
74 assert(OffloadingDeviceKind == OFK_None &&
75 "Setting a host kind in a device action.");
76 ActiveOffloadKindMask |= OKinds;
77 OffloadingArch = OArch;
78
79 for (auto *A : Inputs)
80 A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch);
81}
82
83void Action::propagateOffloadInfo(const Action *A) {
84 if (unsigned HK = A->getOffloadingHostActiveKinds())
85 propagateHostOffloadInfo(HK, A->getOffloadingArch());
86 else
87 propagateDeviceOffloadInfo(A->getOffloadingDeviceKind(),
88 A->getOffloadingArch());
89}
90
91std::string Action::getOffloadingKindPrefix() const {
92 switch (OffloadingDeviceKind) {
93 case OFK_None:
94 break;
95 case OFK_Host:
96 llvm_unreachable("Host kind is not an offloading device kind.");
97 break;
98 case OFK_Cuda:
99 return "device-cuda";
Samuel Antao39f9da22016-10-27 16:38:05 +0000100 case OFK_OpenMP:
101 return "device-openmp";
Yaxun Liu398612b2018-05-08 21:02:12 +0000102 case OFK_HIP:
103 return "device-hip";
Samuel Antaod06239d2016-07-15 23:13:27 +0000104
105 // TODO: Add other programming models here.
106 }
107
108 if (!ActiveOffloadKindMask)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000109 return {};
Samuel Antaod06239d2016-07-15 23:13:27 +0000110
111 std::string Res("host");
Yaxun Liu398612b2018-05-08 21:02:12 +0000112 assert(!((ActiveOffloadKindMask & OFK_Cuda) &&
113 (ActiveOffloadKindMask & OFK_HIP)) &&
114 "Cannot offload CUDA and HIP at the same time");
Samuel Antaod06239d2016-07-15 23:13:27 +0000115 if (ActiveOffloadKindMask & OFK_Cuda)
116 Res += "-cuda";
Yaxun Liu398612b2018-05-08 21:02:12 +0000117 if (ActiveOffloadKindMask & OFK_HIP)
118 Res += "-hip";
Samuel Antao39f9da22016-10-27 16:38:05 +0000119 if (ActiveOffloadKindMask & OFK_OpenMP)
120 Res += "-openmp";
Samuel Antaod06239d2016-07-15 23:13:27 +0000121
122 // TODO: Add other programming models here.
123
124 return Res;
125}
126
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000127/// Return a string that can be used as prefix in order to generate unique files
128/// for each offloading kind.
Samuel Antaod06239d2016-07-15 23:13:27 +0000129std::string
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000130Action::GetOffloadingFileNamePrefix(OffloadKind Kind,
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000131 StringRef NormalizedTriple,
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000132 bool CreatePrefixForHost) {
133 // Don't generate prefix for host actions unless required.
134 if (!CreatePrefixForHost && (Kind == OFK_None || Kind == OFK_Host))
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000135 return {};
Samuel Antaod06239d2016-07-15 23:13:27 +0000136
137 std::string Res("-");
Samuel Antao3b7e38b2016-10-27 18:14:55 +0000138 Res += GetOffloadKindName(Kind);
Samuel Antaod06239d2016-07-15 23:13:27 +0000139 Res += "-";
140 Res += NormalizedTriple;
141 return Res;
142}
143
Samuel Antao7cab8f12016-10-27 18:04:42 +0000144/// Return a string with the offload kind name. If that is not defined, we
145/// assume 'host'.
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000146StringRef Action::GetOffloadKindName(OffloadKind Kind) {
Samuel Antao7cab8f12016-10-27 18:04:42 +0000147 switch (Kind) {
148 case OFK_None:
149 case OFK_Host:
150 return "host";
151 case OFK_Cuda:
152 return "cuda";
153 case OFK_OpenMP:
154 return "openmp";
Yaxun Liu398612b2018-05-08 21:02:12 +0000155 case OFK_HIP:
156 return "hip";
Samuel Antao7cab8f12016-10-27 18:04:42 +0000157
158 // TODO: Add other programming models here.
159 }
Simon Pilgrim3315a6a2016-10-28 10:09:35 +0000160
161 llvm_unreachable("invalid offload kind");
Samuel Antao7cab8f12016-10-27 18:04:42 +0000162}
163
David Blaikie68e081d2011-12-20 02:48:34 +0000164void InputAction::anchor() {}
165
Mike Stump11289f42009-09-09 15:08:12 +0000166InputAction::InputAction(const Arg &_Input, types::ID _Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000167 : Action(InputClass, _Type), Input(_Input) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000168
David Blaikie68e081d2011-12-20 02:48:34 +0000169void BindArchAction::anchor() {}
170
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000171BindArchAction::BindArchAction(Action *Input, StringRef ArchName)
Mehdi Amini087f1fb2016-10-07 22:03:03 +0000172 : Action(BindArchClass, Input), ArchName(ArchName) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000173
Samuel Antaod06239d2016-07-15 23:13:27 +0000174void OffloadAction::anchor() {}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000175
Samuel Antaod06239d2016-07-15 23:13:27 +0000176OffloadAction::OffloadAction(const HostDependence &HDep)
177 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) {
178 OffloadingArch = HDep.getBoundArch();
179 ActiveOffloadKindMask = HDep.getOffloadKinds();
180 HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
181 HDep.getBoundArch());
Eric Christopher2a7248f2016-07-16 00:58:34 +0000182}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000183
Samuel Antaod06239d2016-07-15 23:13:27 +0000184OffloadAction::OffloadAction(const DeviceDependences &DDeps, types::ID Ty)
185 : Action(OffloadClass, DDeps.getActions(), Ty),
186 DevToolChains(DDeps.getToolChains()) {
187 auto &OKinds = DDeps.getOffloadKinds();
188 auto &BArchs = DDeps.getBoundArchs();
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000189
Samuel Antaod06239d2016-07-15 23:13:27 +0000190 // If all inputs agree on the same kind, use it also for this action.
191 if (llvm::all_of(OKinds, [&](OffloadKind K) { return K == OKinds.front(); }))
192 OffloadingDeviceKind = OKinds.front();
193
194 // If we have a single dependency, inherit the architecture from it.
195 if (OKinds.size() == 1)
196 OffloadingArch = BArchs.front();
197
198 // Propagate info to the dependencies.
199 for (unsigned i = 0, e = getInputs().size(); i != e; ++i)
200 getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]);
201}
202
203OffloadAction::OffloadAction(const HostDependence &HDep,
204 const DeviceDependences &DDeps)
205 : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()),
206 DevToolChains(DDeps.getToolChains()) {
207 // We use the kinds of the host dependence for this action.
208 OffloadingArch = HDep.getBoundArch();
209 ActiveOffloadKindMask = HDep.getOffloadKinds();
210 HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(),
211 HDep.getBoundArch());
212
213 // Add device inputs and propagate info to the device actions. Do work only if
214 // we have dependencies.
215 for (unsigned i = 0, e = DDeps.getActions().size(); i != e; ++i)
216 if (auto *A = DDeps.getActions()[i]) {
217 getInputs().push_back(A);
218 A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i],
219 DDeps.getBoundArchs()[i]);
220 }
221}
222
223void OffloadAction::doOnHostDependence(const OffloadActionWorkTy &Work) const {
224 if (!HostTC)
225 return;
226 assert(!getInputs().empty() && "No dependencies for offload action??");
227 auto *A = getInputs().front();
228 Work(A, HostTC, A->getOffloadingArch());
229}
230
231void OffloadAction::doOnEachDeviceDependence(
232 const OffloadActionWorkTy &Work) const {
233 auto I = getInputs().begin();
234 auto E = getInputs().end();
235 if (I == E)
236 return;
237
238 // We expect to have the same number of input dependences and device tool
239 // chains, except if we also have a host dependence. In that case we have one
240 // more dependence than we have device tool chains.
241 assert(getInputs().size() == DevToolChains.size() + (HostTC ? 1 : 0) &&
242 "Sizes of action dependences and toolchains are not consistent!");
243
244 // Skip host action
245 if (HostTC)
246 ++I;
247
248 auto TI = DevToolChains.begin();
249 for (; I != E; ++I, ++TI)
250 Work(*I, *TI, (*I)->getOffloadingArch());
251}
252
253void OffloadAction::doOnEachDependence(const OffloadActionWorkTy &Work) const {
254 doOnHostDependence(Work);
255 doOnEachDeviceDependence(Work);
256}
257
258void OffloadAction::doOnEachDependence(bool IsHostDependence,
259 const OffloadActionWorkTy &Work) const {
260 if (IsHostDependence)
261 doOnHostDependence(Work);
262 else
263 doOnEachDeviceDependence(Work);
264}
265
266bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; }
267
268Action *OffloadAction::getHostDependence() const {
269 assert(hasHostDependence() && "Host dependence does not exist!");
270 assert(!getInputs().empty() && "No dependencies for offload action??");
271 return HostTC ? getInputs().front() : nullptr;
272}
273
274bool OffloadAction::hasSingleDeviceDependence(
275 bool DoNotConsiderHostActions) const {
276 if (DoNotConsiderHostActions)
277 return getInputs().size() == (HostTC ? 2 : 1);
278 return !HostTC && getInputs().size() == 1;
279}
280
281Action *
282OffloadAction::getSingleDeviceDependence(bool DoNotConsiderHostActions) const {
283 assert(hasSingleDeviceDependence(DoNotConsiderHostActions) &&
284 "Single device dependence does not exist!");
285 // The previous assert ensures the number of entries in getInputs() is
286 // consistent with what we are doing here.
287 return HostTC ? getInputs()[1] : getInputs().front();
288}
289
290void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC,
291 const char *BoundArch,
292 OffloadKind OKind) {
293 DeviceActions.push_back(&A);
294 DeviceToolChains.push_back(&TC);
295 DeviceBoundArchs.push_back(BoundArch);
296 DeviceOffloadKinds.push_back(OKind);
297}
298
299OffloadAction::HostDependence::HostDependence(Action &A, const ToolChain &TC,
300 const char *BoundArch,
301 const DeviceDependences &DDeps)
302 : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) {
303 for (auto K : DDeps.getOffloadKinds())
304 HostOffloadKinds |= K;
305}
Artem Belevich0ff05cd2015-07-13 23:27:56 +0000306
David Blaikie68e081d2011-12-20 02:48:34 +0000307void JobAction::anchor() {}
308
Justin Lebar41094612016-01-11 23:07:27 +0000309JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type)
310 : Action(Kind, Input, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000311
Mike Stump11289f42009-09-09 15:08:12 +0000312JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000313 : Action(Kind, Inputs, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000314
David Blaikie68e081d2011-12-20 02:48:34 +0000315void PreprocessJobAction::anchor() {}
316
Justin Lebar41094612016-01-11 23:07:27 +0000317PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType)
318 : JobAction(PreprocessJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000319
David Blaikie68e081d2011-12-20 02:48:34 +0000320void PrecompileJobAction::anchor() {}
321
Justin Lebar41094612016-01-11 23:07:27 +0000322PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType)
323 : JobAction(PrecompileJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000324
Richard Smithcd35eff2018-09-15 01:21:16 +0000325PrecompileJobAction::PrecompileJobAction(ActionClass Kind, Action *Input,
326 types::ID OutputType)
327 : JobAction(Kind, Input, OutputType) {
328 assert(isa<PrecompileJobAction>((Action*)this) && "invalid action kind");
329}
330
331void HeaderModulePrecompileJobAction::anchor() {}
332
333HeaderModulePrecompileJobAction::HeaderModulePrecompileJobAction(
334 Action *Input, types::ID OutputType, const char *ModuleName)
335 : PrecompileJobAction(HeaderModulePrecompileJobClass, Input, OutputType),
336 ModuleName(ModuleName) {}
337
David Blaikie68e081d2011-12-20 02:48:34 +0000338void AnalyzeJobAction::anchor() {}
339
Justin Lebar41094612016-01-11 23:07:27 +0000340AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
341 : JobAction(AnalyzeJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000342
Ted Kremenekf7639e12012-03-06 20:06:33 +0000343void MigrateJobAction::anchor() {}
344
Justin Lebar41094612016-01-11 23:07:27 +0000345MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
346 : JobAction(MigrateJobClass, Input, OutputType) {}
Ted Kremenekf7639e12012-03-06 20:06:33 +0000347
David Blaikie68e081d2011-12-20 02:48:34 +0000348void CompileJobAction::anchor() {}
349
Justin Lebar41094612016-01-11 23:07:27 +0000350CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
351 : JobAction(CompileJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000352
Bob Wilson23a55f12014-12-21 07:00:00 +0000353void BackendJobAction::anchor() {}
354
Justin Lebar41094612016-01-11 23:07:27 +0000355BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType)
356 : JobAction(BackendJobClass, Input, OutputType) {}
Bob Wilson23a55f12014-12-21 07:00:00 +0000357
David Blaikie68e081d2011-12-20 02:48:34 +0000358void AssembleJobAction::anchor() {}
359
Justin Lebar41094612016-01-11 23:07:27 +0000360AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
361 : JobAction(AssembleJobClass, Input, OutputType) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000362
Puyan Lotfic382d032019-10-08 15:23:14 +0000363void IfsMergeJobAction::anchor() {}
364
365IfsMergeJobAction::IfsMergeJobAction(ActionList &Inputs, types::ID Type)
366 : JobAction(IfsMergeJobClass, Inputs, Type) {}
367
David Blaikie68e081d2011-12-20 02:48:34 +0000368void LinkJobAction::anchor() {}
369
Mike Stump11289f42009-09-09 15:08:12 +0000370LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000371 : JobAction(LinkJobClass, Inputs, Type) {}
Daniel Dunbar3f261ff2009-03-13 23:08:03 +0000372
David Blaikie68e081d2011-12-20 02:48:34 +0000373void LipoJobAction::anchor() {}
374
Mike Stump11289f42009-09-09 15:08:12 +0000375LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000376 : JobAction(LipoJobClass, Inputs, Type) {}
Daniel Dunbar88299622010-06-04 18:28:36 +0000377
David Blaikie68e081d2011-12-20 02:48:34 +0000378void DsymutilJobAction::anchor() {}
379
Daniel Dunbar88299622010-06-04 18:28:36 +0000380DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
Eugene Zelenko5e4511c2018-03-20 21:08:59 +0000381 : JobAction(DsymutilJobClass, Inputs, Type) {}
Eric Christopher551ef452011-08-23 17:56:55 +0000382
David Blaikie68e081d2011-12-20 02:48:34 +0000383void VerifyJobAction::anchor() {}
384
Justin Lebar41094612016-01-11 23:07:27 +0000385VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
386 types::ID Type)
387 : JobAction(Kind, Input, Type) {
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000388 assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
389 "ActionClass is not a valid VerifyJobAction");
390}
391
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000392void VerifyDebugInfoJobAction::anchor() {}
393
Justin Lebar41094612016-01-11 23:07:27 +0000394VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
395 types::ID Type)
396 : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {}
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000397
398void VerifyPCHJobAction::anchor() {}
399
Justin Lebar41094612016-01-11 23:07:27 +0000400VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
401 : VerifyJobAction(VerifyPCHJobClass, Input, Type) {}
Samuel Antao69d6f312016-10-27 17:50:43 +0000402
403void OffloadBundlingJobAction::anchor() {}
404
405OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs)
Yaxun Liuac8ccd52018-08-28 21:09:09 +0000406 : JobAction(OffloadBundlingJobClass, Inputs, Inputs.back()->getType()) {}
Samuel Antaofab4f372016-10-27 18:00:51 +0000407
408void OffloadUnbundlingJobAction::anchor() {}
409
410OffloadUnbundlingJobAction::OffloadUnbundlingJobAction(Action *Input)
411 : JobAction(OffloadUnbundlingJobClass, Input, Input->getType()) {}
Sergey Dmitrieva0d83762019-10-09 20:42:58 +0000412
413void OffloadWrapperJobAction::anchor() {}
414
415OffloadWrapperJobAction::OffloadWrapperJobAction(ActionList &Inputs,
416 types::ID Type)
417 : JobAction(OffloadWrapperJobClass, Inputs, Type) {}