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