File: | build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/include/llvm/ADT/Twine.h |
Warning: | line 272, column 11 Array access (from variable 'Str') results in a null pointer dereference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- Driver.cpp - Clang GCC Compatible Driver -------------------------===// | ||||
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/Driver.h" | ||||
10 | #include "ToolChains/AIX.h" | ||||
11 | #include "ToolChains/AMDGPU.h" | ||||
12 | #include "ToolChains/AMDGPUOpenMP.h" | ||||
13 | #include "ToolChains/AVR.h" | ||||
14 | #include "ToolChains/Ananas.h" | ||||
15 | #include "ToolChains/BareMetal.h" | ||||
16 | #include "ToolChains/CSKYToolChain.h" | ||||
17 | #include "ToolChains/Clang.h" | ||||
18 | #include "ToolChains/CloudABI.h" | ||||
19 | #include "ToolChains/Contiki.h" | ||||
20 | #include "ToolChains/CrossWindows.h" | ||||
21 | #include "ToolChains/Cuda.h" | ||||
22 | #include "ToolChains/Darwin.h" | ||||
23 | #include "ToolChains/DragonFly.h" | ||||
24 | #include "ToolChains/FreeBSD.h" | ||||
25 | #include "ToolChains/Fuchsia.h" | ||||
26 | #include "ToolChains/Gnu.h" | ||||
27 | #include "ToolChains/HIPAMD.h" | ||||
28 | #include "ToolChains/HIPSPV.h" | ||||
29 | #include "ToolChains/HLSL.h" | ||||
30 | #include "ToolChains/Haiku.h" | ||||
31 | #include "ToolChains/Hexagon.h" | ||||
32 | #include "ToolChains/Hurd.h" | ||||
33 | #include "ToolChains/Lanai.h" | ||||
34 | #include "ToolChains/Linux.h" | ||||
35 | #include "ToolChains/MSP430.h" | ||||
36 | #include "ToolChains/MSVC.h" | ||||
37 | #include "ToolChains/MinGW.h" | ||||
38 | #include "ToolChains/Minix.h" | ||||
39 | #include "ToolChains/MipsLinux.h" | ||||
40 | #include "ToolChains/Myriad.h" | ||||
41 | #include "ToolChains/NaCl.h" | ||||
42 | #include "ToolChains/NetBSD.h" | ||||
43 | #include "ToolChains/OpenBSD.h" | ||||
44 | #include "ToolChains/PPCFreeBSD.h" | ||||
45 | #include "ToolChains/PPCLinux.h" | ||||
46 | #include "ToolChains/PS4CPU.h" | ||||
47 | #include "ToolChains/RISCVToolchain.h" | ||||
48 | #include "ToolChains/SPIRV.h" | ||||
49 | #include "ToolChains/Solaris.h" | ||||
50 | #include "ToolChains/TCE.h" | ||||
51 | #include "ToolChains/VEToolchain.h" | ||||
52 | #include "ToolChains/WebAssembly.h" | ||||
53 | #include "ToolChains/XCore.h" | ||||
54 | #include "ToolChains/ZOS.h" | ||||
55 | #include "clang/Basic/TargetID.h" | ||||
56 | #include "clang/Basic/Version.h" | ||||
57 | #include "clang/Config/config.h" | ||||
58 | #include "clang/Driver/Action.h" | ||||
59 | #include "clang/Driver/Compilation.h" | ||||
60 | #include "clang/Driver/DriverDiagnostic.h" | ||||
61 | #include "clang/Driver/InputInfo.h" | ||||
62 | #include "clang/Driver/Job.h" | ||||
63 | #include "clang/Driver/Options.h" | ||||
64 | #include "clang/Driver/Phases.h" | ||||
65 | #include "clang/Driver/SanitizerArgs.h" | ||||
66 | #include "clang/Driver/Tool.h" | ||||
67 | #include "clang/Driver/ToolChain.h" | ||||
68 | #include "clang/Driver/Types.h" | ||||
69 | #include "llvm/ADT/ArrayRef.h" | ||||
70 | #include "llvm/ADT/STLExtras.h" | ||||
71 | #include "llvm/ADT/SmallSet.h" | ||||
72 | #include "llvm/ADT/StringExtras.h" | ||||
73 | #include "llvm/ADT/StringRef.h" | ||||
74 | #include "llvm/ADT/StringSet.h" | ||||
75 | #include "llvm/ADT/StringSwitch.h" | ||||
76 | #include "llvm/Config/llvm-config.h" | ||||
77 | #include "llvm/MC/TargetRegistry.h" | ||||
78 | #include "llvm/Option/Arg.h" | ||||
79 | #include "llvm/Option/ArgList.h" | ||||
80 | #include "llvm/Option/OptSpecifier.h" | ||||
81 | #include "llvm/Option/OptTable.h" | ||||
82 | #include "llvm/Option/Option.h" | ||||
83 | #include "llvm/Support/CommandLine.h" | ||||
84 | #include "llvm/Support/ErrorHandling.h" | ||||
85 | #include "llvm/Support/ExitCodes.h" | ||||
86 | #include "llvm/Support/FileSystem.h" | ||||
87 | #include "llvm/Support/FormatVariadic.h" | ||||
88 | #include "llvm/Support/Host.h" | ||||
89 | #include "llvm/Support/MD5.h" | ||||
90 | #include "llvm/Support/Path.h" | ||||
91 | #include "llvm/Support/PrettyStackTrace.h" | ||||
92 | #include "llvm/Support/Process.h" | ||||
93 | #include "llvm/Support/Program.h" | ||||
94 | #include "llvm/Support/StringSaver.h" | ||||
95 | #include "llvm/Support/VirtualFileSystem.h" | ||||
96 | #include "llvm/Support/raw_ostream.h" | ||||
97 | #include <map> | ||||
98 | #include <memory> | ||||
99 | #include <utility> | ||||
100 | #if LLVM_ON_UNIX1 | ||||
101 | #include <unistd.h> // getpid | ||||
102 | #endif | ||||
103 | |||||
104 | using namespace clang::driver; | ||||
105 | using namespace clang; | ||||
106 | using namespace llvm::opt; | ||||
107 | |||||
108 | static llvm::Optional<llvm::Triple> | ||||
109 | getOffloadTargetTriple(const Driver &D, const ArgList &Args) { | ||||
110 | auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ); | ||||
111 | // Offload compilation flow does not support multiple targets for now. We | ||||
112 | // need the HIPActionBuilder (and possibly the CudaActionBuilder{,Base}too) | ||||
113 | // to support multiple tool chains first. | ||||
114 | switch (OffloadTargets.size()) { | ||||
115 | default: | ||||
116 | D.Diag(diag::err_drv_only_one_offload_target_supported); | ||||
117 | return llvm::None; | ||||
118 | case 0: | ||||
119 | D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << ""; | ||||
120 | return llvm::None; | ||||
121 | case 1: | ||||
122 | break; | ||||
123 | } | ||||
124 | return llvm::Triple(OffloadTargets[0]); | ||||
125 | } | ||||
126 | |||||
127 | static llvm::Optional<llvm::Triple> | ||||
128 | getNVIDIAOffloadTargetTriple(const Driver &D, const ArgList &Args, | ||||
129 | const llvm::Triple &HostTriple) { | ||||
130 | if (!Args.hasArg(options::OPT_offload_EQ)) { | ||||
131 | return llvm::Triple(HostTriple.isArch64Bit() ? "nvptx64-nvidia-cuda" | ||||
132 | : "nvptx-nvidia-cuda"); | ||||
133 | } | ||||
134 | auto TT = getOffloadTargetTriple(D, Args); | ||||
135 | if (TT && (TT->getArch() == llvm::Triple::spirv32 || | ||||
136 | TT->getArch() == llvm::Triple::spirv64)) { | ||||
137 | if (Args.hasArg(options::OPT_emit_llvm)) | ||||
138 | return TT; | ||||
139 | D.Diag(diag::err_drv_cuda_offload_only_emit_bc); | ||||
140 | return llvm::None; | ||||
141 | } | ||||
142 | D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str(); | ||||
143 | return llvm::None; | ||||
144 | } | ||||
145 | static llvm::Optional<llvm::Triple> | ||||
146 | getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) { | ||||
147 | if (!Args.hasArg(options::OPT_offload_EQ)) { | ||||
148 | return llvm::Triple("amdgcn-amd-amdhsa"); // Default HIP triple. | ||||
149 | } | ||||
150 | auto TT = getOffloadTargetTriple(D, Args); | ||||
151 | if (!TT) | ||||
152 | return llvm::None; | ||||
153 | if (TT->getArch() == llvm::Triple::amdgcn && | ||||
154 | TT->getVendor() == llvm::Triple::AMD && | ||||
155 | TT->getOS() == llvm::Triple::AMDHSA) | ||||
156 | return TT; | ||||
157 | if (TT->getArch() == llvm::Triple::spirv64) | ||||
158 | return TT; | ||||
159 | D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str(); | ||||
160 | return llvm::None; | ||||
161 | } | ||||
162 | |||||
163 | // static | ||||
164 | std::string Driver::GetResourcesPath(StringRef BinaryPath, | ||||
165 | StringRef CustomResourceDir) { | ||||
166 | // Since the resource directory is embedded in the module hash, it's important | ||||
167 | // that all places that need it call this function, so that they get the | ||||
168 | // exact same string ("a/../b/" and "b/" get different hashes, for example). | ||||
169 | |||||
170 | // Dir is bin/ or lib/, depending on where BinaryPath is. | ||||
171 | std::string Dir = std::string(llvm::sys::path::parent_path(BinaryPath)); | ||||
172 | |||||
173 | SmallString<128> P(Dir); | ||||
174 | if (CustomResourceDir != "") { | ||||
175 | llvm::sys::path::append(P, CustomResourceDir); | ||||
176 | } else { | ||||
177 | // On Windows, libclang.dll is in bin/. | ||||
178 | // On non-Windows, libclang.so/.dylib is in lib/. | ||||
179 | // With a static-library build of libclang, LibClangPath will contain the | ||||
180 | // path of the embedding binary, which for LLVM binaries will be in bin/. | ||||
181 | // ../lib gets us to lib/ in both cases. | ||||
182 | P = llvm::sys::path::parent_path(Dir); | ||||
183 | llvm::sys::path::append(P, Twine("lib") + CLANG_LIBDIR_SUFFIX"", "clang", | ||||
184 | CLANG_VERSION_STRING"15.0.0"); | ||||
185 | } | ||||
186 | |||||
187 | return std::string(P.str()); | ||||
188 | } | ||||
189 | |||||
190 | Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, | ||||
191 | DiagnosticsEngine &Diags, std::string Title, | ||||
192 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) | ||||
193 | : Diags(Diags), VFS(std::move(VFS)), Mode(GCCMode), | ||||
194 | SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None), | ||||
195 | ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT""), | ||||
196 | DriverTitle(Title), CCCPrintBindings(false), CCPrintOptions(false), | ||||
197 | CCPrintHeaders(false), CCLogDiagnostics(false), CCGenDiagnostics(false), | ||||
198 | CCPrintProcessStats(false), TargetTriple(TargetTriple), Saver(Alloc), | ||||
199 | CheckInputsExist(true), GenReproducer(false), | ||||
200 | SuppressMissingInputWarning(false) { | ||||
201 | // Provide a sane fallback if no VFS is specified. | ||||
202 | if (!this->VFS) | ||||
203 | this->VFS = llvm::vfs::getRealFileSystem(); | ||||
204 | |||||
205 | Name = std::string(llvm::sys::path::filename(ClangExecutable)); | ||||
206 | Dir = std::string(llvm::sys::path::parent_path(ClangExecutable)); | ||||
207 | InstalledDir = Dir; // Provide a sensible default installed dir. | ||||
208 | |||||
209 | if ((!SysRoot.empty()) && llvm::sys::path::is_relative(SysRoot)) { | ||||
210 | // Prepend InstalledDir if SysRoot is relative | ||||
211 | SmallString<128> P(InstalledDir); | ||||
212 | llvm::sys::path::append(P, SysRoot); | ||||
213 | SysRoot = std::string(P); | ||||
214 | } | ||||
215 | |||||
216 | #if defined(CLANG_CONFIG_FILE_SYSTEM_DIR) | ||||
217 | SystemConfigDir = CLANG_CONFIG_FILE_SYSTEM_DIR; | ||||
218 | #endif | ||||
219 | #if defined(CLANG_CONFIG_FILE_USER_DIR) | ||||
220 | UserConfigDir = CLANG_CONFIG_FILE_USER_DIR; | ||||
221 | #endif | ||||
222 | |||||
223 | // Compute the path to the resource directory. | ||||
224 | ResourceDir = GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR""); | ||||
225 | } | ||||
226 | |||||
227 | void Driver::setDriverMode(StringRef Value) { | ||||
228 | static const std::string OptName = | ||||
229 | getOpts().getOption(options::OPT_driver_mode).getPrefixedName(); | ||||
230 | if (auto M = llvm::StringSwitch<llvm::Optional<DriverMode>>(Value) | ||||
231 | .Case("gcc", GCCMode) | ||||
232 | .Case("g++", GXXMode) | ||||
233 | .Case("cpp", CPPMode) | ||||
234 | .Case("cl", CLMode) | ||||
235 | .Case("flang", FlangMode) | ||||
236 | .Case("dxc", DXCMode) | ||||
237 | .Default(None)) | ||||
238 | Mode = *M; | ||||
239 | else | ||||
240 | Diag(diag::err_drv_unsupported_option_argument) << OptName << Value; | ||||
241 | } | ||||
242 | |||||
243 | InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings, | ||||
244 | bool IsClCompatMode, | ||||
245 | bool &ContainsError) { | ||||
246 | llvm::PrettyStackTraceString CrashInfo("Command line argument parsing"); | ||||
247 | ContainsError = false; | ||||
248 | |||||
249 | unsigned IncludedFlagsBitmask; | ||||
250 | unsigned ExcludedFlagsBitmask; | ||||
251 | std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) = | ||||
252 | getIncludeExcludeOptionFlagMasks(IsClCompatMode); | ||||
253 | |||||
254 | // Make sure that Flang-only options don't pollute the Clang output | ||||
255 | // TODO: Make sure that Clang-only options don't pollute Flang output | ||||
256 | if (!IsFlangMode()) | ||||
257 | ExcludedFlagsBitmask |= options::FlangOnlyOption; | ||||
258 | |||||
259 | unsigned MissingArgIndex, MissingArgCount; | ||||
260 | InputArgList Args = | ||||
261 | getOpts().ParseArgs(ArgStrings, MissingArgIndex, MissingArgCount, | ||||
262 | IncludedFlagsBitmask, ExcludedFlagsBitmask); | ||||
263 | |||||
264 | // Check for missing argument error. | ||||
265 | if (MissingArgCount) { | ||||
266 | Diag(diag::err_drv_missing_argument) | ||||
267 | << Args.getArgString(MissingArgIndex) << MissingArgCount; | ||||
268 | ContainsError |= | ||||
269 | Diags.getDiagnosticLevel(diag::err_drv_missing_argument, | ||||
270 | SourceLocation()) > DiagnosticsEngine::Warning; | ||||
271 | } | ||||
272 | |||||
273 | // Check for unsupported options. | ||||
274 | for (const Arg *A : Args) { | ||||
275 | if (A->getOption().hasFlag(options::Unsupported)) { | ||||
276 | unsigned DiagID; | ||||
277 | auto ArgString = A->getAsString(Args); | ||||
278 | std::string Nearest; | ||||
279 | if (getOpts().findNearest( | ||||
280 | ArgString, Nearest, IncludedFlagsBitmask, | ||||
281 | ExcludedFlagsBitmask | options::Unsupported) > 1) { | ||||
282 | DiagID = diag::err_drv_unsupported_opt; | ||||
283 | Diag(DiagID) << ArgString; | ||||
284 | } else { | ||||
285 | DiagID = diag::err_drv_unsupported_opt_with_suggestion; | ||||
286 | Diag(DiagID) << ArgString << Nearest; | ||||
287 | } | ||||
288 | ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) > | ||||
289 | DiagnosticsEngine::Warning; | ||||
290 | continue; | ||||
291 | } | ||||
292 | |||||
293 | // Warn about -mcpu= without an argument. | ||||
294 | if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue("")) { | ||||
295 | Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args); | ||||
296 | ContainsError |= Diags.getDiagnosticLevel( | ||||
297 | diag::warn_drv_empty_joined_argument, | ||||
298 | SourceLocation()) > DiagnosticsEngine::Warning; | ||||
299 | } | ||||
300 | } | ||||
301 | |||||
302 | for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) { | ||||
303 | unsigned DiagID; | ||||
304 | auto ArgString = A->getAsString(Args); | ||||
305 | std::string Nearest; | ||||
306 | if (getOpts().findNearest( | ||||
307 | ArgString, Nearest, IncludedFlagsBitmask, ExcludedFlagsBitmask) > 1) { | ||||
308 | DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl | ||||
309 | : diag::err_drv_unknown_argument; | ||||
310 | Diags.Report(DiagID) << ArgString; | ||||
311 | } else { | ||||
312 | DiagID = IsCLMode() | ||||
313 | ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion | ||||
314 | : diag::err_drv_unknown_argument_with_suggestion; | ||||
315 | Diags.Report(DiagID) << ArgString << Nearest; | ||||
316 | } | ||||
317 | ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) > | ||||
318 | DiagnosticsEngine::Warning; | ||||
319 | } | ||||
320 | |||||
321 | return Args; | ||||
322 | } | ||||
323 | |||||
324 | // Determine which compilation mode we are in. We look for options which | ||||
325 | // affect the phase, starting with the earliest phases, and record which | ||||
326 | // option we used to determine the final phase. | ||||
327 | phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, | ||||
328 | Arg **FinalPhaseArg) const { | ||||
329 | Arg *PhaseArg = nullptr; | ||||
330 | phases::ID FinalPhase; | ||||
331 | |||||
332 | // -{E,EP,P,M,MM} only run the preprocessor. | ||||
333 | if (CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) || | ||||
334 | (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) || | ||||
335 | (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) || | ||||
336 | (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) || | ||||
337 | CCGenDiagnostics) { | ||||
338 | FinalPhase = phases::Preprocess; | ||||
339 | |||||
340 | // --precompile only runs up to precompilation. | ||||
341 | } else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) || | ||||
342 | (PhaseArg = DAL.getLastArg(options::OPT_extract_api))) { | ||||
343 | FinalPhase = phases::Precompile; | ||||
344 | // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler. | ||||
345 | } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || | ||||
346 | (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || | ||||
347 | (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || | ||||
348 | (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || | ||||
349 | (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || | ||||
350 | (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) || | ||||
351 | (PhaseArg = DAL.getLastArg(options::OPT__migrate)) || | ||||
352 | (PhaseArg = DAL.getLastArg(options::OPT__analyze)) || | ||||
353 | (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) { | ||||
354 | FinalPhase = phases::Compile; | ||||
355 | |||||
356 | // -S only runs up to the backend. | ||||
357 | } else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) { | ||||
358 | FinalPhase = phases::Backend; | ||||
359 | |||||
360 | // -c compilation only runs up to the assembler. | ||||
361 | } else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) { | ||||
362 | FinalPhase = phases::Assemble; | ||||
363 | |||||
364 | } else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) { | ||||
365 | FinalPhase = phases::IfsMerge; | ||||
366 | |||||
367 | // Otherwise do everything. | ||||
368 | } else | ||||
369 | FinalPhase = phases::Link; | ||||
370 | |||||
371 | if (FinalPhaseArg) | ||||
372 | *FinalPhaseArg = PhaseArg; | ||||
373 | |||||
374 | return FinalPhase; | ||||
375 | } | ||||
376 | |||||
377 | static Arg *MakeInputArg(DerivedArgList &Args, const OptTable &Opts, | ||||
378 | StringRef Value, bool Claim = true) { | ||||
379 | Arg *A = new Arg(Opts.getOption(options::OPT_INPUT), Value, | ||||
380 | Args.getBaseArgs().MakeIndex(Value), Value.data()); | ||||
381 | Args.AddSynthesizedArg(A); | ||||
382 | if (Claim) | ||||
383 | A->claim(); | ||||
384 | return A; | ||||
385 | } | ||||
386 | |||||
387 | DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { | ||||
388 | const llvm::opt::OptTable &Opts = getOpts(); | ||||
389 | DerivedArgList *DAL = new DerivedArgList(Args); | ||||
390 | |||||
391 | bool HasNostdlib = Args.hasArg(options::OPT_nostdlib); | ||||
392 | bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx); | ||||
393 | bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs); | ||||
394 | bool IgnoreUnused = false; | ||||
395 | for (Arg *A : Args) { | ||||
396 | if (IgnoreUnused) | ||||
397 | A->claim(); | ||||
398 | |||||
399 | if (A->getOption().matches(options::OPT_start_no_unused_arguments)) { | ||||
400 | IgnoreUnused = true; | ||||
401 | continue; | ||||
402 | } | ||||
403 | if (A->getOption().matches(options::OPT_end_no_unused_arguments)) { | ||||
404 | IgnoreUnused = false; | ||||
405 | continue; | ||||
406 | } | ||||
407 | |||||
408 | // Unfortunately, we have to parse some forwarding options (-Xassembler, | ||||
409 | // -Xlinker, -Xpreprocessor) because we either integrate their functionality | ||||
410 | // (assembler and preprocessor), or bypass a previous driver ('collect2'). | ||||
411 | |||||
412 | // Rewrite linker options, to replace --no-demangle with a custom internal | ||||
413 | // option. | ||||
414 | if ((A->getOption().matches(options::OPT_Wl_COMMA) || | ||||
415 | A->getOption().matches(options::OPT_Xlinker)) && | ||||
416 | A->containsValue("--no-demangle")) { | ||||
417 | // Add the rewritten no-demangle argument. | ||||
418 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle)); | ||||
419 | |||||
420 | // Add the remaining values as Xlinker arguments. | ||||
421 | for (StringRef Val : A->getValues()) | ||||
422 | if (Val != "--no-demangle") | ||||
423 | DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val); | ||||
424 | |||||
425 | continue; | ||||
426 | } | ||||
427 | |||||
428 | // Rewrite preprocessor options, to replace -Wp,-MD,FOO which is used by | ||||
429 | // some build systems. We don't try to be complete here because we don't | ||||
430 | // care to encourage this usage model. | ||||
431 | if (A->getOption().matches(options::OPT_Wp_COMMA) && | ||||
432 | (A->getValue(0) == StringRef("-MD") || | ||||
433 | A->getValue(0) == StringRef("-MMD"))) { | ||||
434 | // Rewrite to -MD/-MMD along with -MF. | ||||
435 | if (A->getValue(0) == StringRef("-MD")) | ||||
436 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD)); | ||||
437 | else | ||||
438 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD)); | ||||
439 | if (A->getNumValues() == 2) | ||||
440 | DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1)); | ||||
441 | continue; | ||||
442 | } | ||||
443 | |||||
444 | // Rewrite reserved library names. | ||||
445 | if (A->getOption().matches(options::OPT_l)) { | ||||
446 | StringRef Value = A->getValue(); | ||||
447 | |||||
448 | // Rewrite unless -nostdlib is present. | ||||
449 | if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx && | ||||
450 | Value == "stdc++") { | ||||
451 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx)); | ||||
452 | continue; | ||||
453 | } | ||||
454 | |||||
455 | // Rewrite unconditionally. | ||||
456 | if (Value == "cc_kext") { | ||||
457 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext)); | ||||
458 | continue; | ||||
459 | } | ||||
460 | } | ||||
461 | |||||
462 | // Pick up inputs via the -- option. | ||||
463 | if (A->getOption().matches(options::OPT__DASH_DASH)) { | ||||
464 | A->claim(); | ||||
465 | for (StringRef Val : A->getValues()) | ||||
466 | DAL->append(MakeInputArg(*DAL, Opts, Val, false)); | ||||
467 | continue; | ||||
468 | } | ||||
469 | |||||
470 | DAL->append(A); | ||||
471 | } | ||||
472 | |||||
473 | // Enforce -static if -miamcu is present. | ||||
474 | if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) | ||||
475 | DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_static)); | ||||
476 | |||||
477 | // Add a default value of -mlinker-version=, if one was given and the user | ||||
478 | // didn't specify one. | ||||
479 | #if defined(HOST_LINK_VERSION) | ||||
480 | if (!Args.hasArg(options::OPT_mlinker_version_EQ) && | ||||
481 | strlen(HOST_LINK_VERSION) > 0) { | ||||
482 | DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ), | ||||
483 | HOST_LINK_VERSION); | ||||
484 | DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim(); | ||||
485 | } | ||||
486 | #endif | ||||
487 | |||||
488 | return DAL; | ||||
489 | } | ||||
490 | |||||
491 | /// Compute target triple from args. | ||||
492 | /// | ||||
493 | /// This routine provides the logic to compute a target triple from various | ||||
494 | /// args passed to the driver and the default triple string. | ||||
495 | static llvm::Triple computeTargetTriple(const Driver &D, | ||||
496 | StringRef TargetTriple, | ||||
497 | const ArgList &Args, | ||||
498 | StringRef DarwinArchName = "") { | ||||
499 | // FIXME: Already done in Compilation *Driver::BuildCompilation | ||||
500 | if (const Arg *A = Args.getLastArg(options::OPT_target)) | ||||
501 | TargetTriple = A->getValue(); | ||||
502 | |||||
503 | llvm::Triple Target(llvm::Triple::normalize(TargetTriple)); | ||||
504 | |||||
505 | // GNU/Hurd's triples should have been -hurd-gnu*, but were historically made | ||||
506 | // -gnu* only, and we can not change this, so we have to detect that case as | ||||
507 | // being the Hurd OS. | ||||
508 | if (TargetTriple.contains("-unknown-gnu") || TargetTriple.contains("-pc-gnu")) | ||||
509 | Target.setOSName("hurd"); | ||||
510 | |||||
511 | // Handle Apple-specific options available here. | ||||
512 | if (Target.isOSBinFormatMachO()) { | ||||
513 | // If an explicit Darwin arch name is given, that trumps all. | ||||
514 | if (!DarwinArchName.empty()) { | ||||
515 | tools::darwin::setTripleTypeForMachOArchName(Target, DarwinArchName); | ||||
516 | return Target; | ||||
517 | } | ||||
518 | |||||
519 | // Handle the Darwin '-arch' flag. | ||||
520 | if (Arg *A = Args.getLastArg(options::OPT_arch)) { | ||||
521 | StringRef ArchName = A->getValue(); | ||||
522 | tools::darwin::setTripleTypeForMachOArchName(Target, ArchName); | ||||
523 | } | ||||
524 | } | ||||
525 | |||||
526 | // Handle pseudo-target flags '-mlittle-endian'/'-EL' and | ||||
527 | // '-mbig-endian'/'-EB'. | ||||
528 | if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, | ||||
529 | options::OPT_mbig_endian)) { | ||||
530 | if (A->getOption().matches(options::OPT_mlittle_endian)) { | ||||
531 | llvm::Triple LE = Target.getLittleEndianArchVariant(); | ||||
532 | if (LE.getArch() != llvm::Triple::UnknownArch) | ||||
533 | Target = std::move(LE); | ||||
534 | } else { | ||||
535 | llvm::Triple BE = Target.getBigEndianArchVariant(); | ||||
536 | if (BE.getArch() != llvm::Triple::UnknownArch) | ||||
537 | Target = std::move(BE); | ||||
538 | } | ||||
539 | } | ||||
540 | |||||
541 | // Skip further flag support on OSes which don't support '-m32' or '-m64'. | ||||
542 | if (Target.getArch() == llvm::Triple::tce || | ||||
543 | Target.getOS() == llvm::Triple::Minix) | ||||
544 | return Target; | ||||
545 | |||||
546 | // On AIX, the env OBJECT_MODE may affect the resulting arch variant. | ||||
547 | if (Target.isOSAIX()) { | ||||
548 | if (Optional<std::string> ObjectModeValue = | ||||
549 | llvm::sys::Process::GetEnv("OBJECT_MODE")) { | ||||
550 | StringRef ObjectMode = *ObjectModeValue; | ||||
551 | llvm::Triple::ArchType AT = llvm::Triple::UnknownArch; | ||||
552 | |||||
553 | if (ObjectMode.equals("64")) { | ||||
554 | AT = Target.get64BitArchVariant().getArch(); | ||||
555 | } else if (ObjectMode.equals("32")) { | ||||
556 | AT = Target.get32BitArchVariant().getArch(); | ||||
557 | } else { | ||||
558 | D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode; | ||||
559 | } | ||||
560 | |||||
561 | if (AT != llvm::Triple::UnknownArch && AT != Target.getArch()) | ||||
562 | Target.setArch(AT); | ||||
563 | } | ||||
564 | } | ||||
565 | |||||
566 | // Handle pseudo-target flags '-m64', '-mx32', '-m32' and '-m16'. | ||||
567 | Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32, | ||||
568 | options::OPT_m32, options::OPT_m16); | ||||
569 | if (A) { | ||||
570 | llvm::Triple::ArchType AT = llvm::Triple::UnknownArch; | ||||
571 | |||||
572 | if (A->getOption().matches(options::OPT_m64)) { | ||||
573 | AT = Target.get64BitArchVariant().getArch(); | ||||
574 | if (Target.getEnvironment() == llvm::Triple::GNUX32) | ||||
575 | Target.setEnvironment(llvm::Triple::GNU); | ||||
576 | else if (Target.getEnvironment() == llvm::Triple::MuslX32) | ||||
577 | Target.setEnvironment(llvm::Triple::Musl); | ||||
578 | } else if (A->getOption().matches(options::OPT_mx32) && | ||||
579 | Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) { | ||||
580 | AT = llvm::Triple::x86_64; | ||||
581 | if (Target.getEnvironment() == llvm::Triple::Musl) | ||||
582 | Target.setEnvironment(llvm::Triple::MuslX32); | ||||
583 | else | ||||
584 | Target.setEnvironment(llvm::Triple::GNUX32); | ||||
585 | } else if (A->getOption().matches(options::OPT_m32)) { | ||||
586 | AT = Target.get32BitArchVariant().getArch(); | ||||
587 | if (Target.getEnvironment() == llvm::Triple::GNUX32) | ||||
588 | Target.setEnvironment(llvm::Triple::GNU); | ||||
589 | else if (Target.getEnvironment() == llvm::Triple::MuslX32) | ||||
590 | Target.setEnvironment(llvm::Triple::Musl); | ||||
591 | } else if (A->getOption().matches(options::OPT_m16) && | ||||
592 | Target.get32BitArchVariant().getArch() == llvm::Triple::x86) { | ||||
593 | AT = llvm::Triple::x86; | ||||
594 | Target.setEnvironment(llvm::Triple::CODE16); | ||||
595 | } | ||||
596 | |||||
597 | if (AT != llvm::Triple::UnknownArch && AT != Target.getArch()) { | ||||
598 | Target.setArch(AT); | ||||
599 | if (Target.isWindowsGNUEnvironment()) | ||||
600 | toolchains::MinGW::fixTripleArch(D, Target, Args); | ||||
601 | } | ||||
602 | } | ||||
603 | |||||
604 | // Handle -miamcu flag. | ||||
605 | if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) { | ||||
606 | if (Target.get32BitArchVariant().getArch() != llvm::Triple::x86) | ||||
607 | D.Diag(diag::err_drv_unsupported_opt_for_target) << "-miamcu" | ||||
608 | << Target.str(); | ||||
609 | |||||
610 | if (A && !A->getOption().matches(options::OPT_m32)) | ||||
611 | D.Diag(diag::err_drv_argument_not_allowed_with) | ||||
612 | << "-miamcu" << A->getBaseArg().getAsString(Args); | ||||
613 | |||||
614 | Target.setArch(llvm::Triple::x86); | ||||
615 | Target.setArchName("i586"); | ||||
616 | Target.setEnvironment(llvm::Triple::UnknownEnvironment); | ||||
617 | Target.setEnvironmentName(""); | ||||
618 | Target.setOS(llvm::Triple::ELFIAMCU); | ||||
619 | Target.setVendor(llvm::Triple::UnknownVendor); | ||||
620 | Target.setVendorName("intel"); | ||||
621 | } | ||||
622 | |||||
623 | // If target is MIPS adjust the target triple | ||||
624 | // accordingly to provided ABI name. | ||||
625 | A = Args.getLastArg(options::OPT_mabi_EQ); | ||||
626 | if (A && Target.isMIPS()) { | ||||
627 | StringRef ABIName = A->getValue(); | ||||
628 | if (ABIName == "32") { | ||||
629 | Target = Target.get32BitArchVariant(); | ||||
630 | if (Target.getEnvironment() == llvm::Triple::GNUABI64 || | ||||
631 | Target.getEnvironment() == llvm::Triple::GNUABIN32) | ||||
632 | Target.setEnvironment(llvm::Triple::GNU); | ||||
633 | } else if (ABIName == "n32") { | ||||
634 | Target = Target.get64BitArchVariant(); | ||||
635 | if (Target.getEnvironment() == llvm::Triple::GNU || | ||||
636 | Target.getEnvironment() == llvm::Triple::GNUABI64) | ||||
637 | Target.setEnvironment(llvm::Triple::GNUABIN32); | ||||
638 | } else if (ABIName == "64") { | ||||
639 | Target = Target.get64BitArchVariant(); | ||||
640 | if (Target.getEnvironment() == llvm::Triple::GNU || | ||||
641 | Target.getEnvironment() == llvm::Triple::GNUABIN32) | ||||
642 | Target.setEnvironment(llvm::Triple::GNUABI64); | ||||
643 | } | ||||
644 | } | ||||
645 | |||||
646 | // If target is RISC-V adjust the target triple according to | ||||
647 | // provided architecture name | ||||
648 | A = Args.getLastArg(options::OPT_march_EQ); | ||||
649 | if (A && Target.isRISCV()) { | ||||
650 | StringRef ArchName = A->getValue(); | ||||
651 | if (ArchName.startswith_insensitive("rv32")) | ||||
652 | Target.setArch(llvm::Triple::riscv32); | ||||
653 | else if (ArchName.startswith_insensitive("rv64")) | ||||
654 | Target.setArch(llvm::Triple::riscv64); | ||||
655 | } | ||||
656 | |||||
657 | return Target; | ||||
658 | } | ||||
659 | |||||
660 | // Parse the LTO options and record the type of LTO compilation | ||||
661 | // based on which -f(no-)?lto(=.*)? or -f(no-)?offload-lto(=.*)? | ||||
662 | // option occurs last. | ||||
663 | static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args, | ||||
664 | OptSpecifier OptEq, OptSpecifier OptNeg) { | ||||
665 | if (!Args.hasFlag(OptEq, OptNeg, false)) | ||||
666 | return LTOK_None; | ||||
667 | |||||
668 | const Arg *A = Args.getLastArg(OptEq); | ||||
669 | StringRef LTOName = A->getValue(); | ||||
670 | |||||
671 | driver::LTOKind LTOMode = llvm::StringSwitch<LTOKind>(LTOName) | ||||
672 | .Case("full", LTOK_Full) | ||||
673 | .Case("thin", LTOK_Thin) | ||||
674 | .Default(LTOK_Unknown); | ||||
675 | |||||
676 | if (LTOMode == LTOK_Unknown) { | ||||
677 | D.Diag(diag::err_drv_unsupported_option_argument) | ||||
678 | << A->getOption().getName() << A->getValue(); | ||||
679 | return LTOK_None; | ||||
680 | } | ||||
681 | return LTOMode; | ||||
682 | } | ||||
683 | |||||
684 | // Parse the LTO options. | ||||
685 | void Driver::setLTOMode(const llvm::opt::ArgList &Args) { | ||||
686 | LTOMode = | ||||
687 | parseLTOMode(*this, Args, options::OPT_flto_EQ, options::OPT_fno_lto); | ||||
688 | |||||
689 | OffloadLTOMode = parseLTOMode(*this, Args, options::OPT_foffload_lto_EQ, | ||||
690 | options::OPT_fno_offload_lto); | ||||
691 | } | ||||
692 | |||||
693 | /// Compute the desired OpenMP runtime from the flags provided. | ||||
694 | Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const { | ||||
695 | StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME"libomp"); | ||||
696 | |||||
697 | const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ); | ||||
698 | if (A) | ||||
699 | RuntimeName = A->getValue(); | ||||
700 | |||||
701 | auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName) | ||||
702 | .Case("libomp", OMPRT_OMP) | ||||
703 | .Case("libgomp", OMPRT_GOMP) | ||||
704 | .Case("libiomp5", OMPRT_IOMP5) | ||||
705 | .Default(OMPRT_Unknown); | ||||
706 | |||||
707 | if (RT == OMPRT_Unknown) { | ||||
708 | if (A) | ||||
709 | Diag(diag::err_drv_unsupported_option_argument) | ||||
710 | << A->getOption().getName() << A->getValue(); | ||||
711 | else | ||||
712 | // FIXME: We could use a nicer diagnostic here. | ||||
713 | Diag(diag::err_drv_unsupported_opt) << "-fopenmp"; | ||||
714 | } | ||||
715 | |||||
716 | return RT; | ||||
717 | } | ||||
718 | |||||
719 | void Driver::CreateOffloadingDeviceToolChains(Compilation &C, | ||||
720 | InputList &Inputs) { | ||||
721 | |||||
722 | // | ||||
723 | // CUDA/HIP | ||||
724 | // | ||||
725 | // We need to generate a CUDA/HIP toolchain if any of the inputs has a CUDA | ||||
726 | // or HIP type. However, mixed CUDA/HIP compilation is not supported. | ||||
727 | bool IsCuda = | ||||
728 | llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) { | ||||
729 | return types::isCuda(I.first); | ||||
730 | }); | ||||
731 | bool IsHIP = | ||||
732 | llvm::any_of(Inputs, | ||||
733 | [](std::pair<types::ID, const llvm::opt::Arg *> &I) { | ||||
734 | return types::isHIP(I.first); | ||||
735 | }) || | ||||
736 | C.getInputArgs().hasArg(options::OPT_hip_link); | ||||
737 | if (IsCuda && IsHIP) { | ||||
738 | Diag(clang::diag::err_drv_mix_cuda_hip); | ||||
739 | return; | ||||
740 | } | ||||
741 | if (IsCuda) { | ||||
742 | const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>(); | ||||
743 | const llvm::Triple &HostTriple = HostTC->getTriple(); | ||||
744 | auto OFK = Action::OFK_Cuda; | ||||
745 | auto CudaTriple = | ||||
746 | getNVIDIAOffloadTargetTriple(*this, C.getInputArgs(), HostTriple); | ||||
747 | if (!CudaTriple) | ||||
748 | return; | ||||
749 | // Use the CUDA and host triples as the key into the ToolChains map, | ||||
750 | // because the device toolchain we create depends on both. | ||||
751 | auto &CudaTC = ToolChains[CudaTriple->str() + "/" + HostTriple.str()]; | ||||
752 | if (!CudaTC) { | ||||
753 | CudaTC = std::make_unique<toolchains::CudaToolChain>( | ||||
754 | *this, *CudaTriple, *HostTC, C.getInputArgs(), OFK); | ||||
755 | } | ||||
756 | C.addOffloadDeviceToolChain(CudaTC.get(), OFK); | ||||
757 | } else if (IsHIP) { | ||||
758 | if (auto *OMPTargetArg = | ||||
759 | C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) { | ||||
760 | Diag(clang::diag::err_drv_unsupported_opt_for_language_mode) | ||||
761 | << OMPTargetArg->getSpelling() << "HIP"; | ||||
762 | return; | ||||
763 | } | ||||
764 | const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>(); | ||||
765 | auto OFK = Action::OFK_HIP; | ||||
766 | auto HIPTriple = getHIPOffloadTargetTriple(*this, C.getInputArgs()); | ||||
767 | if (!HIPTriple) | ||||
768 | return; | ||||
769 | auto *HIPTC = &getOffloadingDeviceToolChain(C.getInputArgs(), *HIPTriple, | ||||
770 | *HostTC, OFK); | ||||
771 | assert(HIPTC && "Could not create offloading device tool chain.")(static_cast <bool> (HIPTC && "Could not create offloading device tool chain." ) ? void (0) : __assert_fail ("HIPTC && \"Could not create offloading device tool chain.\"" , "clang/lib/Driver/Driver.cpp", 771, __extension__ __PRETTY_FUNCTION__ )); | ||||
772 | C.addOffloadDeviceToolChain(HIPTC, OFK); | ||||
773 | } | ||||
774 | |||||
775 | // | ||||
776 | // OpenMP | ||||
777 | // | ||||
778 | // We need to generate an OpenMP toolchain if the user specified targets with | ||||
779 | // the -fopenmp-targets option. | ||||
780 | if (Arg *OpenMPTargets = | ||||
781 | C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) { | ||||
782 | if (OpenMPTargets->getNumValues()) { | ||||
783 | // We expect that -fopenmp-targets is always used in conjunction with the | ||||
784 | // option -fopenmp specifying a valid runtime with offloading support, | ||||
785 | // i.e. libomp or libiomp. | ||||
786 | bool HasValidOpenMPRuntime = C.getInputArgs().hasFlag( | ||||
787 | options::OPT_fopenmp, options::OPT_fopenmp_EQ, | ||||
788 | options::OPT_fno_openmp, false); | ||||
789 | if (HasValidOpenMPRuntime) { | ||||
790 | OpenMPRuntimeKind OpenMPKind = getOpenMPRuntime(C.getInputArgs()); | ||||
791 | HasValidOpenMPRuntime = | ||||
792 | OpenMPKind == OMPRT_OMP || OpenMPKind == OMPRT_IOMP5; | ||||
793 | } | ||||
794 | |||||
795 | if (HasValidOpenMPRuntime) { | ||||
796 | llvm::StringMap<const char *> FoundNormalizedTriples; | ||||
797 | for (const char *Val : OpenMPTargets->getValues()) { | ||||
798 | llvm::Triple TT(ToolChain::getOpenMPTriple(Val)); | ||||
799 | std::string NormalizedName = TT.normalize(); | ||||
800 | |||||
801 | // Make sure we don't have a duplicate triple. | ||||
802 | auto Duplicate = FoundNormalizedTriples.find(NormalizedName); | ||||
803 | if (Duplicate != FoundNormalizedTriples.end()) { | ||||
804 | Diag(clang::diag::warn_drv_omp_offload_target_duplicate) | ||||
805 | << Val << Duplicate->second; | ||||
806 | continue; | ||||
807 | } | ||||
808 | |||||
809 | // Store the current triple so that we can check for duplicates in the | ||||
810 | // following iterations. | ||||
811 | FoundNormalizedTriples[NormalizedName] = Val; | ||||
812 | |||||
813 | // If the specified target is invalid, emit a diagnostic. | ||||
814 | if (TT.getArch() == llvm::Triple::UnknownArch) | ||||
815 | Diag(clang::diag::err_drv_invalid_omp_target) << Val; | ||||
816 | else { | ||||
817 | const ToolChain *TC; | ||||
818 | // Device toolchains have to be selected differently. They pair host | ||||
819 | // and device in their implementation. | ||||
820 | if (TT.isNVPTX() || TT.isAMDGCN()) { | ||||
821 | const ToolChain *HostTC = | ||||
822 | C.getSingleOffloadToolChain<Action::OFK_Host>(); | ||||
823 | assert(HostTC && "Host toolchain should be always defined.")(static_cast <bool> (HostTC && "Host toolchain should be always defined." ) ? void (0) : __assert_fail ("HostTC && \"Host toolchain should be always defined.\"" , "clang/lib/Driver/Driver.cpp", 823, __extension__ __PRETTY_FUNCTION__ )); | ||||
824 | auto &DeviceTC = | ||||
825 | ToolChains[TT.str() + "/" + HostTC->getTriple().normalize()]; | ||||
826 | if (!DeviceTC) { | ||||
827 | if (TT.isNVPTX()) | ||||
828 | DeviceTC = std::make_unique<toolchains::CudaToolChain>( | ||||
829 | *this, TT, *HostTC, C.getInputArgs(), Action::OFK_OpenMP); | ||||
830 | else if (TT.isAMDGCN()) | ||||
831 | DeviceTC = | ||||
832 | std::make_unique<toolchains::AMDGPUOpenMPToolChain>( | ||||
833 | *this, TT, *HostTC, C.getInputArgs()); | ||||
834 | else | ||||
835 | assert(DeviceTC && "Device toolchain not defined.")(static_cast <bool> (DeviceTC && "Device toolchain not defined." ) ? void (0) : __assert_fail ("DeviceTC && \"Device toolchain not defined.\"" , "clang/lib/Driver/Driver.cpp", 835, __extension__ __PRETTY_FUNCTION__ )); | ||||
836 | } | ||||
837 | |||||
838 | TC = DeviceTC.get(); | ||||
839 | } else | ||||
840 | TC = &getToolChain(C.getInputArgs(), TT); | ||||
841 | C.addOffloadDeviceToolChain(TC, Action::OFK_OpenMP); | ||||
842 | } | ||||
843 | } | ||||
844 | } else | ||||
845 | Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets); | ||||
846 | } else | ||||
847 | Diag(clang::diag::warn_drv_empty_joined_argument) | ||||
848 | << OpenMPTargets->getAsString(C.getInputArgs()); | ||||
849 | } | ||||
850 | |||||
851 | // | ||||
852 | // TODO: Add support for other offloading programming models here. | ||||
853 | // | ||||
854 | } | ||||
855 | |||||
856 | /// Looks the given directories for the specified file. | ||||
857 | /// | ||||
858 | /// \param[out] FilePath File path, if the file was found. | ||||
859 | /// \param[in] Dirs Directories used for the search. | ||||
860 | /// \param[in] FileName Name of the file to search for. | ||||
861 | /// \return True if file was found. | ||||
862 | /// | ||||
863 | /// Looks for file specified by FileName sequentially in directories specified | ||||
864 | /// by Dirs. | ||||
865 | /// | ||||
866 | static bool searchForFile(SmallVectorImpl<char> &FilePath, | ||||
867 | ArrayRef<StringRef> Dirs, StringRef FileName) { | ||||
868 | SmallString<128> WPath; | ||||
869 | for (const StringRef &Dir : Dirs) { | ||||
870 | if (Dir.empty()) | ||||
871 | continue; | ||||
872 | WPath.clear(); | ||||
873 | llvm::sys::path::append(WPath, Dir, FileName); | ||||
874 | llvm::sys::path::native(WPath); | ||||
875 | if (llvm::sys::fs::is_regular_file(WPath)) { | ||||
876 | FilePath = std::move(WPath); | ||||
877 | return true; | ||||
878 | } | ||||
879 | } | ||||
880 | return false; | ||||
881 | } | ||||
882 | |||||
883 | bool Driver::readConfigFile(StringRef FileName) { | ||||
884 | // Try reading the given file. | ||||
885 | SmallVector<const char *, 32> NewCfgArgs; | ||||
886 | if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) { | ||||
887 | Diag(diag::err_drv_cannot_read_config_file) << FileName; | ||||
888 | return true; | ||||
889 | } | ||||
890 | |||||
891 | // Read options from config file. | ||||
892 | llvm::SmallString<128> CfgFileName(FileName); | ||||
893 | llvm::sys::path::native(CfgFileName); | ||||
894 | ConfigFile = std::string(CfgFileName); | ||||
895 | bool ContainErrors; | ||||
896 | CfgOptions = std::make_unique<InputArgList>( | ||||
897 | ParseArgStrings(NewCfgArgs, IsCLMode(), ContainErrors)); | ||||
898 | if (ContainErrors) { | ||||
899 | CfgOptions.reset(); | ||||
900 | return true; | ||||
901 | } | ||||
902 | |||||
903 | if (CfgOptions->hasArg(options::OPT_config)) { | ||||
904 | CfgOptions.reset(); | ||||
905 | Diag(diag::err_drv_nested_config_file); | ||||
906 | return true; | ||||
907 | } | ||||
908 | |||||
909 | // Claim all arguments that come from a configuration file so that the driver | ||||
910 | // does not warn on any that is unused. | ||||
911 | for (Arg *A : *CfgOptions) | ||||
912 | A->claim(); | ||||
913 | return false; | ||||
914 | } | ||||
915 | |||||
916 | bool Driver::loadConfigFile() { | ||||
917 | std::string CfgFileName; | ||||
918 | bool FileSpecifiedExplicitly = false; | ||||
919 | |||||
920 | // Process options that change search path for config files. | ||||
921 | if (CLOptions) { | ||||
922 | if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) { | ||||
923 | SmallString<128> CfgDir; | ||||
924 | CfgDir.append( | ||||
925 | CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ)); | ||||
926 | if (!CfgDir.empty()) { | ||||
927 | if (llvm::sys::fs::make_absolute(CfgDir).value() != 0) | ||||
928 | SystemConfigDir.clear(); | ||||
929 | else | ||||
930 | SystemConfigDir = std::string(CfgDir.begin(), CfgDir.end()); | ||||
931 | } | ||||
932 | } | ||||
933 | if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) { | ||||
934 | SmallString<128> CfgDir; | ||||
935 | CfgDir.append( | ||||
936 | CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ)); | ||||
937 | if (!CfgDir.empty()) { | ||||
938 | if (llvm::sys::fs::make_absolute(CfgDir).value() != 0) | ||||
939 | UserConfigDir.clear(); | ||||
940 | else | ||||
941 | UserConfigDir = std::string(CfgDir.begin(), CfgDir.end()); | ||||
942 | } | ||||
943 | } | ||||
944 | } | ||||
945 | |||||
946 | // First try to find config file specified in command line. | ||||
947 | if (CLOptions) { | ||||
948 | std::vector<std::string> ConfigFiles = | ||||
949 | CLOptions->getAllArgValues(options::OPT_config); | ||||
950 | if (ConfigFiles.size() > 1) { | ||||
951 | if (!llvm::all_of(ConfigFiles, [ConfigFiles](const std::string &s) { | ||||
952 | return s == ConfigFiles[0]; | ||||
953 | })) { | ||||
954 | Diag(diag::err_drv_duplicate_config); | ||||
955 | return true; | ||||
956 | } | ||||
957 | } | ||||
958 | |||||
959 | if (!ConfigFiles.empty()) { | ||||
960 | CfgFileName = ConfigFiles.front(); | ||||
961 | assert(!CfgFileName.empty())(static_cast <bool> (!CfgFileName.empty()) ? void (0) : __assert_fail ("!CfgFileName.empty()", "clang/lib/Driver/Driver.cpp" , 961, __extension__ __PRETTY_FUNCTION__)); | ||||
962 | |||||
963 | // If argument contains directory separator, treat it as a path to | ||||
964 | // configuration file. | ||||
965 | if (llvm::sys::path::has_parent_path(CfgFileName)) { | ||||
966 | SmallString<128> CfgFilePath; | ||||
967 | if (llvm::sys::path::is_relative(CfgFileName)) | ||||
968 | llvm::sys::fs::current_path(CfgFilePath); | ||||
969 | llvm::sys::path::append(CfgFilePath, CfgFileName); | ||||
970 | if (!llvm::sys::fs::is_regular_file(CfgFilePath)) { | ||||
971 | Diag(diag::err_drv_config_file_not_exist) << CfgFilePath; | ||||
972 | return true; | ||||
973 | } | ||||
974 | return readConfigFile(CfgFilePath); | ||||
975 | } | ||||
976 | |||||
977 | FileSpecifiedExplicitly = true; | ||||
978 | } | ||||
979 | } | ||||
980 | |||||
981 | // If config file is not specified explicitly, try to deduce configuration | ||||
982 | // from executable name. For instance, an executable 'armv7l-clang' will | ||||
983 | // search for config file 'armv7l-clang.cfg'. | ||||
984 | if (CfgFileName.empty() && !ClangNameParts.TargetPrefix.empty()) | ||||
985 | CfgFileName = ClangNameParts.TargetPrefix + '-' + ClangNameParts.ModeSuffix; | ||||
986 | |||||
987 | if (CfgFileName.empty()) | ||||
988 | return false; | ||||
989 | |||||
990 | // Determine architecture part of the file name, if it is present. | ||||
991 | StringRef CfgFileArch = CfgFileName; | ||||
992 | size_t ArchPrefixLen = CfgFileArch.find('-'); | ||||
993 | if (ArchPrefixLen == StringRef::npos) | ||||
994 | ArchPrefixLen = CfgFileArch.size(); | ||||
995 | llvm::Triple CfgTriple; | ||||
996 | CfgFileArch = CfgFileArch.take_front(ArchPrefixLen); | ||||
997 | CfgTriple = llvm::Triple(llvm::Triple::normalize(CfgFileArch)); | ||||
998 | if (CfgTriple.getArch() == llvm::Triple::ArchType::UnknownArch) | ||||
999 | ArchPrefixLen = 0; | ||||
1000 | |||||
1001 | if (!StringRef(CfgFileName).endswith(".cfg")) | ||||
1002 | CfgFileName += ".cfg"; | ||||
1003 | |||||
1004 | // If config file starts with architecture name and command line options | ||||
1005 | // redefine architecture (with options like -m32 -LE etc), try finding new | ||||
1006 | // config file with that architecture. | ||||
1007 | SmallString<128> FixedConfigFile; | ||||
1008 | size_t FixedArchPrefixLen = 0; | ||||
1009 | if (ArchPrefixLen) { | ||||
1010 | // Get architecture name from config file name like 'i386.cfg' or | ||||
1011 | // 'armv7l-clang.cfg'. | ||||
1012 | // Check if command line options changes effective triple. | ||||
1013 | llvm::Triple EffectiveTriple = computeTargetTriple(*this, | ||||
1014 | CfgTriple.getTriple(), *CLOptions); | ||||
1015 | if (CfgTriple.getArch() != EffectiveTriple.getArch()) { | ||||
1016 | FixedConfigFile = EffectiveTriple.getArchName(); | ||||
1017 | FixedArchPrefixLen = FixedConfigFile.size(); | ||||
1018 | // Append the rest of original file name so that file name transforms | ||||
1019 | // like: i386-clang.cfg -> x86_64-clang.cfg. | ||||
1020 | if (ArchPrefixLen < CfgFileName.size()) | ||||
1021 | FixedConfigFile += CfgFileName.substr(ArchPrefixLen); | ||||
1022 | } | ||||
1023 | } | ||||
1024 | |||||
1025 | // Prepare list of directories where config file is searched for. | ||||
1026 | StringRef CfgFileSearchDirs[] = {UserConfigDir, SystemConfigDir, Dir}; | ||||
1027 | |||||
1028 | // Try to find config file. First try file with corrected architecture. | ||||
1029 | llvm::SmallString<128> CfgFilePath; | ||||
1030 | if (!FixedConfigFile.empty()) { | ||||
1031 | if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile)) | ||||
1032 | return readConfigFile(CfgFilePath); | ||||
1033 | // If 'x86_64-clang.cfg' was not found, try 'x86_64.cfg'. | ||||
1034 | FixedConfigFile.resize(FixedArchPrefixLen); | ||||
1035 | FixedConfigFile.append(".cfg"); | ||||
1036 | if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile)) | ||||
1037 | return readConfigFile(CfgFilePath); | ||||
1038 | } | ||||
1039 | |||||
1040 | // Then try original file name. | ||||
1041 | if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName)) | ||||
1042 | return readConfigFile(CfgFilePath); | ||||
1043 | |||||
1044 | // Finally try removing driver mode part: 'x86_64-clang.cfg' -> 'x86_64.cfg'. | ||||
1045 | if (!ClangNameParts.ModeSuffix.empty() && | ||||
1046 | !ClangNameParts.TargetPrefix.empty()) { | ||||
1047 | CfgFileName.assign(ClangNameParts.TargetPrefix); | ||||
1048 | CfgFileName.append(".cfg"); | ||||
1049 | if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName)) | ||||
1050 | return readConfigFile(CfgFilePath); | ||||
1051 | } | ||||
1052 | |||||
1053 | // Report error but only if config file was specified explicitly, by option | ||||
1054 | // --config. If it was deduced from executable name, it is not an error. | ||||
1055 | if (FileSpecifiedExplicitly) { | ||||
1056 | Diag(diag::err_drv_config_file_not_found) << CfgFileName; | ||||
1057 | for (const StringRef &SearchDir : CfgFileSearchDirs) | ||||
1058 | if (!SearchDir.empty()) | ||||
1059 | Diag(diag::note_drv_config_file_searched_in) << SearchDir; | ||||
1060 | return true; | ||||
1061 | } | ||||
1062 | |||||
1063 | return false; | ||||
1064 | } | ||||
1065 | |||||
1066 | Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { | ||||
1067 | llvm::PrettyStackTraceString CrashInfo("Compilation construction"); | ||||
1068 | |||||
1069 | // FIXME: Handle environment options which affect driver behavior, somewhere | ||||
1070 | // (client?). GCC_EXEC_PREFIX, LPATH, CC_PRINT_OPTIONS. | ||||
1071 | |||||
1072 | // We look for the driver mode option early, because the mode can affect | ||||
1073 | // how other options are parsed. | ||||
1074 | |||||
1075 | auto DriverMode = getDriverMode(ClangExecutable, ArgList.slice(1)); | ||||
1076 | if (!DriverMode.empty()) | ||||
1077 | setDriverMode(DriverMode); | ||||
1078 | |||||
1079 | // FIXME: What are we going to do with -V and -b? | ||||
1080 | |||||
1081 | // Arguments specified in command line. | ||||
1082 | bool ContainsError; | ||||
1083 | CLOptions = std::make_unique<InputArgList>( | ||||
1084 | ParseArgStrings(ArgList.slice(1), IsCLMode(), ContainsError)); | ||||
1085 | |||||
1086 | // Try parsing configuration file. | ||||
1087 | if (!ContainsError) | ||||
1088 | ContainsError = loadConfigFile(); | ||||
1089 | bool HasConfigFile = !ContainsError && (CfgOptions.get() != nullptr); | ||||
1090 | |||||
1091 | // All arguments, from both config file and command line. | ||||
1092 | InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions) | ||||
1093 | : std::move(*CLOptions)); | ||||
1094 | |||||
1095 | // The args for config files or /clang: flags belong to different InputArgList | ||||
1096 | // objects than Args. This copies an Arg from one of those other InputArgLists | ||||
1097 | // to the ownership of Args. | ||||
1098 | auto appendOneArg = [&Args](const Arg *Opt, const Arg *BaseArg) { | ||||
1099 | unsigned Index = Args.MakeIndex(Opt->getSpelling()); | ||||
1100 | Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index), | ||||
1101 | Index, BaseArg); | ||||
1102 | Copy->getValues() = Opt->getValues(); | ||||
1103 | if (Opt->isClaimed()) | ||||
1104 | Copy->claim(); | ||||
1105 | Copy->setOwnsValues(Opt->getOwnsValues()); | ||||
1106 | Opt->setOwnsValues(false); | ||||
1107 | Args.append(Copy); | ||||
1108 | }; | ||||
1109 | |||||
1110 | if (HasConfigFile) | ||||
1111 | for (auto *Opt : *CLOptions) { | ||||
1112 | if (Opt->getOption().matches(options::OPT_config)) | ||||
1113 | continue; | ||||
1114 | const Arg *BaseArg = &Opt->getBaseArg(); | ||||
1115 | if (BaseArg == Opt) | ||||
1116 | BaseArg = nullptr; | ||||
1117 | appendOneArg(Opt, BaseArg); | ||||
1118 | } | ||||
1119 | |||||
1120 | // In CL mode, look for any pass-through arguments | ||||
1121 | if (IsCLMode() && !ContainsError) { | ||||
1122 | SmallVector<const char *, 16> CLModePassThroughArgList; | ||||
1123 | for (const auto *A : Args.filtered(options::OPT__SLASH_clang)) { | ||||
1124 | A->claim(); | ||||
1125 | CLModePassThroughArgList.push_back(A->getValue()); | ||||
1126 | } | ||||
1127 | |||||
1128 | if (!CLModePassThroughArgList.empty()) { | ||||
1129 | // Parse any pass through args using default clang processing rather | ||||
1130 | // than clang-cl processing. | ||||
1131 | auto CLModePassThroughOptions = std::make_unique<InputArgList>( | ||||
1132 | ParseArgStrings(CLModePassThroughArgList, false, ContainsError)); | ||||
1133 | |||||
1134 | if (!ContainsError) | ||||
1135 | for (auto *Opt : *CLModePassThroughOptions) { | ||||
1136 | appendOneArg(Opt, nullptr); | ||||
1137 | } | ||||
1138 | } | ||||
1139 | } | ||||
1140 | |||||
1141 | // Check for working directory option before accessing any files | ||||
1142 | if (Arg *WD = Args.getLastArg(options::OPT_working_directory)) | ||||
1143 | if (VFS->setCurrentWorkingDirectory(WD->getValue())) | ||||
1144 | Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue(); | ||||
1145 | |||||
1146 | // FIXME: This stuff needs to go into the Compilation, not the driver. | ||||
1147 | bool CCCPrintPhases; | ||||
1148 | |||||
1149 | // Silence driver warnings if requested | ||||
1150 | Diags.setIgnoreAllWarnings(Args.hasArg(options::OPT_w)); | ||||
1151 | |||||
1152 | // -canonical-prefixes, -no-canonical-prefixes are used very early in main. | ||||
1153 | Args.ClaimAllArgs(options::OPT_canonical_prefixes); | ||||
1154 | Args.ClaimAllArgs(options::OPT_no_canonical_prefixes); | ||||
1155 | |||||
1156 | // f(no-)integated-cc1 is also used very early in main. | ||||
1157 | Args.ClaimAllArgs(options::OPT_fintegrated_cc1); | ||||
1158 | Args.ClaimAllArgs(options::OPT_fno_integrated_cc1); | ||||
1159 | |||||
1160 | // Ignore -pipe. | ||||
1161 | Args.ClaimAllArgs(options::OPT_pipe); | ||||
1162 | |||||
1163 | // Extract -ccc args. | ||||
1164 | // | ||||
1165 | // FIXME: We need to figure out where this behavior should live. Most of it | ||||
1166 | // should be outside in the client; the parts that aren't should have proper | ||||
1167 | // options, either by introducing new ones or by overloading gcc ones like -V | ||||
1168 | // or -b. | ||||
1169 | CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases); | ||||
1170 | CCCPrintBindings = Args.hasArg(options::OPT_ccc_print_bindings); | ||||
1171 | if (const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name)) | ||||
1172 | CCCGenericGCCName = A->getValue(); | ||||
1173 | GenReproducer = Args.hasFlag(options::OPT_gen_reproducer, | ||||
1174 | options::OPT_fno_crash_diagnostics, | ||||
1175 | !!::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")); | ||||
1176 | |||||
1177 | // Process -fproc-stat-report options. | ||||
1178 | if (const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) { | ||||
1179 | CCPrintProcessStats = true; | ||||
1180 | CCPrintStatReportFilename = A->getValue(); | ||||
1181 | } | ||||
1182 | if (Args.hasArg(options::OPT_fproc_stat_report)) | ||||
1183 | CCPrintProcessStats = true; | ||||
1184 | |||||
1185 | // FIXME: TargetTriple is used by the target-prefixed calls to as/ld | ||||
1186 | // and getToolChain is const. | ||||
1187 | if (IsCLMode()) { | ||||
1188 | // clang-cl targets MSVC-style Win32. | ||||
1189 | llvm::Triple T(TargetTriple); | ||||
1190 | T.setOS(llvm::Triple::Win32); | ||||
1191 | T.setVendor(llvm::Triple::PC); | ||||
1192 | T.setEnvironment(llvm::Triple::MSVC); | ||||
1193 | T.setObjectFormat(llvm::Triple::COFF); | ||||
1194 | TargetTriple = T.str(); | ||||
1195 | } else if (IsDXCMode()) { | ||||
1196 | // clang-dxc target is build from target_profile option. | ||||
1197 | // Just set OS to shader model to select HLSLToolChain. | ||||
1198 | llvm::Triple T(TargetTriple); | ||||
1199 | T.setOS(llvm::Triple::ShaderModel); | ||||
1200 | TargetTriple = T.str(); | ||||
1201 | } | ||||
1202 | |||||
1203 | if (const Arg *A = Args.getLastArg(options::OPT_target)) | ||||
1204 | TargetTriple = A->getValue(); | ||||
1205 | if (const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir)) | ||||
1206 | Dir = InstalledDir = A->getValue(); | ||||
1207 | for (const Arg *A : Args.filtered(options::OPT_B)) { | ||||
1208 | A->claim(); | ||||
1209 | PrefixDirs.push_back(A->getValue(0)); | ||||
1210 | } | ||||
1211 | if (Optional<std::string> CompilerPathValue = | ||||
1212 | llvm::sys::Process::GetEnv("COMPILER_PATH")) { | ||||
1213 | StringRef CompilerPath = *CompilerPathValue; | ||||
1214 | while (!CompilerPath.empty()) { | ||||
1215 | std::pair<StringRef, StringRef> Split = | ||||
1216 | CompilerPath.split(llvm::sys::EnvPathSeparator); | ||||
1217 | PrefixDirs.push_back(std::string(Split.first)); | ||||
1218 | CompilerPath = Split.second; | ||||
1219 | } | ||||
1220 | } | ||||
1221 | if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) | ||||
1222 | SysRoot = A->getValue(); | ||||
1223 | if (const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ)) | ||||
1224 | DyldPrefix = A->getValue(); | ||||
1225 | |||||
1226 | if (const Arg *A = Args.getLastArg(options::OPT_resource_dir)) | ||||
1227 | ResourceDir = A->getValue(); | ||||
1228 | |||||
1229 | if (const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) { | ||||
1230 | SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue()) | ||||
1231 | .Case("cwd", SaveTempsCwd) | ||||
1232 | .Case("obj", SaveTempsObj) | ||||
1233 | .Default(SaveTempsCwd); | ||||
1234 | } | ||||
1235 | |||||
1236 | setLTOMode(Args); | ||||
1237 | |||||
1238 | // Process -fembed-bitcode= flags. | ||||
1239 | if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) { | ||||
1240 | StringRef Name = A->getValue(); | ||||
1241 | unsigned Model = llvm::StringSwitch<unsigned>(Name) | ||||
1242 | .Case("off", EmbedNone) | ||||
1243 | .Case("all", EmbedBitcode) | ||||
1244 | .Case("bitcode", EmbedBitcode) | ||||
1245 | .Case("marker", EmbedMarker) | ||||
1246 | .Default(~0U); | ||||
1247 | if (Model == ~0U) { | ||||
1248 | Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) | ||||
1249 | << Name; | ||||
1250 | } else | ||||
1251 | BitcodeEmbed = static_cast<BitcodeEmbedMode>(Model); | ||||
1252 | } | ||||
1253 | |||||
1254 | std::unique_ptr<llvm::opt::InputArgList> UArgs = | ||||
1255 | std::make_unique<InputArgList>(std::move(Args)); | ||||
1256 | |||||
1257 | // Perform the default argument translations. | ||||
1258 | DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs); | ||||
1259 | |||||
1260 | // Owned by the host. | ||||
1261 | const ToolChain &TC = getToolChain( | ||||
1262 | *UArgs, computeTargetTriple(*this, TargetTriple, *UArgs)); | ||||
1263 | |||||
1264 | // The compilation takes ownership of Args. | ||||
1265 | Compilation *C = new Compilation(*this, TC, UArgs.release(), TranslatedArgs, | ||||
1266 | ContainsError); | ||||
1267 | |||||
1268 | if (!HandleImmediateArgs(*C)) | ||||
1269 | return C; | ||||
1270 | |||||
1271 | // Construct the list of inputs. | ||||
1272 | InputList Inputs; | ||||
1273 | BuildInputs(C->getDefaultToolChain(), *TranslatedArgs, Inputs); | ||||
1274 | |||||
1275 | // Populate the tool chains for the offloading devices, if any. | ||||
1276 | CreateOffloadingDeviceToolChains(*C, Inputs); | ||||
1277 | |||||
1278 | // Construct the list of abstract actions to perform for this compilation. On | ||||
1279 | // MachO targets this uses the driver-driver and universal actions. | ||||
1280 | if (TC.getTriple().isOSBinFormatMachO()) | ||||
1281 | BuildUniversalActions(*C, C->getDefaultToolChain(), Inputs); | ||||
1282 | else | ||||
1283 | BuildActions(*C, C->getArgs(), Inputs, C->getActions()); | ||||
1284 | |||||
1285 | if (CCCPrintPhases) { | ||||
1286 | PrintActions(*C); | ||||
1287 | return C; | ||||
1288 | } | ||||
1289 | |||||
1290 | BuildJobs(*C); | ||||
1291 | |||||
1292 | return C; | ||||
1293 | } | ||||
1294 | |||||
1295 | static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args) { | ||||
1296 | llvm::opt::ArgStringList ASL; | ||||
1297 | for (const auto *A : Args) { | ||||
1298 | // Use user's original spelling of flags. For example, use | ||||
1299 | // `/source-charset:utf-8` instead of `-finput-charset=utf-8` if the user | ||||
1300 | // wrote the former. | ||||
1301 | while (A->getAlias()) | ||||
1302 | A = A->getAlias(); | ||||
1303 | A->render(Args, ASL); | ||||
1304 | } | ||||
1305 | |||||
1306 | for (auto I = ASL.begin(), E = ASL.end(); I != E; ++I) { | ||||
1307 | if (I != ASL.begin()) | ||||
1308 | OS << ' '; | ||||
1309 | llvm::sys::printArg(OS, *I, true); | ||||
1310 | } | ||||
1311 | OS << '\n'; | ||||
1312 | } | ||||
1313 | |||||
1314 | bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename, | ||||
1315 | SmallString<128> &CrashDiagDir) { | ||||
1316 | using namespace llvm::sys; | ||||
1317 | assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&(static_cast <bool> (llvm::Triple(llvm::sys::getProcessTriple ()).isOSDarwin() && "Only knows about .crash files on Darwin" ) ? void (0) : __assert_fail ("llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() && \"Only knows about .crash files on Darwin\"" , "clang/lib/Driver/Driver.cpp", 1318, __extension__ __PRETTY_FUNCTION__ )) | ||||
1318 | "Only knows about .crash files on Darwin")(static_cast <bool> (llvm::Triple(llvm::sys::getProcessTriple ()).isOSDarwin() && "Only knows about .crash files on Darwin" ) ? void (0) : __assert_fail ("llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() && \"Only knows about .crash files on Darwin\"" , "clang/lib/Driver/Driver.cpp", 1318, __extension__ __PRETTY_FUNCTION__ )); | ||||
1319 | |||||
1320 | // The .crash file can be found on at ~/Library/Logs/DiagnosticReports/ | ||||
1321 | // (or /Library/Logs/DiagnosticReports for root) and has the filename pattern | ||||
1322 | // clang-<VERSION>_<YYYY-MM-DD-HHMMSS>_<hostname>.crash. | ||||
1323 | path::home_directory(CrashDiagDir); | ||||
1324 | if (CrashDiagDir.startswith("/var/root")) | ||||
1325 | CrashDiagDir = "/"; | ||||
1326 | path::append(CrashDiagDir, "Library/Logs/DiagnosticReports"); | ||||
1327 | int PID = | ||||
1328 | #if LLVM_ON_UNIX1 | ||||
1329 | getpid(); | ||||
1330 | #else | ||||
1331 | 0; | ||||
1332 | #endif | ||||
1333 | std::error_code EC; | ||||
1334 | fs::file_status FileStatus; | ||||
1335 | TimePoint<> LastAccessTime; | ||||
1336 | SmallString<128> CrashFilePath; | ||||
1337 | // Lookup the .crash files and get the one generated by a subprocess spawned | ||||
1338 | // by this driver invocation. | ||||
1339 | for (fs::directory_iterator File(CrashDiagDir, EC), FileEnd; | ||||
1340 | File != FileEnd && !EC; File.increment(EC)) { | ||||
1341 | StringRef FileName = path::filename(File->path()); | ||||
1342 | if (!FileName.startswith(Name)) | ||||
1343 | continue; | ||||
1344 | if (fs::status(File->path(), FileStatus)) | ||||
1345 | continue; | ||||
1346 | llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile = | ||||
1347 | llvm::MemoryBuffer::getFile(File->path()); | ||||
1348 | if (!CrashFile) | ||||
1349 | continue; | ||||
1350 | // The first line should start with "Process:", otherwise this isn't a real | ||||
1351 | // .crash file. | ||||
1352 | StringRef Data = CrashFile.get()->getBuffer(); | ||||
1353 | if (!Data.startswith("Process:")) | ||||
1354 | continue; | ||||
1355 | // Parse parent process pid line, e.g: "Parent Process: clang-4.0 [79141]" | ||||
1356 | size_t ParentProcPos = Data.find("Parent Process:"); | ||||
1357 | if (ParentProcPos == StringRef::npos) | ||||
1358 | continue; | ||||
1359 | size_t LineEnd = Data.find_first_of("\n", ParentProcPos); | ||||
1360 | if (LineEnd == StringRef::npos) | ||||
1361 | continue; | ||||
1362 | StringRef ParentProcess = Data.slice(ParentProcPos+15, LineEnd).trim(); | ||||
1363 | int OpenBracket = -1, CloseBracket = -1; | ||||
1364 | for (size_t i = 0, e = ParentProcess.size(); i < e; ++i) { | ||||
1365 | if (ParentProcess[i] == '[') | ||||
1366 | OpenBracket = i; | ||||
1367 | if (ParentProcess[i] == ']') | ||||
1368 | CloseBracket = i; | ||||
1369 | } | ||||
1370 | // Extract the parent process PID from the .crash file and check whether | ||||
1371 | // it matches this driver invocation pid. | ||||
1372 | int CrashPID; | ||||
1373 | if (OpenBracket < 0 || CloseBracket < 0 || | ||||
1374 | ParentProcess.slice(OpenBracket + 1, CloseBracket) | ||||
1375 | .getAsInteger(10, CrashPID) || CrashPID != PID) { | ||||
1376 | continue; | ||||
1377 | } | ||||
1378 | |||||
1379 | // Found a .crash file matching the driver pid. To avoid getting an older | ||||
1380 | // and misleading crash file, continue looking for the most recent. | ||||
1381 | // FIXME: the driver can dispatch multiple cc1 invocations, leading to | ||||
1382 | // multiple crashes poiting to the same parent process. Since the driver | ||||
1383 | // does not collect pid information for the dispatched invocation there's | ||||
1384 | // currently no way to distinguish among them. | ||||
1385 | const auto FileAccessTime = FileStatus.getLastModificationTime(); | ||||
1386 | if (FileAccessTime > LastAccessTime) { | ||||
1387 | CrashFilePath.assign(File->path()); | ||||
1388 | LastAccessTime = FileAccessTime; | ||||
1389 | } | ||||
1390 | } | ||||
1391 | |||||
1392 | // If found, copy it over to the location of other reproducer files. | ||||
1393 | if (!CrashFilePath.empty()) { | ||||
1394 | EC = fs::copy_file(CrashFilePath, ReproCrashFilename); | ||||
1395 | if (EC) | ||||
1396 | return false; | ||||
1397 | return true; | ||||
1398 | } | ||||
1399 | |||||
1400 | return false; | ||||
1401 | } | ||||
1402 | |||||
1403 | // When clang crashes, produce diagnostic information including the fully | ||||
1404 | // preprocessed source file(s). Request that the developer attach the | ||||
1405 | // diagnostic information to a bug report. | ||||
1406 | void Driver::generateCompilationDiagnostics( | ||||
1407 | Compilation &C, const Command &FailingCommand, | ||||
1408 | StringRef AdditionalInformation, CompilationDiagnosticReport *Report) { | ||||
1409 | if (C.getArgs().hasArg(options::OPT_fno_crash_diagnostics)) | ||||
1410 | return; | ||||
1411 | |||||
1412 | // Don't try to generate diagnostics for link or dsymutil jobs. | ||||
1413 | if (FailingCommand.getCreator().isLinkJob() || | ||||
1414 | FailingCommand.getCreator().isDsymutilJob()) | ||||
1415 | return; | ||||
1416 | |||||
1417 | // Print the version of the compiler. | ||||
1418 | PrintVersion(C, llvm::errs()); | ||||
1419 | |||||
1420 | // Suppress driver output and emit preprocessor output to temp file. | ||||
1421 | CCGenDiagnostics = true; | ||||
1422 | |||||
1423 | // Save the original job command(s). | ||||
1424 | Command Cmd = FailingCommand; | ||||
1425 | |||||
1426 | // Keep track of whether we produce any errors while trying to produce | ||||
1427 | // preprocessed sources. | ||||
1428 | DiagnosticErrorTrap Trap(Diags); | ||||
1429 | |||||
1430 | // Suppress tool output. | ||||
1431 | C.initCompilationForDiagnostics(); | ||||
1432 | |||||
1433 | // Construct the list of inputs. | ||||
1434 | InputList Inputs; | ||||
1435 | BuildInputs(C.getDefaultToolChain(), C.getArgs(), Inputs); | ||||
1436 | |||||
1437 | for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) { | ||||
1438 | bool IgnoreInput = false; | ||||
1439 | |||||
1440 | // Ignore input from stdin or any inputs that cannot be preprocessed. | ||||
1441 | // Check type first as not all linker inputs have a value. | ||||
1442 | if (types::getPreprocessedType(it->first) == types::TY_INVALID) { | ||||
1443 | IgnoreInput = true; | ||||
1444 | } else if (!strcmp(it->second->getValue(), "-")) { | ||||
1445 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1446 | << "Error generating preprocessed source(s) - " | ||||
1447 | "ignoring input from stdin."; | ||||
1448 | IgnoreInput = true; | ||||
1449 | } | ||||
1450 | |||||
1451 | if (IgnoreInput) { | ||||
1452 | it = Inputs.erase(it); | ||||
1453 | ie = Inputs.end(); | ||||
1454 | } else { | ||||
1455 | ++it; | ||||
1456 | } | ||||
1457 | } | ||||
1458 | |||||
1459 | if (Inputs.empty()) { | ||||
1460 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1461 | << "Error generating preprocessed source(s) - " | ||||
1462 | "no preprocessable inputs."; | ||||
1463 | return; | ||||
1464 | } | ||||
1465 | |||||
1466 | // Don't attempt to generate preprocessed files if multiple -arch options are | ||||
1467 | // used, unless they're all duplicates. | ||||
1468 | llvm::StringSet<> ArchNames; | ||||
1469 | for (const Arg *A : C.getArgs()) { | ||||
1470 | if (A->getOption().matches(options::OPT_arch)) { | ||||
1471 | StringRef ArchName = A->getValue(); | ||||
1472 | ArchNames.insert(ArchName); | ||||
1473 | } | ||||
1474 | } | ||||
1475 | if (ArchNames.size() > 1) { | ||||
1476 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1477 | << "Error generating preprocessed source(s) - cannot generate " | ||||
1478 | "preprocessed source with multiple -arch options."; | ||||
1479 | return; | ||||
1480 | } | ||||
1481 | |||||
1482 | // Construct the list of abstract actions to perform for this compilation. On | ||||
1483 | // Darwin OSes this uses the driver-driver and builds universal actions. | ||||
1484 | const ToolChain &TC = C.getDefaultToolChain(); | ||||
1485 | if (TC.getTriple().isOSBinFormatMachO()) | ||||
1486 | BuildUniversalActions(C, TC, Inputs); | ||||
1487 | else | ||||
1488 | BuildActions(C, C.getArgs(), Inputs, C.getActions()); | ||||
1489 | |||||
1490 | BuildJobs(C); | ||||
1491 | |||||
1492 | // If there were errors building the compilation, quit now. | ||||
1493 | if (Trap.hasErrorOccurred()) { | ||||
1494 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1495 | << "Error generating preprocessed source(s)."; | ||||
1496 | return; | ||||
1497 | } | ||||
1498 | |||||
1499 | // Generate preprocessed output. | ||||
1500 | SmallVector<std::pair<int, const Command *>, 4> FailingCommands; | ||||
1501 | C.ExecuteJobs(C.getJobs(), FailingCommands); | ||||
1502 | |||||
1503 | // If any of the preprocessing commands failed, clean up and exit. | ||||
1504 | if (!FailingCommands.empty()) { | ||||
1505 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1506 | << "Error generating preprocessed source(s)."; | ||||
1507 | return; | ||||
1508 | } | ||||
1509 | |||||
1510 | const ArgStringList &TempFiles = C.getTempFiles(); | ||||
1511 | if (TempFiles.empty()) { | ||||
1512 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1513 | << "Error generating preprocessed source(s)."; | ||||
1514 | return; | ||||
1515 | } | ||||
1516 | |||||
1517 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1518 | << "\n********************\n\n" | ||||
1519 | "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n" | ||||
1520 | "Preprocessed source(s) and associated run script(s) are located at:"; | ||||
1521 | |||||
1522 | SmallString<128> VFS; | ||||
1523 | SmallString<128> ReproCrashFilename; | ||||
1524 | for (const char *TempFile : TempFiles) { | ||||
1525 | Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile; | ||||
1526 | if (Report) | ||||
1527 | Report->TemporaryFiles.push_back(TempFile); | ||||
1528 | if (ReproCrashFilename.empty()) { | ||||
1529 | ReproCrashFilename = TempFile; | ||||
1530 | llvm::sys::path::replace_extension(ReproCrashFilename, ".crash"); | ||||
1531 | } | ||||
1532 | if (StringRef(TempFile).endswith(".cache")) { | ||||
1533 | // In some cases (modules) we'll dump extra data to help with reproducing | ||||
1534 | // the crash into a directory next to the output. | ||||
1535 | VFS = llvm::sys::path::filename(TempFile); | ||||
1536 | llvm::sys::path::append(VFS, "vfs", "vfs.yaml"); | ||||
1537 | } | ||||
1538 | } | ||||
1539 | |||||
1540 | // Assume associated files are based off of the first temporary file. | ||||
1541 | CrashReportInfo CrashInfo(TempFiles[0], VFS); | ||||
1542 | |||||
1543 | llvm::SmallString<128> Script(CrashInfo.Filename); | ||||
1544 | llvm::sys::path::replace_extension(Script, "sh"); | ||||
1545 | std::error_code EC; | ||||
1546 | llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew, | ||||
1547 | llvm::sys::fs::FA_Write, | ||||
1548 | llvm::sys::fs::OF_Text); | ||||
1549 | if (EC) { | ||||
1550 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1551 | << "Error generating run script: " << Script << " " << EC.message(); | ||||
1552 | } else { | ||||
1553 | ScriptOS << "# Crash reproducer for " << getClangFullVersion() << "\n" | ||||
1554 | << "# Driver args: "; | ||||
1555 | printArgList(ScriptOS, C.getInputArgs()); | ||||
1556 | ScriptOS << "# Original command: "; | ||||
1557 | Cmd.Print(ScriptOS, "\n", /*Quote=*/true); | ||||
1558 | Cmd.Print(ScriptOS, "\n", /*Quote=*/true, &CrashInfo); | ||||
1559 | if (!AdditionalInformation.empty()) | ||||
1560 | ScriptOS << "\n# Additional information: " << AdditionalInformation | ||||
1561 | << "\n"; | ||||
1562 | if (Report) | ||||
1563 | Report->TemporaryFiles.push_back(std::string(Script.str())); | ||||
1564 | Diag(clang::diag::note_drv_command_failed_diag_msg) << Script; | ||||
1565 | } | ||||
1566 | |||||
1567 | // On darwin, provide information about the .crash diagnostic report. | ||||
1568 | if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) { | ||||
1569 | SmallString<128> CrashDiagDir; | ||||
1570 | if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) { | ||||
1571 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1572 | << ReproCrashFilename.str(); | ||||
1573 | } else { // Suggest a directory for the user to look for .crash files. | ||||
1574 | llvm::sys::path::append(CrashDiagDir, Name); | ||||
1575 | CrashDiagDir += "_<YYYY-MM-DD-HHMMSS>_<hostname>.crash"; | ||||
1576 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1577 | << "Crash backtrace is located in"; | ||||
1578 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1579 | << CrashDiagDir.str(); | ||||
1580 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1581 | << "(choose the .crash file that corresponds to your crash)"; | ||||
1582 | } | ||||
1583 | } | ||||
1584 | |||||
1585 | for (const auto &A : C.getArgs().filtered(options::OPT_frewrite_map_file_EQ)) | ||||
1586 | Diag(clang::diag::note_drv_command_failed_diag_msg) << A->getValue(); | ||||
1587 | |||||
1588 | Diag(clang::diag::note_drv_command_failed_diag_msg) | ||||
1589 | << "\n\n********************"; | ||||
1590 | } | ||||
1591 | |||||
1592 | void Driver::setUpResponseFiles(Compilation &C, Command &Cmd) { | ||||
1593 | // Since commandLineFitsWithinSystemLimits() may underestimate system's | ||||
1594 | // capacity if the tool does not support response files, there is a chance/ | ||||
1595 | // that things will just work without a response file, so we silently just | ||||
1596 | // skip it. | ||||
1597 | if (Cmd.getResponseFileSupport().ResponseKind == | ||||
1598 | ResponseFileSupport::RF_None || | ||||
1599 | llvm::sys::commandLineFitsWithinSystemLimits(Cmd.getExecutable(), | ||||
1600 | Cmd.getArguments())) | ||||
1601 | return; | ||||
1602 | |||||
1603 | std::string TmpName = GetTemporaryPath("response", "txt"); | ||||
1604 | Cmd.setResponseFile(C.addTempFile(C.getArgs().MakeArgString(TmpName))); | ||||
1605 | } | ||||
1606 | |||||
1607 | int Driver::ExecuteCompilation( | ||||
1608 | Compilation &C, | ||||
1609 | SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) { | ||||
1610 | // Just print if -### was present. | ||||
1611 | if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) { | ||||
1612 | C.getJobs().Print(llvm::errs(), "\n", true); | ||||
1613 | return 0; | ||||
1614 | } | ||||
1615 | |||||
1616 | // If there were errors building the compilation, quit now. | ||||
1617 | if (Diags.hasErrorOccurred()) | ||||
1618 | return 1; | ||||
1619 | |||||
1620 | // Set up response file names for each command, if necessary. | ||||
1621 | for (auto &Job : C.getJobs()) | ||||
1622 | setUpResponseFiles(C, Job); | ||||
1623 | |||||
1624 | C.ExecuteJobs(C.getJobs(), FailingCommands); | ||||
1625 | |||||
1626 | // If the command succeeded, we are done. | ||||
1627 | if (FailingCommands.empty()) | ||||
1628 | return 0; | ||||
1629 | |||||
1630 | // Otherwise, remove result files and print extra information about abnormal | ||||
1631 | // failures. | ||||
1632 | int Res = 0; | ||||
1633 | for (const auto &CmdPair : FailingCommands) { | ||||
1634 | int CommandRes = CmdPair.first; | ||||
1635 | const Command *FailingCommand = CmdPair.second; | ||||
1636 | |||||
1637 | // Remove result files if we're not saving temps. | ||||
1638 | if (!isSaveTempsEnabled()) { | ||||
1639 | const JobAction *JA = cast<JobAction>(&FailingCommand->getSource()); | ||||
1640 | C.CleanupFileMap(C.getResultFiles(), JA, true); | ||||
1641 | |||||
1642 | // Failure result files are valid unless we crashed. | ||||
1643 | if (CommandRes < 0) | ||||
1644 | C.CleanupFileMap(C.getFailureResultFiles(), JA, true); | ||||
1645 | } | ||||
1646 | |||||
1647 | #if LLVM_ON_UNIX1 | ||||
1648 | // llvm/lib/Support/Unix/Signals.inc will exit with a special return code | ||||
1649 | // for SIGPIPE. Do not print diagnostics for this case. | ||||
1650 | if (CommandRes == EX_IOERR74) { | ||||
1651 | Res = CommandRes; | ||||
1652 | continue; | ||||
1653 | } | ||||
1654 | #endif | ||||
1655 | |||||
1656 | // Print extra information about abnormal failures, if possible. | ||||
1657 | // | ||||
1658 | // This is ad-hoc, but we don't want to be excessively noisy. If the result | ||||
1659 | // status was 1, assume the command failed normally. In particular, if it | ||||
1660 | // was the compiler then assume it gave a reasonable error code. Failures | ||||
1661 | // in other tools are less common, and they generally have worse | ||||
1662 | // diagnostics, so always print the diagnostic there. | ||||
1663 | const Tool &FailingTool = FailingCommand->getCreator(); | ||||
1664 | |||||
1665 | if (!FailingCommand->getCreator().hasGoodDiagnostics() || CommandRes != 1) { | ||||
1666 | // FIXME: See FIXME above regarding result code interpretation. | ||||
1667 | if (CommandRes < 0) | ||||
1668 | Diag(clang::diag::err_drv_command_signalled) | ||||
1669 | << FailingTool.getShortName(); | ||||
1670 | else | ||||
1671 | Diag(clang::diag::err_drv_command_failed) | ||||
1672 | << FailingTool.getShortName() << CommandRes; | ||||
1673 | } | ||||
1674 | } | ||||
1675 | return Res; | ||||
1676 | } | ||||
1677 | |||||
1678 | void Driver::PrintHelp(bool ShowHidden) const { | ||||
1679 | unsigned IncludedFlagsBitmask; | ||||
1680 | unsigned ExcludedFlagsBitmask; | ||||
1681 | std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) = | ||||
1682 | getIncludeExcludeOptionFlagMasks(IsCLMode()); | ||||
1683 | |||||
1684 | ExcludedFlagsBitmask |= options::NoDriverOption; | ||||
1685 | if (!ShowHidden) | ||||
1686 | ExcludedFlagsBitmask |= HelpHidden; | ||||
1687 | |||||
1688 | if (IsFlangMode()) | ||||
1689 | IncludedFlagsBitmask |= options::FlangOption; | ||||
1690 | else | ||||
1691 | ExcludedFlagsBitmask |= options::FlangOnlyOption; | ||||
1692 | |||||
1693 | std::string Usage = llvm::formatv("{0} [options] file...", Name).str(); | ||||
1694 | getOpts().printHelp(llvm::outs(), Usage.c_str(), DriverTitle.c_str(), | ||||
1695 | IncludedFlagsBitmask, ExcludedFlagsBitmask, | ||||
1696 | /*ShowAllAliases=*/false); | ||||
1697 | } | ||||
1698 | |||||
1699 | void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const { | ||||
1700 | if (IsFlangMode()) { | ||||
1701 | OS << getClangToolFullVersion("flang-new") << '\n'; | ||||
1702 | } else { | ||||
1703 | // FIXME: The following handlers should use a callback mechanism, we don't | ||||
1704 | // know what the client would like to do. | ||||
1705 | OS << getClangFullVersion() << '\n'; | ||||
1706 | } | ||||
1707 | const ToolChain &TC = C.getDefaultToolChain(); | ||||
1708 | OS << "Target: " << TC.getTripleString() << '\n'; | ||||
1709 | |||||
1710 | // Print the threading model. | ||||
1711 | if (Arg *A = C.getArgs().getLastArg(options::OPT_mthread_model)) { | ||||
1712 | // Don't print if the ToolChain would have barfed on it already | ||||
1713 | if (TC.isThreadModelSupported(A->getValue())) | ||||
1714 | OS << "Thread model: " << A->getValue(); | ||||
1715 | } else | ||||
1716 | OS << "Thread model: " << TC.getThreadModel(); | ||||
1717 | OS << '\n'; | ||||
1718 | |||||
1719 | // Print out the install directory. | ||||
1720 | OS << "InstalledDir: " << InstalledDir << '\n'; | ||||
1721 | |||||
1722 | // If configuration file was used, print its path. | ||||
1723 | if (!ConfigFile.empty()) | ||||
1724 | OS << "Configuration file: " << ConfigFile << '\n'; | ||||
1725 | } | ||||
1726 | |||||
1727 | /// PrintDiagnosticCategories - Implement the --print-diagnostic-categories | ||||
1728 | /// option. | ||||
1729 | static void PrintDiagnosticCategories(raw_ostream &OS) { | ||||
1730 | // Skip the empty category. | ||||
1731 | for (unsigned i = 1, max = DiagnosticIDs::getNumberOfCategories(); i != max; | ||||
1732 | ++i) | ||||
1733 | OS << i << ',' << DiagnosticIDs::getCategoryNameFromID(i) << '\n'; | ||||
1734 | } | ||||
1735 | |||||
1736 | void Driver::HandleAutocompletions(StringRef PassedFlags) const { | ||||
1737 | if (PassedFlags == "") | ||||
1738 | return; | ||||
1739 | // Print out all options that start with a given argument. This is used for | ||||
1740 | // shell autocompletion. | ||||
1741 | std::vector<std::string> SuggestedCompletions; | ||||
1742 | std::vector<std::string> Flags; | ||||
1743 | |||||
1744 | unsigned int DisableFlags = | ||||
1745 | options::NoDriverOption | options::Unsupported | options::Ignored; | ||||
1746 | |||||
1747 | // Make sure that Flang-only options don't pollute the Clang output | ||||
1748 | // TODO: Make sure that Clang-only options don't pollute Flang output | ||||
1749 | if (!IsFlangMode()) | ||||
1750 | DisableFlags |= options::FlangOnlyOption; | ||||
1751 | |||||
1752 | // Distinguish "--autocomplete=-someflag" and "--autocomplete=-someflag," | ||||
1753 | // because the latter indicates that the user put space before pushing tab | ||||
1754 | // which should end up in a file completion. | ||||
1755 | const bool HasSpace = PassedFlags.endswith(","); | ||||
1756 | |||||
1757 | // Parse PassedFlags by "," as all the command-line flags are passed to this | ||||
1758 | // function separated by "," | ||||
1759 | StringRef TargetFlags = PassedFlags; | ||||
1760 | while (TargetFlags != "") { | ||||
1761 | StringRef CurFlag; | ||||
1762 | std::tie(CurFlag, TargetFlags) = TargetFlags.split(","); | ||||
1763 | Flags.push_back(std::string(CurFlag)); | ||||
1764 | } | ||||
1765 | |||||
1766 | // We want to show cc1-only options only when clang is invoked with -cc1 or | ||||
1767 | // -Xclang. | ||||
1768 | if (llvm::is_contained(Flags, "-Xclang") || llvm::is_contained(Flags, "-cc1")) | ||||
1769 | DisableFlags &= ~options::NoDriverOption; | ||||
1770 | |||||
1771 | const llvm::opt::OptTable &Opts = getOpts(); | ||||
1772 | StringRef Cur; | ||||
1773 | Cur = Flags.at(Flags.size() - 1); | ||||
1774 | StringRef Prev; | ||||
1775 | if (Flags.size() >= 2) { | ||||
1776 | Prev = Flags.at(Flags.size() - 2); | ||||
1777 | SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur); | ||||
1778 | } | ||||
1779 | |||||
1780 | if (SuggestedCompletions.empty()) | ||||
1781 | SuggestedCompletions = Opts.suggestValueCompletions(Cur, ""); | ||||
1782 | |||||
1783 | // If Flags were empty, it means the user typed `clang [tab]` where we should | ||||
1784 | // list all possible flags. If there was no value completion and the user | ||||
1785 | // pressed tab after a space, we should fall back to a file completion. | ||||
1786 | // We're printing a newline to be consistent with what we print at the end of | ||||
1787 | // this function. | ||||
1788 | if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) { | ||||
1789 | llvm::outs() << '\n'; | ||||
1790 | return; | ||||
1791 | } | ||||
1792 | |||||
1793 | // When flag ends with '=' and there was no value completion, return empty | ||||
1794 | // string and fall back to the file autocompletion. | ||||
1795 | if (SuggestedCompletions.empty() && !Cur.endswith("=")) { | ||||
1796 | // If the flag is in the form of "--autocomplete=-foo", | ||||
1797 | // we were requested to print out all option names that start with "-foo". | ||||
1798 | // For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only". | ||||
1799 | SuggestedCompletions = Opts.findByPrefix(Cur, DisableFlags); | ||||
1800 | |||||
1801 | // We have to query the -W flags manually as they're not in the OptTable. | ||||
1802 | // TODO: Find a good way to add them to OptTable instead and them remove | ||||
1803 | // this code. | ||||
1804 | for (StringRef S : DiagnosticIDs::getDiagnosticFlags()) | ||||
1805 | if (S.startswith(Cur)) | ||||
1806 | SuggestedCompletions.push_back(std::string(S)); | ||||
1807 | } | ||||
1808 | |||||
1809 | // Sort the autocomplete candidates so that shells print them out in a | ||||
1810 | // deterministic order. We could sort in any way, but we chose | ||||
1811 | // case-insensitive sorting for consistency with the -help option | ||||
1812 | // which prints out options in the case-insensitive alphabetical order. | ||||
1813 | llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) { | ||||
1814 | if (int X = A.compare_insensitive(B)) | ||||
1815 | return X < 0; | ||||
1816 | return A.compare(B) > 0; | ||||
1817 | }); | ||||
1818 | |||||
1819 | llvm::outs() << llvm::join(SuggestedCompletions, "\n") << '\n'; | ||||
1820 | } | ||||
1821 | |||||
1822 | bool Driver::HandleImmediateArgs(const Compilation &C) { | ||||
1823 | // The order these options are handled in gcc is all over the place, but we | ||||
1824 | // don't expect inconsistencies w.r.t. that to matter in practice. | ||||
1825 | |||||
1826 | if (C.getArgs().hasArg(options::OPT_dumpmachine)) { | ||||
1827 | llvm::outs() << C.getDefaultToolChain().getTripleString() << '\n'; | ||||
1828 | return false; | ||||
1829 | } | ||||
1830 | |||||
1831 | if (C.getArgs().hasArg(options::OPT_dumpversion)) { | ||||
1832 | // Since -dumpversion is only implemented for pedantic GCC compatibility, we | ||||
1833 | // return an answer which matches our definition of __VERSION__. | ||||
1834 | llvm::outs() << CLANG_VERSION_STRING"15.0.0" << "\n"; | ||||
1835 | return false; | ||||
1836 | } | ||||
1837 | |||||
1838 | if (C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) { | ||||
1839 | PrintDiagnosticCategories(llvm::outs()); | ||||
1840 | return false; | ||||
1841 | } | ||||
1842 | |||||
1843 | if (C.getArgs().hasArg(options::OPT_help) || | ||||
1844 | C.getArgs().hasArg(options::OPT__help_hidden)) { | ||||
1845 | PrintHelp(C.getArgs().hasArg(options::OPT__help_hidden)); | ||||
1846 | return false; | ||||
1847 | } | ||||
1848 | |||||
1849 | if (C.getArgs().hasArg(options::OPT__version)) { | ||||
1850 | // Follow gcc behavior and use stdout for --version and stderr for -v. | ||||
1851 | PrintVersion(C, llvm::outs()); | ||||
1852 | return false; | ||||
1853 | } | ||||
1854 | |||||
1855 | if (C.getArgs().hasArg(options::OPT_v) || | ||||
1856 | C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) || | ||||
1857 | C.getArgs().hasArg(options::OPT_print_supported_cpus)) { | ||||
1858 | PrintVersion(C, llvm::errs()); | ||||
1859 | SuppressMissingInputWarning = true; | ||||
1860 | } | ||||
1861 | |||||
1862 | if (C.getArgs().hasArg(options::OPT_v)) { | ||||
1863 | if (!SystemConfigDir.empty()) | ||||
1864 | llvm::errs() << "System configuration file directory: " | ||||
1865 | << SystemConfigDir << "\n"; | ||||
1866 | if (!UserConfigDir.empty()) | ||||
1867 | llvm::errs() << "User configuration file directory: " | ||||
1868 | << UserConfigDir << "\n"; | ||||
1869 | } | ||||
1870 | |||||
1871 | const ToolChain &TC = C.getDefaultToolChain(); | ||||
1872 | |||||
1873 | if (C.getArgs().hasArg(options::OPT_v)) | ||||
1874 | TC.printVerboseInfo(llvm::errs()); | ||||
1875 | |||||
1876 | if (C.getArgs().hasArg(options::OPT_print_resource_dir)) { | ||||
1877 | llvm::outs() << ResourceDir << '\n'; | ||||
1878 | return false; | ||||
1879 | } | ||||
1880 | |||||
1881 | if (C.getArgs().hasArg(options::OPT_print_search_dirs)) { | ||||
1882 | llvm::outs() << "programs: ="; | ||||
1883 | bool separator = false; | ||||
1884 | // Print -B and COMPILER_PATH. | ||||
1885 | for (const std::string &Path : PrefixDirs) { | ||||
1886 | if (separator) | ||||
1887 | llvm::outs() << llvm::sys::EnvPathSeparator; | ||||
1888 | llvm::outs() << Path; | ||||
1889 | separator = true; | ||||
1890 | } | ||||
1891 | for (const std::string &Path : TC.getProgramPaths()) { | ||||
1892 | if (separator) | ||||
1893 | llvm::outs() << llvm::sys::EnvPathSeparator; | ||||
1894 | llvm::outs() << Path; | ||||
1895 | separator = true; | ||||
1896 | } | ||||
1897 | llvm::outs() << "\n"; | ||||
1898 | llvm::outs() << "libraries: =" << ResourceDir; | ||||
1899 | |||||
1900 | StringRef sysroot = C.getSysRoot(); | ||||
1901 | |||||
1902 | for (const std::string &Path : TC.getFilePaths()) { | ||||
1903 | // Always print a separator. ResourceDir was the first item shown. | ||||
1904 | llvm::outs() << llvm::sys::EnvPathSeparator; | ||||
1905 | // Interpretation of leading '=' is needed only for NetBSD. | ||||
1906 | if (Path[0] == '=') | ||||
1907 | llvm::outs() << sysroot << Path.substr(1); | ||||
1908 | else | ||||
1909 | llvm::outs() << Path; | ||||
1910 | } | ||||
1911 | llvm::outs() << "\n"; | ||||
1912 | return false; | ||||
1913 | } | ||||
1914 | |||||
1915 | if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) { | ||||
1916 | std::string RuntimePath; | ||||
1917 | // Get the first existing path, if any. | ||||
1918 | for (auto Path : TC.getRuntimePaths()) { | ||||
1919 | if (getVFS().exists(Path)) { | ||||
1920 | RuntimePath = Path; | ||||
1921 | break; | ||||
1922 | } | ||||
1923 | } | ||||
1924 | if (!RuntimePath.empty()) | ||||
1925 | llvm::outs() << RuntimePath << '\n'; | ||||
1926 | else | ||||
1927 | llvm::outs() << TC.getCompilerRTPath() << '\n'; | ||||
1928 | return false; | ||||
1929 | } | ||||
1930 | |||||
1931 | // FIXME: The following handlers should use a callback mechanism, we don't | ||||
1932 | // know what the client would like to do. | ||||
1933 | if (Arg *A = C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) { | ||||
1934 | llvm::outs() << GetFilePath(A->getValue(), TC) << "\n"; | ||||
1935 | return false; | ||||
1936 | } | ||||
1937 | |||||
1938 | if (Arg *A = C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) { | ||||
1939 | StringRef ProgName = A->getValue(); | ||||
1940 | |||||
1941 | // Null program name cannot have a path. | ||||
1942 | if (! ProgName.empty()) | ||||
1943 | llvm::outs() << GetProgramPath(ProgName, TC); | ||||
1944 | |||||
1945 | llvm::outs() << "\n"; | ||||
1946 | return false; | ||||
1947 | } | ||||
1948 | |||||
1949 | if (Arg *A = C.getArgs().getLastArg(options::OPT_autocomplete)) { | ||||
1950 | StringRef PassedFlags = A->getValue(); | ||||
1951 | HandleAutocompletions(PassedFlags); | ||||
1952 | return false; | ||||
1953 | } | ||||
1954 | |||||
1955 | if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) { | ||||
1956 | ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(C.getArgs()); | ||||
1957 | const llvm::Triple Triple(TC.ComputeEffectiveClangTriple(C.getArgs())); | ||||
1958 | RegisterEffectiveTriple TripleRAII(TC, Triple); | ||||
1959 | switch (RLT) { | ||||
1960 | case ToolChain::RLT_CompilerRT: | ||||
1961 | llvm::outs() << TC.getCompilerRT(C.getArgs(), "builtins") << "\n"; | ||||
1962 | break; | ||||
1963 | case ToolChain::RLT_Libgcc: | ||||
1964 | llvm::outs() << GetFilePath("libgcc.a", TC) << "\n"; | ||||
1965 | break; | ||||
1966 | } | ||||
1967 | return false; | ||||
1968 | } | ||||
1969 | |||||
1970 | if (C.getArgs().hasArg(options::OPT_print_multi_lib)) { | ||||
1971 | for (const Multilib &Multilib : TC.getMultilibs()) | ||||
1972 | llvm::outs() << Multilib << "\n"; | ||||
1973 | return false; | ||||
1974 | } | ||||
1975 | |||||
1976 | if (C.getArgs().hasArg(options::OPT_print_multi_directory)) { | ||||
1977 | const Multilib &Multilib = TC.getMultilib(); | ||||
1978 | if (Multilib.gccSuffix().empty()) | ||||
1979 | llvm::outs() << ".\n"; | ||||
1980 | else { | ||||
1981 | StringRef Suffix(Multilib.gccSuffix()); | ||||
1982 | assert(Suffix.front() == '/')(static_cast <bool> (Suffix.front() == '/') ? void (0) : __assert_fail ("Suffix.front() == '/'", "clang/lib/Driver/Driver.cpp" , 1982, __extension__ __PRETTY_FUNCTION__)); | ||||
1983 | llvm::outs() << Suffix.substr(1) << "\n"; | ||||
1984 | } | ||||
1985 | return false; | ||||
1986 | } | ||||
1987 | |||||
1988 | if (C.getArgs().hasArg(options::OPT_print_target_triple)) { | ||||
1989 | llvm::outs() << TC.getTripleString() << "\n"; | ||||
1990 | return false; | ||||
1991 | } | ||||
1992 | |||||
1993 | if (C.getArgs().hasArg(options::OPT_print_effective_triple)) { | ||||
1994 | const llvm::Triple Triple(TC.ComputeEffectiveClangTriple(C.getArgs())); | ||||
1995 | llvm::outs() << Triple.getTriple() << "\n"; | ||||
1996 | return false; | ||||
1997 | } | ||||
1998 | |||||
1999 | if (C.getArgs().hasArg(options::OPT_print_multiarch)) { | ||||
2000 | llvm::outs() << TC.getMultiarchTriple(*this, TC.getTriple(), SysRoot) | ||||
2001 | << "\n"; | ||||
2002 | return false; | ||||
2003 | } | ||||
2004 | |||||
2005 | if (C.getArgs().hasArg(options::OPT_print_targets)) { | ||||
2006 | llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs()); | ||||
2007 | return false; | ||||
2008 | } | ||||
2009 | |||||
2010 | return true; | ||||
2011 | } | ||||
2012 | |||||
2013 | enum { | ||||
2014 | TopLevelAction = 0, | ||||
2015 | HeadSibAction = 1, | ||||
2016 | OtherSibAction = 2, | ||||
2017 | }; | ||||
2018 | |||||
2019 | // Display an action graph human-readably. Action A is the "sink" node | ||||
2020 | // and latest-occuring action. Traversal is in pre-order, visiting the | ||||
2021 | // inputs to each action before printing the action itself. | ||||
2022 | static unsigned PrintActions1(const Compilation &C, Action *A, | ||||
2023 | std::map<Action *, unsigned> &Ids, | ||||
2024 | Twine Indent = {}, int Kind = TopLevelAction) { | ||||
2025 | if (Ids.count(A)) // A was already visited. | ||||
2026 | return Ids[A]; | ||||
2027 | |||||
2028 | std::string str; | ||||
2029 | llvm::raw_string_ostream os(str); | ||||
2030 | |||||
2031 | auto getSibIndent = [](int K) -> Twine { | ||||
2032 | return (K == HeadSibAction) ? " " : (K == OtherSibAction) ? "| " : ""; | ||||
2033 | }; | ||||
2034 | |||||
2035 | Twine SibIndent = Indent + getSibIndent(Kind); | ||||
2036 | int SibKind = HeadSibAction; | ||||
2037 | os << Action::getClassName(A->getKind()) << ", "; | ||||
2038 | if (InputAction *IA = dyn_cast<InputAction>(A)) { | ||||
2039 | os << "\"" << IA->getInputArg().getValue() << "\""; | ||||
2040 | } else if (BindArchAction *BIA = dyn_cast<BindArchAction>(A)) { | ||||
2041 | os << '"' << BIA->getArchName() << '"' << ", {" | ||||
2042 | << PrintActions1(C, *BIA->input_begin(), Ids, SibIndent, SibKind) << "}"; | ||||
2043 | } else if (OffloadAction *OA = dyn_cast<OffloadAction>(A)) { | ||||
2044 | bool IsFirst = true; | ||||
2045 | OA->doOnEachDependence( | ||||
2046 | [&](Action *A, const ToolChain *TC, const char *BoundArch) { | ||||
2047 | assert(TC && "Unknown host toolchain")(static_cast <bool> (TC && "Unknown host toolchain" ) ? void (0) : __assert_fail ("TC && \"Unknown host toolchain\"" , "clang/lib/Driver/Driver.cpp", 2047, __extension__ __PRETTY_FUNCTION__ )); | ||||
2048 | // E.g. for two CUDA device dependences whose bound arch is sm_20 and | ||||
2049 | // sm_35 this will generate: | ||||
2050 | // "cuda-device" (nvptx64-nvidia-cuda:sm_20) {#ID}, "cuda-device" | ||||
2051 | // (nvptx64-nvidia-cuda:sm_35) {#ID} | ||||
2052 | if (!IsFirst) | ||||
2053 | os << ", "; | ||||
2054 | os << '"'; | ||||
2055 | os << A->getOffloadingKindPrefix(); | ||||
2056 | os << " ("; | ||||
2057 | os << TC->getTriple().normalize(); | ||||
2058 | if (BoundArch) | ||||
2059 | os << ":" << BoundArch; | ||||
2060 | os << ")"; | ||||
2061 | os << '"'; | ||||
2062 | os << " {" << PrintActions1(C, A, Ids, SibIndent, SibKind) << "}"; | ||||
2063 | IsFirst = false; | ||||
2064 | SibKind = OtherSibAction; | ||||
2065 | }); | ||||
2066 | } else { | ||||
2067 | const ActionList *AL = &A->getInputs(); | ||||
2068 | |||||
2069 | if (AL->size()) { | ||||
2070 | const char *Prefix = "{"; | ||||
2071 | for (Action *PreRequisite : *AL) { | ||||
2072 | os << Prefix << PrintActions1(C, PreRequisite, Ids, SibIndent, SibKind); | ||||
2073 | Prefix = ", "; | ||||
2074 | SibKind = OtherSibAction; | ||||
2075 | } | ||||
2076 | os << "}"; | ||||
2077 | } else | ||||
2078 | os << "{}"; | ||||
2079 | } | ||||
2080 | |||||
2081 | // Append offload info for all options other than the offloading action | ||||
2082 | // itself (e.g. (cuda-device, sm_20) or (cuda-host)). | ||||
2083 | std::string offload_str; | ||||
2084 | llvm::raw_string_ostream offload_os(offload_str); | ||||
2085 | if (!isa<OffloadAction>(A)) { | ||||
2086 | auto S = A->getOffloadingKindPrefix(); | ||||
2087 | if (!S.empty()) { | ||||
2088 | offload_os << ", (" << S; | ||||
2089 | if (A->getOffloadingArch()) | ||||
2090 | offload_os << ", " << A->getOffloadingArch(); | ||||
2091 | offload_os << ")"; | ||||
2092 | } | ||||
2093 | } | ||||
2094 | |||||
2095 | auto getSelfIndent = [](int K) -> Twine { | ||||
2096 | return (K == HeadSibAction) ? "+- " : (K == OtherSibAction) ? "|- " : ""; | ||||
2097 | }; | ||||
2098 | |||||
2099 | unsigned Id = Ids.size(); | ||||
2100 | Ids[A] = Id; | ||||
2101 | llvm::errs() << Indent + getSelfIndent(Kind) << Id << ": " << os.str() << ", " | ||||
2102 | << types::getTypeName(A->getType()) << offload_os.str() << "\n"; | ||||
2103 | |||||
2104 | return Id; | ||||
2105 | } | ||||
2106 | |||||
2107 | // Print the action graphs in a compilation C. | ||||
2108 | // For example "clang -c file1.c file2.c" is composed of two subgraphs. | ||||
2109 | void Driver::PrintActions(const Compilation &C) const { | ||||
2110 | std::map<Action *, unsigned> Ids; | ||||
2111 | for (Action *A : C.getActions()) | ||||
2112 | PrintActions1(C, A, Ids); | ||||
2113 | } | ||||
2114 | |||||
2115 | /// Check whether the given input tree contains any compilation or | ||||
2116 | /// assembly actions. | ||||
2117 | static bool ContainsCompileOrAssembleAction(const Action *A) { | ||||
2118 | if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) || | ||||
2119 | isa<AssembleJobAction>(A)) | ||||
2120 | return true; | ||||
2121 | |||||
2122 | return llvm::any_of(A->inputs(), ContainsCompileOrAssembleAction); | ||||
2123 | } | ||||
2124 | |||||
2125 | void Driver::BuildUniversalActions(Compilation &C, const ToolChain &TC, | ||||
2126 | const InputList &BAInputs) const { | ||||
2127 | DerivedArgList &Args = C.getArgs(); | ||||
2128 | ActionList &Actions = C.getActions(); | ||||
2129 | llvm::PrettyStackTraceString CrashInfo("Building universal build actions"); | ||||
2130 | // Collect the list of architectures. Duplicates are allowed, but should only | ||||
2131 | // be handled once (in the order seen). | ||||
2132 | llvm::StringSet<> ArchNames; | ||||
2133 | SmallVector<const char *, 4> Archs; | ||||
2134 | for (Arg *A : Args) { | ||||
2135 | if (A->getOption().matches(options::OPT_arch)) { | ||||
2136 | // Validate the option here; we don't save the type here because its | ||||
2137 | // particular spelling may participate in other driver choices. | ||||
2138 | llvm::Triple::ArchType Arch = | ||||
2139 | tools::darwin::getArchTypeForMachOArchName(A->getValue()); | ||||
2140 | if (Arch == llvm::Triple::UnknownArch) { | ||||
2141 | Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args); | ||||
2142 | continue; | ||||
2143 | } | ||||
2144 | |||||
2145 | A->claim(); | ||||
2146 | if (ArchNames.insert(A->getValue()).second) | ||||
2147 | Archs.push_back(A->getValue()); | ||||
2148 | } | ||||
2149 | } | ||||
2150 | |||||
2151 | // When there is no explicit arch for this platform, make sure we still bind | ||||
2152 | // the architecture (to the default) so that -Xarch_ is handled correctly. | ||||
2153 | if (!Archs.size()) | ||||
2154 | Archs.push_back(Args.MakeArgString(TC.getDefaultUniversalArchName())); | ||||
2155 | |||||
2156 | ActionList SingleActions; | ||||
2157 | BuildActions(C, Args, BAInputs, SingleActions); | ||||
2158 | |||||
2159 | // Add in arch bindings for every top level action, as well as lipo and | ||||
2160 | // dsymutil steps if needed. | ||||
2161 | for (Action* Act : SingleActions) { | ||||
2162 | // Make sure we can lipo this kind of output. If not (and it is an actual | ||||
2163 | // output) then we disallow, since we can't create an output file with the | ||||
2164 | // right name without overwriting it. We could remove this oddity by just | ||||
2165 | // changing the output names to include the arch, which would also fix | ||||
2166 | // -save-temps. Compatibility wins for now. | ||||
2167 | |||||
2168 | if (Archs.size() > 1 && !types::canLipoType(Act->getType())) | ||||
2169 | Diag(clang::diag::err_drv_invalid_output_with_multiple_archs) | ||||
2170 | << types::getTypeName(Act->getType()); | ||||
2171 | |||||
2172 | ActionList Inputs; | ||||
2173 | for (unsigned i = 0, e = Archs.size(); i != e; ++i) | ||||
2174 | Inputs.push_back(C.MakeAction<BindArchAction>(Act, Archs[i])); | ||||
2175 | |||||
2176 | // Lipo if necessary, we do it this way because we need to set the arch flag | ||||
2177 | // so that -Xarch_ gets overwritten. | ||||
2178 | if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing) | ||||
2179 | Actions.append(Inputs.begin(), Inputs.end()); | ||||
2180 | else | ||||
2181 | Actions.push_back(C.MakeAction<LipoJobAction>(Inputs, Act->getType())); | ||||
2182 | |||||
2183 | // Handle debug info queries. | ||||
2184 | Arg *A = Args.getLastArg(options::OPT_g_Group); | ||||
2185 | bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) && | ||||
2186 | !A->getOption().matches(options::OPT_gstabs); | ||||
2187 | if ((enablesDebugInfo || willEmitRemarks(Args)) && | ||||
2188 | ContainsCompileOrAssembleAction(Actions.back())) { | ||||
2189 | |||||
2190 | // Add a 'dsymutil' step if necessary, when debug info is enabled and we | ||||
2191 | // have a compile input. We need to run 'dsymutil' ourselves in such cases | ||||
2192 | // because the debug info will refer to a temporary object file which | ||||
2193 | // will be removed at the end of the compilation process. | ||||
2194 | if (Act->getType() == types::TY_Image) { | ||||
2195 | ActionList Inputs; | ||||
2196 | Inputs.push_back(Actions.back()); | ||||
2197 | Actions.pop_back(); | ||||
2198 | Actions.push_back( | ||||
2199 | C.MakeAction<DsymutilJobAction>(Inputs, types::TY_dSYM)); | ||||
2200 | } | ||||
2201 | |||||
2202 | // Verify the debug info output. | ||||
2203 | if (Args.hasArg(options::OPT_verify_debug_info)) { | ||||
2204 | Action* LastAction = Actions.back(); | ||||
2205 | Actions.pop_back(); | ||||
2206 | Actions.push_back(C.MakeAction<VerifyDebugInfoJobAction>( | ||||
2207 | LastAction, types::TY_Nothing)); | ||||
2208 | } | ||||
2209 | } | ||||
2210 | } | ||||
2211 | } | ||||
2212 | |||||
2213 | bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value, | ||||
2214 | types::ID Ty, bool TypoCorrect) const { | ||||
2215 | if (!getCheckInputsExist()) | ||||
2216 | return true; | ||||
2217 | |||||
2218 | // stdin always exists. | ||||
2219 | if (Value == "-") | ||||
2220 | return true; | ||||
2221 | |||||
2222 | if (getVFS().exists(Value)) | ||||
2223 | return true; | ||||
2224 | |||||
2225 | if (TypoCorrect) { | ||||
2226 | // Check if the filename is a typo for an option flag. OptTable thinks | ||||
2227 | // that all args that are not known options and that start with / are | ||||
2228 | // filenames, but e.g. `/diagnostic:caret` is more likely a typo for | ||||
2229 | // the option `/diagnostics:caret` than a reference to a file in the root | ||||
2230 | // directory. | ||||
2231 | unsigned IncludedFlagsBitmask; | ||||
2232 | unsigned ExcludedFlagsBitmask; | ||||
2233 | std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) = | ||||
2234 | getIncludeExcludeOptionFlagMasks(IsCLMode()); | ||||
2235 | std::string Nearest; | ||||
2236 | if (getOpts().findNearest(Value, Nearest, IncludedFlagsBitmask, | ||||
2237 | ExcludedFlagsBitmask) <= 1) { | ||||
2238 | Diag(clang::diag::err_drv_no_such_file_with_suggestion) | ||||
2239 | << Value << Nearest; | ||||
2240 | return false; | ||||
2241 | } | ||||
2242 | } | ||||
2243 | |||||
2244 | // In CL mode, don't error on apparently non-existent linker inputs, because | ||||
2245 | // they can be influenced by linker flags the clang driver might not | ||||
2246 | // understand. | ||||
2247 | // Examples: | ||||
2248 | // - `clang-cl main.cc ole32.lib` in a a non-MSVC shell will make the driver | ||||
2249 | // module look for an MSVC installation in the registry. (We could ask | ||||
2250 | // the MSVCToolChain object if it can find `ole32.lib`, but the logic to | ||||
2251 | // look in the registry might move into lld-link in the future so that | ||||
2252 | // lld-link invocations in non-MSVC shells just work too.) | ||||
2253 | // - `clang-cl ... /link ...` can pass arbitrary flags to the linker, | ||||
2254 | // including /libpath:, which is used to find .lib and .obj files. | ||||
2255 | // So do not diagnose this on the driver level. Rely on the linker diagnosing | ||||
2256 | // it. (If we don't end up invoking the linker, this means we'll emit a | ||||
2257 | // "'linker' input unused [-Wunused-command-line-argument]" warning instead | ||||
2258 | // of an error.) | ||||
2259 | // | ||||
2260 | // Only do this skip after the typo correction step above. `/Brepo` is treated | ||||
2261 | // as TY_Object, but it's clearly a typo for `/Brepro`. It seems fine to emit | ||||
2262 | // an error if we have a flag that's within an edit distance of 1 from a | ||||
2263 | // flag. (Users can use `-Wl,` or `/linker` to launder the flag past the | ||||
2264 | // driver in the unlikely case they run into this.) | ||||
2265 | // | ||||
2266 | // Don't do this for inputs that start with a '/', else we'd pass options | ||||
2267 | // like /libpath: through to the linker silently. | ||||
2268 | // | ||||
2269 | // Emitting an error for linker inputs can also cause incorrect diagnostics | ||||
2270 | // with the gcc driver. The command | ||||
2271 | // clang -fuse-ld=lld -Wl,--chroot,some/dir /file.o | ||||
2272 | // will make lld look for some/dir/file.o, while we will diagnose here that | ||||
2273 | // `/file.o` does not exist. However, configure scripts check if | ||||
2274 | // `clang /GR-` compiles without error to see if the compiler is cl.exe, | ||||
2275 | // so we can't downgrade diagnostics for `/GR-` from an error to a warning | ||||
2276 | // in cc mode. (We can in cl mode because cl.exe itself only warns on | ||||
2277 | // unknown flags.) | ||||
2278 | if (IsCLMode() && Ty == types::TY_Object && !Value.startswith("/")) | ||||
2279 | return true; | ||||
2280 | |||||
2281 | Diag(clang::diag::err_drv_no_such_file) << Value; | ||||
2282 | return false; | ||||
2283 | } | ||||
2284 | |||||
2285 | // Construct a the list of inputs and their types. | ||||
2286 | void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, | ||||
2287 | InputList &Inputs) const { | ||||
2288 | const llvm::opt::OptTable &Opts = getOpts(); | ||||
2289 | // Track the current user specified (-x) input. We also explicitly track the | ||||
2290 | // argument used to set the type; we only want to claim the type when we | ||||
2291 | // actually use it, so we warn about unused -x arguments. | ||||
2292 | types::ID InputType = types::TY_Nothing; | ||||
2293 | Arg *InputTypeArg = nullptr; | ||||
2294 | |||||
2295 | // The last /TC or /TP option sets the input type to C or C++ globally. | ||||
2296 | if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC, | ||||
2297 | options::OPT__SLASH_TP)) { | ||||
2298 | InputTypeArg = TCTP; | ||||
2299 | InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) | ||||
2300 | ? types::TY_C | ||||
2301 | : types::TY_CXX; | ||||
2302 | |||||
2303 | Arg *Previous = nullptr; | ||||
2304 | bool ShowNote = false; | ||||
2305 | for (Arg *A : | ||||
2306 | Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) { | ||||
2307 | if (Previous) { | ||||
2308 | Diag(clang::diag::warn_drv_overriding_flag_option) | ||||
2309 | << Previous->getSpelling() << A->getSpelling(); | ||||
2310 | ShowNote = true; | ||||
2311 | } | ||||
2312 | Previous = A; | ||||
2313 | } | ||||
2314 | if (ShowNote) | ||||
2315 | Diag(clang::diag::note_drv_t_option_is_global); | ||||
2316 | |||||
2317 | // No driver mode exposes -x and /TC or /TP; we don't support mixing them. | ||||
2318 | assert(!Args.hasArg(options::OPT_x) && "-x and /TC or /TP is not allowed")(static_cast <bool> (!Args.hasArg(options::OPT_x) && "-x and /TC or /TP is not allowed") ? void (0) : __assert_fail ("!Args.hasArg(options::OPT_x) && \"-x and /TC or /TP is not allowed\"" , "clang/lib/Driver/Driver.cpp", 2318, __extension__ __PRETTY_FUNCTION__ )); | ||||
2319 | } | ||||
2320 | |||||
2321 | // Warn -x after last input file has no effect | ||||
2322 | { | ||||
2323 | Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x); | ||||
2324 | Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT); | ||||
2325 | if (LastXArg && LastInputArg && LastInputArg->getIndex() < LastXArg->getIndex()) | ||||
2326 | Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue(); | ||||
2327 | } | ||||
2328 | |||||
2329 | for (Arg *A : Args) { | ||||
2330 | if (A->getOption().getKind() == Option::InputClass) { | ||||
2331 | const char *Value = A->getValue(); | ||||
2332 | types::ID Ty = types::TY_INVALID; | ||||
2333 | |||||
2334 | // Infer the input type if necessary. | ||||
2335 | if (InputType == types::TY_Nothing) { | ||||
2336 | // If there was an explicit arg for this, claim it. | ||||
2337 | if (InputTypeArg) | ||||
2338 | InputTypeArg->claim(); | ||||
2339 | |||||
2340 | // stdin must be handled specially. | ||||
2341 | if (memcmp(Value, "-", 2) == 0) { | ||||
2342 | if (IsFlangMode()) { | ||||
2343 | Ty = types::TY_Fortran; | ||||
2344 | } else { | ||||
2345 | // If running with -E, treat as a C input (this changes the | ||||
2346 | // builtin macros, for example). This may be overridden by -ObjC | ||||
2347 | // below. | ||||
2348 | // | ||||
2349 | // Otherwise emit an error but still use a valid type to avoid | ||||
2350 | // spurious errors (e.g., no inputs). | ||||
2351 | assert(!CCGenDiagnostics && "stdin produces no crash reproducer")(static_cast <bool> (!CCGenDiagnostics && "stdin produces no crash reproducer" ) ? void (0) : __assert_fail ("!CCGenDiagnostics && \"stdin produces no crash reproducer\"" , "clang/lib/Driver/Driver.cpp", 2351, __extension__ __PRETTY_FUNCTION__ )); | ||||
2352 | if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP()) | ||||
2353 | Diag(IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl | ||||
2354 | : clang::diag::err_drv_unknown_stdin_type); | ||||
2355 | Ty = types::TY_C; | ||||
2356 | } | ||||
2357 | } else { | ||||
2358 | // Otherwise lookup by extension. | ||||
2359 | // Fallback is C if invoked as C preprocessor, C++ if invoked with | ||||
2360 | // clang-cl /E, or Object otherwise. | ||||
2361 | // We use a host hook here because Darwin at least has its own | ||||
2362 | // idea of what .s is. | ||||
2363 | if (const char *Ext = strrchr(Value, '.')) | ||||
2364 | Ty = TC.LookupTypeForExtension(Ext + 1); | ||||
2365 | |||||
2366 | if (Ty == types::TY_INVALID) { | ||||
2367 | if (IsCLMode() && (Args.hasArgNoClaim(options::OPT_E) || CCGenDiagnostics)) | ||||
2368 | Ty = types::TY_CXX; | ||||
2369 | else if (CCCIsCPP() || CCGenDiagnostics) | ||||
2370 | Ty = types::TY_C; | ||||
2371 | else | ||||
2372 | Ty = types::TY_Object; | ||||
2373 | } | ||||
2374 | |||||
2375 | // If the driver is invoked as C++ compiler (like clang++ or c++) it | ||||
2376 | // should autodetect some input files as C++ for g++ compatibility. | ||||
2377 | if (CCCIsCXX()) { | ||||
2378 | types::ID OldTy = Ty; | ||||
2379 | Ty = types::lookupCXXTypeForCType(Ty); | ||||
2380 | |||||
2381 | if (Ty != OldTy) | ||||
2382 | Diag(clang::diag::warn_drv_treating_input_as_cxx) | ||||
2383 | << getTypeName(OldTy) << getTypeName(Ty); | ||||
2384 | } | ||||
2385 | |||||
2386 | // If running with -fthinlto-index=, extensions that normally identify | ||||
2387 | // native object files actually identify LLVM bitcode files. | ||||
2388 | if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) && | ||||
2389 | Ty == types::TY_Object) | ||||
2390 | Ty = types::TY_LLVM_BC; | ||||
2391 | } | ||||
2392 | |||||
2393 | // -ObjC and -ObjC++ override the default language, but only for "source | ||||
2394 | // files". We just treat everything that isn't a linker input as a | ||||
2395 | // source file. | ||||
2396 | // | ||||
2397 | // FIXME: Clean this up if we move the phase sequence into the type. | ||||
2398 | if (Ty != types::TY_Object) { | ||||
2399 | if (Args.hasArg(options::OPT_ObjC)) | ||||
2400 | Ty = types::TY_ObjC; | ||||
2401 | else if (Args.hasArg(options::OPT_ObjCXX)) | ||||
2402 | Ty = types::TY_ObjCXX; | ||||
2403 | } | ||||
2404 | } else { | ||||
2405 | assert(InputTypeArg && "InputType set w/o InputTypeArg")(static_cast <bool> (InputTypeArg && "InputType set w/o InputTypeArg" ) ? void (0) : __assert_fail ("InputTypeArg && \"InputType set w/o InputTypeArg\"" , "clang/lib/Driver/Driver.cpp", 2405, __extension__ __PRETTY_FUNCTION__ )); | ||||
2406 | if (!InputTypeArg->getOption().matches(options::OPT_x)) { | ||||
2407 | // If emulating cl.exe, make sure that /TC and /TP don't affect input | ||||
2408 | // object files. | ||||
2409 | const char *Ext = strrchr(Value, '.'); | ||||
2410 | if (Ext && TC.LookupTypeForExtension(Ext + 1) == types::TY_Object) | ||||
2411 | Ty = types::TY_Object; | ||||
2412 | } | ||||
2413 | if (Ty == types::TY_INVALID) { | ||||
2414 | Ty = InputType; | ||||
2415 | InputTypeArg->claim(); | ||||
2416 | } | ||||
2417 | } | ||||
2418 | |||||
2419 | if (DiagnoseInputExistence(Args, Value, Ty, /*TypoCorrect=*/true)) | ||||
2420 | Inputs.push_back(std::make_pair(Ty, A)); | ||||
2421 | |||||
2422 | } else if (A->getOption().matches(options::OPT__SLASH_Tc)) { | ||||
2423 | StringRef Value = A->getValue(); | ||||
2424 | if (DiagnoseInputExistence(Args, Value, types::TY_C, | ||||
2425 | /*TypoCorrect=*/false)) { | ||||
2426 | Arg *InputArg = MakeInputArg(Args, Opts, A->getValue()); | ||||
2427 | Inputs.push_back(std::make_pair(types::TY_C, InputArg)); | ||||
2428 | } | ||||
2429 | A->claim(); | ||||
2430 | } else if (A->getOption().matches(options::OPT__SLASH_Tp)) { | ||||
2431 | StringRef Value = A->getValue(); | ||||
2432 | if (DiagnoseInputExistence(Args, Value, types::TY_CXX, | ||||
2433 | /*TypoCorrect=*/false)) { | ||||
2434 | Arg *InputArg = MakeInputArg(Args, Opts, A->getValue()); | ||||
2435 | Inputs.push_back(std::make_pair(types::TY_CXX, InputArg)); | ||||
2436 | } | ||||
2437 | A->claim(); | ||||
2438 | } else if (A->getOption().hasFlag(options::LinkerInput)) { | ||||
2439 | // Just treat as object type, we could make a special type for this if | ||||
2440 | // necessary. | ||||
2441 | Inputs.push_back(std::make_pair(types::TY_Object, A)); | ||||
2442 | |||||
2443 | } else if (A->getOption().matches(options::OPT_x)) { | ||||
2444 | InputTypeArg = A; | ||||
2445 | InputType = types::lookupTypeForTypeSpecifier(A->getValue()); | ||||
2446 | A->claim(); | ||||
2447 | |||||
2448 | // Follow gcc behavior and treat as linker input for invalid -x | ||||
2449 | // options. Its not clear why we shouldn't just revert to unknown; but | ||||
2450 | // this isn't very important, we might as well be bug compatible. | ||||
2451 | if (!InputType) { | ||||
2452 | Diag(clang::diag::err_drv_unknown_language) << A->getValue(); | ||||
2453 | InputType = types::TY_Object; | ||||
2454 | } | ||||
2455 | } else if (A->getOption().getID() == options::OPT_U) { | ||||
2456 | assert(A->getNumValues() == 1 && "The /U option has one value.")(static_cast <bool> (A->getNumValues() == 1 && "The /U option has one value.") ? void (0) : __assert_fail ( "A->getNumValues() == 1 && \"The /U option has one value.\"" , "clang/lib/Driver/Driver.cpp", 2456, __extension__ __PRETTY_FUNCTION__ )); | ||||
2457 | StringRef Val = A->getValue(0); | ||||
2458 | if (Val.find_first_of("/\\") != StringRef::npos) { | ||||
2459 | // Warn about e.g. "/Users/me/myfile.c". | ||||
2460 | Diag(diag::warn_slash_u_filename) << Val; | ||||
2461 | Diag(diag::note_use_dashdash); | ||||
2462 | } | ||||
2463 | } | ||||
2464 | } | ||||
2465 | if (CCCIsCPP() && Inputs.empty()) { | ||||
2466 | // If called as standalone preprocessor, stdin is processed | ||||
2467 | // if no other input is present. | ||||
2468 | Arg *A = MakeInputArg(Args, Opts, "-"); | ||||
2469 | Inputs.push_back(std::make_pair(types::TY_C, A)); | ||||
2470 | } | ||||
2471 | } | ||||
2472 | |||||
2473 | namespace { | ||||
2474 | /// Provides a convenient interface for different programming models to generate | ||||
2475 | /// the required device actions. | ||||
2476 | class OffloadingActionBuilder final { | ||||
2477 | /// Flag used to trace errors in the builder. | ||||
2478 | bool IsValid = false; | ||||
2479 | |||||
2480 | /// The compilation that is using this builder. | ||||
2481 | Compilation &C; | ||||
2482 | |||||
2483 | /// Map between an input argument and the offload kinds used to process it. | ||||
2484 | std::map<const Arg *, unsigned> InputArgToOffloadKindMap; | ||||
2485 | |||||
2486 | /// Map between a host action and its originating input argument. | ||||
2487 | std::map<Action *, const Arg *> HostActionToInputArgMap; | ||||
2488 | |||||
2489 | /// Builder interface. It doesn't build anything or keep any state. | ||||
2490 | class DeviceActionBuilder { | ||||
2491 | public: | ||||
2492 | typedef const llvm::SmallVectorImpl<phases::ID> PhasesTy; | ||||
2493 | |||||
2494 | enum ActionBuilderReturnCode { | ||||
2495 | // The builder acted successfully on the current action. | ||||
2496 | ABRT_Success, | ||||
2497 | // The builder didn't have to act on the current action. | ||||
2498 | ABRT_Inactive, | ||||
2499 | // The builder was successful and requested the host action to not be | ||||
2500 | // generated. | ||||
2501 | ABRT_Ignore_Host, | ||||
2502 | }; | ||||
2503 | |||||
2504 | protected: | ||||
2505 | /// Compilation associated with this builder. | ||||
2506 | Compilation &C; | ||||
2507 | |||||
2508 | /// Tool chains associated with this builder. The same programming | ||||
2509 | /// model may have associated one or more tool chains. | ||||
2510 | SmallVector<const ToolChain *, 2> ToolChains; | ||||
2511 | |||||
2512 | /// The derived arguments associated with this builder. | ||||
2513 | DerivedArgList &Args; | ||||
2514 | |||||
2515 | /// The inputs associated with this builder. | ||||
2516 | const Driver::InputList &Inputs; | ||||
2517 | |||||
2518 | /// The associated offload kind. | ||||
2519 | Action::OffloadKind AssociatedOffloadKind = Action::OFK_None; | ||||
2520 | |||||
2521 | public: | ||||
2522 | DeviceActionBuilder(Compilation &C, DerivedArgList &Args, | ||||
2523 | const Driver::InputList &Inputs, | ||||
2524 | Action::OffloadKind AssociatedOffloadKind) | ||||
2525 | : C(C), Args(Args), Inputs(Inputs), | ||||
2526 | AssociatedOffloadKind(AssociatedOffloadKind) {} | ||||
2527 | virtual ~DeviceActionBuilder() {} | ||||
2528 | |||||
2529 | /// Fill up the array \a DA with all the device dependences that should be | ||||
2530 | /// added to the provided host action \a HostAction. By default it is | ||||
2531 | /// inactive. | ||||
2532 | virtual ActionBuilderReturnCode | ||||
2533 | getDeviceDependences(OffloadAction::DeviceDependences &DA, | ||||
2534 | phases::ID CurPhase, phases::ID FinalPhase, | ||||
2535 | PhasesTy &Phases) { | ||||
2536 | return ABRT_Inactive; | ||||
2537 | } | ||||
2538 | |||||
2539 | /// Update the state to include the provided host action \a HostAction as a | ||||
2540 | /// dependency of the current device action. By default it is inactive. | ||||
2541 | virtual ActionBuilderReturnCode addDeviceDepences(Action *HostAction) { | ||||
2542 | return ABRT_Inactive; | ||||
2543 | } | ||||
2544 | |||||
2545 | /// Append top level actions generated by the builder. | ||||
2546 | virtual void appendTopLevelActions(ActionList &AL) {} | ||||
2547 | |||||
2548 | /// Append linker device actions generated by the builder. | ||||
2549 | virtual void appendLinkDeviceActions(ActionList &AL) {} | ||||
2550 | |||||
2551 | /// Append linker host action generated by the builder. | ||||
2552 | virtual Action* appendLinkHostActions(ActionList &AL) { return nullptr; } | ||||
2553 | |||||
2554 | /// Append linker actions generated by the builder. | ||||
2555 | virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {} | ||||
2556 | |||||
2557 | /// Initialize the builder. Return true if any initialization errors are | ||||
2558 | /// found. | ||||
2559 | virtual bool initialize() { return false; } | ||||
2560 | |||||
2561 | /// Return true if the builder can use bundling/unbundling. | ||||
2562 | virtual bool canUseBundlerUnbundler() const { return false; } | ||||
2563 | |||||
2564 | /// Return true if this builder is valid. We have a valid builder if we have | ||||
2565 | /// associated device tool chains. | ||||
2566 | bool isValid() { return !ToolChains.empty(); } | ||||
2567 | |||||
2568 | /// Return the associated offload kind. | ||||
2569 | Action::OffloadKind getAssociatedOffloadKind() { | ||||
2570 | return AssociatedOffloadKind; | ||||
2571 | } | ||||
2572 | }; | ||||
2573 | |||||
2574 | /// Base class for CUDA/HIP action builder. It injects device code in | ||||
2575 | /// the host backend action. | ||||
2576 | class CudaActionBuilderBase : public DeviceActionBuilder { | ||||
2577 | protected: | ||||
2578 | /// Flags to signal if the user requested host-only or device-only | ||||
2579 | /// compilation. | ||||
2580 | bool CompileHostOnly = false; | ||||
2581 | bool CompileDeviceOnly = false; | ||||
2582 | bool EmitLLVM = false; | ||||
2583 | bool EmitAsm = false; | ||||
2584 | |||||
2585 | /// ID to identify each device compilation. For CUDA it is simply the | ||||
2586 | /// GPU arch string. For HIP it is either the GPU arch string or GPU | ||||
2587 | /// arch string plus feature strings delimited by a plus sign, e.g. | ||||
2588 | /// gfx906+xnack. | ||||
2589 | struct TargetID { | ||||
2590 | /// Target ID string which is persistent throughout the compilation. | ||||
2591 | const char *ID; | ||||
2592 | TargetID(CudaArch Arch) { ID = CudaArchToString(Arch); } | ||||
2593 | TargetID(const char *ID) : ID(ID) {} | ||||
2594 | operator const char *() { return ID; } | ||||
2595 | operator StringRef() { return StringRef(ID); } | ||||
2596 | }; | ||||
2597 | /// List of GPU architectures to use in this compilation. | ||||
2598 | SmallVector<TargetID, 4> GpuArchList; | ||||
2599 | |||||
2600 | /// The CUDA actions for the current input. | ||||
2601 | ActionList CudaDeviceActions; | ||||
2602 | |||||
2603 | /// The CUDA fat binary if it was generated for the current input. | ||||
2604 | Action *CudaFatBinary = nullptr; | ||||
2605 | |||||
2606 | /// Flag that is set to true if this builder acted on the current input. | ||||
2607 | bool IsActive = false; | ||||
2608 | |||||
2609 | /// Flag for -fgpu-rdc. | ||||
2610 | bool Relocatable = false; | ||||
2611 | |||||
2612 | /// Default GPU architecture if there's no one specified. | ||||
2613 | CudaArch DefaultCudaArch = CudaArch::UNKNOWN; | ||||
2614 | |||||
2615 | /// Method to generate compilation unit ID specified by option | ||||
2616 | /// '-fuse-cuid='. | ||||
2617 | enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid }; | ||||
2618 | UseCUIDKind UseCUID = CUID_Hash; | ||||
2619 | |||||
2620 | /// Compilation unit ID specified by option '-cuid='. | ||||
2621 | StringRef FixedCUID; | ||||
2622 | |||||
2623 | public: | ||||
2624 | CudaActionBuilderBase(Compilation &C, DerivedArgList &Args, | ||||
2625 | const Driver::InputList &Inputs, | ||||
2626 | Action::OffloadKind OFKind) | ||||
2627 | : DeviceActionBuilder(C, Args, Inputs, OFKind) {} | ||||
2628 | |||||
2629 | ActionBuilderReturnCode addDeviceDepences(Action *HostAction) override { | ||||
2630 | // While generating code for CUDA, we only depend on the host input action | ||||
2631 | // to trigger the creation of all the CUDA device actions. | ||||
2632 | |||||
2633 | // If we are dealing with an input action, replicate it for each GPU | ||||
2634 | // architecture. If we are in host-only mode we return 'success' so that | ||||
2635 | // the host uses the CUDA offload kind. | ||||
2636 | if (auto *IA = dyn_cast<InputAction>(HostAction)) { | ||||
2637 | assert(!GpuArchList.empty() &&(static_cast <bool> (!GpuArchList.empty() && "We should have at least one GPU architecture." ) ? void (0) : __assert_fail ("!GpuArchList.empty() && \"We should have at least one GPU architecture.\"" , "clang/lib/Driver/Driver.cpp", 2638, __extension__ __PRETTY_FUNCTION__ )) | ||||
2638 | "We should have at least one GPU architecture.")(static_cast <bool> (!GpuArchList.empty() && "We should have at least one GPU architecture." ) ? void (0) : __assert_fail ("!GpuArchList.empty() && \"We should have at least one GPU architecture.\"" , "clang/lib/Driver/Driver.cpp", 2638, __extension__ __PRETTY_FUNCTION__ )); | ||||
2639 | |||||
2640 | // If the host input is not CUDA or HIP, we don't need to bother about | ||||
2641 | // this input. | ||||
2642 | if (!(IA->getType() == types::TY_CUDA || | ||||
2643 | IA->getType() == types::TY_HIP || | ||||
2644 | IA->getType() == types::TY_PP_HIP)) { | ||||
2645 | // The builder will ignore this input. | ||||
2646 | IsActive = false; | ||||
2647 | return ABRT_Inactive; | ||||
2648 | } | ||||
2649 | |||||
2650 | // Set the flag to true, so that the builder acts on the current input. | ||||
2651 | IsActive = true; | ||||
2652 | |||||
2653 | if (CompileHostOnly) | ||||
2654 | return ABRT_Success; | ||||
2655 | |||||
2656 | // Replicate inputs for each GPU architecture. | ||||
2657 | auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE | ||||
2658 | : types::TY_CUDA_DEVICE; | ||||
2659 | std::string CUID = FixedCUID.str(); | ||||
2660 | if (CUID.empty()) { | ||||
2661 | if (UseCUID == CUID_Random) | ||||
2662 | CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(), | ||||
2663 | /*LowerCase=*/true); | ||||
2664 | else if (UseCUID == CUID_Hash) { | ||||
2665 | llvm::MD5 Hasher; | ||||
2666 | llvm::MD5::MD5Result Hash; | ||||
2667 | SmallString<256> RealPath; | ||||
2668 | llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath, | ||||
2669 | /*expand_tilde=*/true); | ||||
2670 | Hasher.update(RealPath); | ||||
2671 | for (auto *A : Args) { | ||||
2672 | if (A->getOption().matches(options::OPT_INPUT)) | ||||
2673 | continue; | ||||
2674 | Hasher.update(A->getAsString(Args)); | ||||
2675 | } | ||||
2676 | Hasher.final(Hash); | ||||
2677 | CUID = llvm::utohexstr(Hash.low(), /*LowerCase=*/true); | ||||
2678 | } | ||||
2679 | } | ||||
2680 | IA->setId(CUID); | ||||
2681 | |||||
2682 | for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) { | ||||
2683 | CudaDeviceActions.push_back( | ||||
2684 | C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId())); | ||||
2685 | } | ||||
2686 | |||||
2687 | return ABRT_Success; | ||||
2688 | } | ||||
2689 | |||||
2690 | // If this is an unbundling action use it as is for each CUDA toolchain. | ||||
2691 | if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) { | ||||
2692 | |||||
2693 | // If -fgpu-rdc is disabled, should not unbundle since there is no | ||||
2694 | // device code to link. | ||||
2695 | if (UA->getType() == types::TY_Object && !Relocatable) | ||||
2696 | return ABRT_Inactive; | ||||
2697 | |||||
2698 | CudaDeviceActions.clear(); | ||||
2699 | auto *IA = cast<InputAction>(UA->getInputs().back()); | ||||
2700 | std::string FileName = IA->getInputArg().getAsString(Args); | ||||
2701 | // Check if the type of the file is the same as the action. Do not | ||||
2702 | // unbundle it if it is not. Do not unbundle .so files, for example, | ||||
2703 | // which are not object files. | ||||
2704 | if (IA->getType() == types::TY_Object && | ||||
2705 | (!llvm::sys::path::has_extension(FileName) || | ||||
2706 | types::lookupTypeForExtension( | ||||
2707 | llvm::sys::path::extension(FileName).drop_front()) != | ||||
2708 | types::TY_Object)) | ||||
2709 | return ABRT_Inactive; | ||||
2710 | |||||
2711 | for (auto Arch : GpuArchList) { | ||||
2712 | CudaDeviceActions.push_back(UA); | ||||
2713 | UA->registerDependentActionInfo(ToolChains[0], Arch, | ||||
2714 | AssociatedOffloadKind); | ||||
2715 | } | ||||
2716 | IsActive = true; | ||||
2717 | return ABRT_Success; | ||||
2718 | } | ||||
2719 | |||||
2720 | return IsActive ? ABRT_Success : ABRT_Inactive; | ||||
2721 | } | ||||
2722 | |||||
2723 | void appendTopLevelActions(ActionList &AL) override { | ||||
2724 | // Utility to append actions to the top level list. | ||||
2725 | auto AddTopLevel = [&](Action *A, TargetID TargetID) { | ||||
2726 | OffloadAction::DeviceDependences Dep; | ||||
2727 | Dep.add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind); | ||||
2728 | AL.push_back(C.MakeAction<OffloadAction>(Dep, A->getType())); | ||||
2729 | }; | ||||
2730 | |||||
2731 | // If we have a fat binary, add it to the list. | ||||
2732 | if (CudaFatBinary) { | ||||
2733 | AddTopLevel(CudaFatBinary, CudaArch::UNUSED); | ||||
2734 | CudaDeviceActions.clear(); | ||||
2735 | CudaFatBinary = nullptr; | ||||
2736 | return; | ||||
2737 | } | ||||
2738 | |||||
2739 | if (CudaDeviceActions.empty()) | ||||
2740 | return; | ||||
2741 | |||||
2742 | // If we have CUDA actions at this point, that's because we have a have | ||||
2743 | // partial compilation, so we should have an action for each GPU | ||||
2744 | // architecture. | ||||
2745 | assert(CudaDeviceActions.size() == GpuArchList.size() &&(static_cast <bool> (CudaDeviceActions.size() == GpuArchList .size() && "Expecting one action per GPU architecture." ) ? void (0) : __assert_fail ("CudaDeviceActions.size() == GpuArchList.size() && \"Expecting one action per GPU architecture.\"" , "clang/lib/Driver/Driver.cpp", 2746, __extension__ __PRETTY_FUNCTION__ )) | ||||
2746 | "Expecting one action per GPU architecture.")(static_cast <bool> (CudaDeviceActions.size() == GpuArchList .size() && "Expecting one action per GPU architecture." ) ? void (0) : __assert_fail ("CudaDeviceActions.size() == GpuArchList.size() && \"Expecting one action per GPU architecture.\"" , "clang/lib/Driver/Driver.cpp", 2746, __extension__ __PRETTY_FUNCTION__ )); | ||||
2747 | assert(ToolChains.size() == 1 &&(static_cast <bool> (ToolChains.size() == 1 && "Expecting to have a single CUDA toolchain." ) ? void (0) : __assert_fail ("ToolChains.size() == 1 && \"Expecting to have a single CUDA toolchain.\"" , "clang/lib/Driver/Driver.cpp", 2748, __extension__ __PRETTY_FUNCTION__ )) | ||||
2748 | "Expecting to have a single CUDA toolchain.")(static_cast <bool> (ToolChains.size() == 1 && "Expecting to have a single CUDA toolchain." ) ? void (0) : __assert_fail ("ToolChains.size() == 1 && \"Expecting to have a single CUDA toolchain.\"" , "clang/lib/Driver/Driver.cpp", 2748, __extension__ __PRETTY_FUNCTION__ )); | ||||
2749 | for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) | ||||
2750 | AddTopLevel(CudaDeviceActions[I], GpuArchList[I]); | ||||
2751 | |||||
2752 | CudaDeviceActions.clear(); | ||||
2753 | } | ||||
2754 | |||||
2755 | /// Get canonicalized offload arch option. \returns empty StringRef if the | ||||
2756 | /// option is invalid. | ||||
2757 | virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0; | ||||
2758 | |||||
2759 | virtual llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>> | ||||
2760 | getConflictOffloadArchCombination(const std::set<StringRef> &GpuArchs) = 0; | ||||
2761 | |||||
2762 | bool initialize() override { | ||||
2763 | assert(AssociatedOffloadKind == Action::OFK_Cuda ||(static_cast <bool> (AssociatedOffloadKind == Action::OFK_Cuda || AssociatedOffloadKind == Action::OFK_HIP) ? void (0) : __assert_fail ("AssociatedOffloadKind == Action::OFK_Cuda || AssociatedOffloadKind == Action::OFK_HIP" , "clang/lib/Driver/Driver.cpp", 2764, __extension__ __PRETTY_FUNCTION__ )) | ||||
2764 | AssociatedOffloadKind == Action::OFK_HIP)(static_cast <bool> (AssociatedOffloadKind == Action::OFK_Cuda || AssociatedOffloadKind == Action::OFK_HIP) ? void (0) : __assert_fail ("AssociatedOffloadKind == Action::OFK_Cuda || AssociatedOffloadKind == Action::OFK_HIP" , "clang/lib/Driver/Driver.cpp", 2764, __extension__ __PRETTY_FUNCTION__ )); | ||||
2765 | |||||
2766 | // We don't need to support CUDA. | ||||
2767 | if (AssociatedOffloadKind == Action::OFK_Cuda && | ||||
2768 | !C.hasOffloadToolChain<Action::OFK_Cuda>()) | ||||
2769 | return false; | ||||
2770 | |||||
2771 | // We don't need to support HIP. | ||||
2772 | if (AssociatedOffloadKind == Action::OFK_HIP && | ||||
2773 | !C.hasOffloadToolChain<Action::OFK_HIP>()) | ||||
2774 | return false; | ||||
2775 | |||||
2776 | Relocatable = Args.hasFlag(options::OPT_fgpu_rdc, | ||||
2777 | options::OPT_fno_gpu_rdc, /*Default=*/false); | ||||
2778 | |||||
2779 | const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>(); | ||||
2780 | assert(HostTC && "No toolchain for host compilation.")(static_cast <bool> (HostTC && "No toolchain for host compilation." ) ? void (0) : __assert_fail ("HostTC && \"No toolchain for host compilation.\"" , "clang/lib/Driver/Driver.cpp", 2780, __extension__ __PRETTY_FUNCTION__ )); | ||||
2781 | if (HostTC->getTriple().isNVPTX() || | ||||
2782 | HostTC->getTriple().getArch() == llvm::Triple::amdgcn) { | ||||
2783 | // We do not support targeting NVPTX/AMDGCN for host compilation. Throw | ||||
2784 | // an error and abort pipeline construction early so we don't trip | ||||
2785 | // asserts that assume device-side compilation. | ||||
2786 | C.getDriver().Diag(diag::err_drv_cuda_host_arch) | ||||
2787 | << HostTC->getTriple().getArchName(); | ||||
2788 | return true; | ||||
2789 | } | ||||
2790 | |||||
2791 | ToolChains.push_back( | ||||
2792 | AssociatedOffloadKind == Action::OFK_Cuda | ||||
2793 | ? C.getSingleOffloadToolChain<Action::OFK_Cuda>() | ||||
2794 | : C.getSingleOffloadToolChain<Action::OFK_HIP>()); | ||||
2795 | |||||
2796 | Arg *PartialCompilationArg = Args.getLastArg( | ||||
2797 | options::OPT_cuda_host_only, options::OPT_cuda_device_only, | ||||
2798 | options::OPT_cuda_compile_host_device); | ||||
2799 | CompileHostOnly = PartialCompilationArg && | ||||
2800 | PartialCompilationArg->getOption().matches( | ||||
2801 | options::OPT_cuda_host_only); | ||||
2802 | CompileDeviceOnly = PartialCompilationArg && | ||||
2803 | PartialCompilationArg->getOption().matches( | ||||
2804 | options::OPT_cuda_device_only); | ||||
2805 | EmitLLVM = Args.getLastArg(options::OPT_emit_llvm); | ||||
2806 | EmitAsm = Args.getLastArg(options::OPT_S); | ||||
2807 | FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ); | ||||
2808 | if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) { | ||||
2809 | StringRef UseCUIDStr = A->getValue(); | ||||
2810 | UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr) | ||||
2811 | .Case("hash", CUID_Hash) | ||||
2812 | .Case("random", CUID_Random) | ||||
2813 | .Case("none", CUID_None) | ||||
2814 | .Default(CUID_Invalid); | ||||
2815 | if (UseCUID == CUID_Invalid) { | ||||
2816 | C.getDriver().Diag(diag::err_drv_invalid_value) | ||||
2817 | << A->getAsString(Args) << UseCUIDStr; | ||||
2818 | C.setContainsError(); | ||||
2819 | return true; | ||||
2820 | } | ||||
2821 | } | ||||
2822 | |||||
2823 | // --offload and --offload-arch options are mutually exclusive. | ||||
2824 | if (Args.hasArgNoClaim(options::OPT_offload_EQ) && | ||||
2825 | Args.hasArgNoClaim(options::OPT_offload_arch_EQ, | ||||
2826 | options::OPT_no_offload_arch_EQ)) { | ||||
2827 | C.getDriver().Diag(diag::err_opt_not_valid_with_opt) << "--offload-arch" | ||||
2828 | << "--offload"; | ||||
2829 | } | ||||
2830 | |||||
2831 | // Collect all cuda_gpu_arch parameters, removing duplicates. | ||||
2832 | std::set<StringRef> GpuArchs; | ||||
2833 | bool Error = false; | ||||
2834 | for (Arg *A : Args) { | ||||
2835 | if (!(A->getOption().matches(options::OPT_offload_arch_EQ) || | ||||
2836 | A->getOption().matches(options::OPT_no_offload_arch_EQ))) | ||||
2837 | continue; | ||||
2838 | A->claim(); | ||||
2839 | |||||
2840 | StringRef ArchStr = A->getValue(); | ||||
2841 | if (A->getOption().matches(options::OPT_no_offload_arch_EQ) && | ||||
2842 | ArchStr == "all") { | ||||
2843 | GpuArchs.clear(); | ||||
2844 | continue; | ||||
2845 | } | ||||
2846 | ArchStr = getCanonicalOffloadArch(ArchStr); | ||||
2847 | if (ArchStr.empty()) { | ||||
2848 | Error = true; | ||||
2849 | } else if (A->getOption().matches(options::OPT_offload_arch_EQ)) | ||||
2850 | GpuArchs.insert(ArchStr); | ||||
2851 | else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) | ||||
2852 | GpuArchs.erase(ArchStr); | ||||
2853 | else | ||||
2854 | llvm_unreachable("Unexpected option.")::llvm::llvm_unreachable_internal("Unexpected option.", "clang/lib/Driver/Driver.cpp" , 2854); | ||||
2855 | } | ||||
2856 | |||||
2857 | auto &&ConflictingArchs = getConflictOffloadArchCombination(GpuArchs); | ||||
2858 | if (ConflictingArchs) { | ||||
2859 | C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo) | ||||
2860 | << ConflictingArchs.getValue().first | ||||
2861 | << ConflictingArchs.getValue().second; | ||||
2862 | C.setContainsError(); | ||||
2863 | return true; | ||||
2864 | } | ||||
2865 | |||||
2866 | // Collect list of GPUs remaining in the set. | ||||
2867 | for (auto Arch : GpuArchs) | ||||
2868 | GpuArchList.push_back(Arch.data()); | ||||
2869 | |||||
2870 | // Default to sm_20 which is the lowest common denominator for | ||||
2871 | // supported GPUs. sm_20 code should work correctly, if | ||||
2872 | // suboptimally, on all newer GPUs. | ||||
2873 | if (GpuArchList.empty()) { | ||||
2874 | if (ToolChains.front()->getTriple().isSPIRV()) | ||||
2875 | GpuArchList.push_back(CudaArch::Generic); | ||||
2876 | else | ||||
2877 | GpuArchList.push_back(DefaultCudaArch); | ||||
2878 | } | ||||
2879 | |||||
2880 | return Error; | ||||
2881 | } | ||||
2882 | }; | ||||
2883 | |||||
2884 | /// \brief CUDA action builder. It injects device code in the host backend | ||||
2885 | /// action. | ||||
2886 | class CudaActionBuilder final : public CudaActionBuilderBase { | ||||
2887 | public: | ||||
2888 | CudaActionBuilder(Compilation &C, DerivedArgList &Args, | ||||
2889 | const Driver::InputList &Inputs) | ||||
2890 | : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_Cuda) { | ||||
2891 | DefaultCudaArch = CudaArch::SM_35; | ||||
2892 | } | ||||
2893 | |||||
2894 | StringRef getCanonicalOffloadArch(StringRef ArchStr) override { | ||||
2895 | CudaArch Arch = StringToCudaArch(ArchStr); | ||||
2896 | if (Arch == CudaArch::UNKNOWN || !IsNVIDIAGpuArch(Arch)) { | ||||
2897 | C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr; | ||||
2898 | return StringRef(); | ||||
2899 | } | ||||
2900 | return CudaArchToString(Arch); | ||||
2901 | } | ||||
2902 | |||||
2903 | llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>> | ||||
2904 | getConflictOffloadArchCombination( | ||||
2905 | const std::set<StringRef> &GpuArchs) override { | ||||
2906 | return llvm::None; | ||||
2907 | } | ||||
2908 | |||||
2909 | ActionBuilderReturnCode | ||||
2910 | getDeviceDependences(OffloadAction::DeviceDependences &DA, | ||||
2911 | phases::ID CurPhase, phases::ID FinalPhase, | ||||
2912 | PhasesTy &Phases) override { | ||||
2913 | if (!IsActive) | ||||
2914 | return ABRT_Inactive; | ||||
2915 | |||||
2916 | // If we don't have more CUDA actions, we don't have any dependences to | ||||
2917 | // create for the host. | ||||
2918 | if (CudaDeviceActions.empty()) | ||||
2919 | return ABRT_Success; | ||||
2920 | |||||
2921 | assert(CudaDeviceActions.size() == GpuArchList.size() &&(static_cast <bool> (CudaDeviceActions.size() == GpuArchList .size() && "Expecting one action per GPU architecture." ) ? void (0) : __assert_fail ("CudaDeviceActions.size() == GpuArchList.size() && \"Expecting one action per GPU architecture.\"" , "clang/lib/Driver/Driver.cpp", 2922, __extension__ __PRETTY_FUNCTION__ )) | ||||
2922 | "Expecting one action per GPU architecture.")(static_cast <bool> (CudaDeviceActions.size() == GpuArchList .size() && "Expecting one action per GPU architecture." ) ? void (0) : __assert_fail ("CudaDeviceActions.size() == GpuArchList.size() && \"Expecting one action per GPU architecture.\"" , "clang/lib/Driver/Driver.cpp", 2922, __extension__ __PRETTY_FUNCTION__ )); | ||||
2923 | assert(!CompileHostOnly &&(static_cast <bool> (!CompileHostOnly && "Not expecting CUDA actions in host-only compilation." ) ? void (0) : __assert_fail ("!CompileHostOnly && \"Not expecting CUDA actions in host-only compilation.\"" , "clang/lib/Driver/Driver.cpp", 2924, __extension__ __PRETTY_FUNCTION__ )) | ||||
2924 | "Not expecting CUDA actions in host-only compilation.")(static_cast <bool> (!CompileHostOnly && "Not expecting CUDA actions in host-only compilation." ) ? void (0) : __assert_fail ("!CompileHostOnly && \"Not expecting CUDA actions in host-only compilation.\"" , "clang/lib/Driver/Driver.cpp", 2924, __extension__ __PRETTY_FUNCTION__ )); | ||||
2925 | |||||
2926 | // If we are generating code for the device or we are in a backend phase, | ||||
2927 | // we attempt to generate the fat binary. We compile each arch to ptx and | ||||
2928 | // assemble to cubin, then feed the cubin *and* the ptx into a device | ||||
2929 | // "link" action, which uses fatbinary to combine these cubins into one | ||||
2930 | // fatbin. The fatbin is then an input to the host action if not in | ||||
2931 | // device-only mode. | ||||
2932 | if (CompileDeviceOnly || CurPhase == phases::Backend) { | ||||
2933 | ActionList DeviceActions; | ||||
2934 | for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) { | ||||
2935 | // Produce the device action from the current phase up to the assemble | ||||
2936 | // phase. | ||||
2937 | for (auto Ph : Phases) { | ||||
2938 | // Skip the phases that were already dealt with. | ||||
2939 | if (Ph < CurPhase) | ||||
2940 | continue; | ||||
2941 | // We have to be consistent with the host final phase. | ||||
2942 | if (Ph > FinalPhase) | ||||
2943 | break; | ||||
2944 | |||||
2945 | CudaDeviceActions[I] = C.getDriver().ConstructPhaseAction( | ||||
2946 | C, Args, Ph, CudaDeviceActions[I], Action::OFK_Cuda); | ||||
2947 | |||||
2948 | if (Ph == phases::Assemble) | ||||
2949 | break; | ||||
2950 | } | ||||
2951 | |||||
2952 | // If we didn't reach the assemble phase, we can't generate the fat | ||||
2953 | // binary. We don't need to generate the fat binary if we are not in | ||||
2954 | // device-only mode. | ||||
2955 | if (!isa<AssembleJobAction>(CudaDeviceActions[I]) || | ||||
2956 | CompileDeviceOnly) | ||||
2957 | continue; | ||||
2958 | |||||
2959 | Action *AssembleAction = CudaDeviceActions[I]; | ||||
2960 | assert(AssembleAction->getType() == types::TY_Object)(static_cast <bool> (AssembleAction->getType() == types ::TY_Object) ? void (0) : __assert_fail ("AssembleAction->getType() == types::TY_Object" , "clang/lib/Driver/Driver.cpp", 2960, __extension__ __PRETTY_FUNCTION__ )); | ||||
2961 | assert(AssembleAction->getInputs().size() == 1)(static_cast <bool> (AssembleAction->getInputs().size () == 1) ? void (0) : __assert_fail ("AssembleAction->getInputs().size() == 1" , "clang/lib/Driver/Driver.cpp", 2961, __extension__ __PRETTY_FUNCTION__ )); | ||||
2962 | |||||
2963 | Action *BackendAction = AssembleAction->getInputs()[0]; | ||||
2964 | assert(BackendAction->getType() == types::TY_PP_Asm)(static_cast <bool> (BackendAction->getType() == types ::TY_PP_Asm) ? void (0) : __assert_fail ("BackendAction->getType() == types::TY_PP_Asm" , "clang/lib/Driver/Driver.cpp", 2964, __extension__ __PRETTY_FUNCTION__ )); | ||||
2965 | |||||
2966 | for (auto &A : {AssembleAction, BackendAction}) { | ||||
2967 | OffloadAction::DeviceDependences DDep; | ||||
2968 | DDep.add(*A, *ToolChains.front(), GpuArchList[I], Action::OFK_Cuda); | ||||
2969 | DeviceActions.push_back( | ||||
2970 | C.MakeAction<OffloadAction>(DDep, A->getType())); | ||||
2971 | } | ||||
2972 | } | ||||
2973 | |||||
2974 | // We generate the fat binary if we have device input actions. | ||||
2975 | if (!DeviceActions.empty()) { | ||||
2976 | CudaFatBinary = | ||||
2977 | C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN); | ||||
2978 | |||||
2979 | if (!CompileDeviceOnly) { | ||||
2980 | DA.add(*CudaFatBinary, *ToolChains.front(), /*BoundArch=*/nullptr, | ||||
2981 | Action::OFK_Cuda); | ||||
2982 | // Clear the fat binary, it is already a dependence to an host | ||||
2983 | // action. | ||||
2984 | CudaFatBinary = nullptr; | ||||
2985 | } | ||||
2986 | |||||
2987 | // Remove the CUDA actions as they are already connected to an host | ||||
2988 | // action or fat binary. | ||||
2989 | CudaDeviceActions.clear(); | ||||
2990 | } | ||||
2991 | |||||
2992 | // We avoid creating host action in device-only mode. | ||||
2993 | return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success; | ||||
2994 | } else if (CurPhase > phases::Backend) { | ||||
2995 | // If we are past the backend phase and still have a device action, we | ||||
2996 | // don't have to do anything as this action is already a device | ||||
2997 | // top-level action. | ||||
2998 | return ABRT_Success; | ||||
2999 | } | ||||
3000 | |||||
3001 | assert(CurPhase < phases::Backend && "Generating single CUDA "(static_cast <bool> (CurPhase < phases::Backend && "Generating single CUDA " "instructions should only occur " "before the backend phase!" ) ? void (0) : __assert_fail ("CurPhase < phases::Backend && \"Generating single CUDA \" \"instructions should only occur \" \"before the backend phase!\"" , "clang/lib/Driver/Driver.cpp", 3003, __extension__ __PRETTY_FUNCTION__ )) | ||||
3002 | "instructions should only occur "(static_cast <bool> (CurPhase < phases::Backend && "Generating single CUDA " "instructions should only occur " "before the backend phase!" ) ? void (0) : __assert_fail ("CurPhase < phases::Backend && \"Generating single CUDA \" \"instructions should only occur \" \"before the backend phase!\"" , "clang/lib/Driver/Driver.cpp", 3003, __extension__ __PRETTY_FUNCTION__ )) | ||||
3003 | "before the backend phase!")(static_cast <bool> (CurPhase < phases::Backend && "Generating single CUDA " "instructions should only occur " "before the backend phase!" ) ? void (0) : __assert_fail ("CurPhase < phases::Backend && \"Generating single CUDA \" \"instructions should only occur \" \"before the backend phase!\"" , "clang/lib/Driver/Driver.cpp", 3003, __extension__ __PRETTY_FUNCTION__ )); | ||||
3004 | |||||
3005 | // By default, we produce an action for each device arch. | ||||
3006 | for (Action *&A : CudaDeviceActions) | ||||
3007 | A = C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A); | ||||
3008 | |||||
3009 | return ABRT_Success; | ||||
3010 | } | ||||
3011 | }; | ||||
3012 | /// \brief HIP action builder. It injects device code in the host backend | ||||
3013 | /// action. | ||||
3014 | class HIPActionBuilder final : public CudaActionBuilderBase { | ||||
3015 | /// The linker inputs obtained for each device arch. | ||||
3016 | SmallVector<ActionList, 8> DeviceLinkerInputs; | ||||
3017 | // The default bundling behavior depends on the type of output, therefore | ||||
3018 | // BundleOutput needs to be tri-value: None, true, or false. | ||||
3019 | // Bundle code objects except --no-gpu-output is specified for device | ||||
3020 | // only compilation. Bundle other type of output files only if | ||||
3021 | // --gpu-bundle-output is specified for device only compilation. | ||||
3022 | Optional<bool> BundleOutput; | ||||
3023 | |||||
3024 | public: | ||||
3025 | HIPActionBuilder(Compilation &C, DerivedArgList &Args, | ||||
3026 | const Driver::InputList &Inputs) | ||||
3027 | : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP) { | ||||
3028 | DefaultCudaArch = CudaArch::GFX803; | ||||
3029 | if (Args.hasArg(options::OPT_gpu_bundle_output, | ||||
3030 | options::OPT_no_gpu_bundle_output)) | ||||
3031 | BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output, | ||||
3032 | options::OPT_no_gpu_bundle_output, true); | ||||
3033 | } | ||||
3034 | |||||
3035 | bool canUseBundlerUnbundler() const override { return true; } | ||||
3036 | |||||
3037 | StringRef getCanonicalOffloadArch(StringRef IdStr) override { | ||||
3038 | llvm::StringMap<bool> Features; | ||||
3039 | // getHIPOffloadTargetTriple() is known to return valid value as it has | ||||
3040 | // been called successfully in the CreateOffloadingDeviceToolChains(). | ||||
3041 | auto ArchStr = parseTargetID( | ||||
3042 | *getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs()), IdStr, | ||||
3043 | &Features); | ||||
3044 | if (!ArchStr) { | ||||
3045 | C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr; | ||||
3046 | C.setContainsError(); | ||||
3047 | return StringRef(); | ||||
3048 | } | ||||
3049 | auto CanId = getCanonicalTargetID(ArchStr.getValue(), Features); | ||||
3050 | return Args.MakeArgStringRef(CanId); | ||||
3051 | }; | ||||
3052 | |||||
3053 | llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>> | ||||
3054 | getConflictOffloadArchCombination( | ||||
3055 | const std::set<StringRef> &GpuArchs) override { | ||||
3056 | return getConflictTargetIDCombination(GpuArchs); | ||||
3057 | } | ||||
3058 | |||||
3059 | ActionBuilderReturnCode | ||||
3060 | getDeviceDependences(OffloadAction::DeviceDependences &DA, | ||||
3061 | phases::ID CurPhase, phases::ID FinalPhase, | ||||
3062 | PhasesTy &Phases) override { | ||||
3063 | if (!IsActive) | ||||
3064 | return ABRT_Inactive; | ||||
3065 | |||||
3066 | // amdgcn does not support linking of object files, therefore we skip | ||||
3067 | // backend and assemble phases to output LLVM IR. Except for generating | ||||
3068 | // non-relocatable device coee, where we generate fat binary for device | ||||
3069 | // code and pass to host in Backend phase. | ||||
3070 | if (CudaDeviceActions.empty()) | ||||
3071 | return ABRT_Success; | ||||
3072 | |||||
3073 | assert(((CurPhase == phases::Link && Relocatable) ||(static_cast <bool> (((CurPhase == phases::Link && Relocatable) || CudaDeviceActions.size() == GpuArchList.size ()) && "Expecting one action per GPU architecture.") ? void (0) : __assert_fail ("((CurPhase == phases::Link && Relocatable) || CudaDeviceActions.size() == GpuArchList.size()) && \"Expecting one action per GPU architecture.\"" , "clang/lib/Driver/Driver.cpp", 3075, __extension__ __PRETTY_FUNCTION__ )) | ||||
3074 | CudaDeviceActions.size() == GpuArchList.size()) &&(static_cast <bool> (((CurPhase == phases::Link && Relocatable) || CudaDeviceActions.size() == GpuArchList.size ()) && "Expecting one action per GPU architecture.") ? void (0) : __assert_fail ("((CurPhase == phases::Link && Relocatable) || CudaDeviceActions.size() == GpuArchList.size()) && \"Expecting one action per GPU architecture.\"" , "clang/lib/Driver/Driver.cpp", 3075, __extension__ __PRETTY_FUNCTION__ )) | ||||
3075 | "Expecting one action per GPU architecture.")(static_cast <bool> (((CurPhase == phases::Link && Relocatable) || CudaDeviceActions.size() == GpuArchList.size ()) && "Expecting one action per GPU architecture.") ? void (0) : __assert_fail ("((CurPhase == phases::Link && Relocatable) || CudaDeviceActions.size() == GpuArchList.size()) && \"Expecting one action per GPU architecture.\"" , "clang/lib/Driver/Driver.cpp", 3075, __extension__ __PRETTY_FUNCTION__ )); | ||||
3076 | assert(!CompileHostOnly &&(static_cast <bool> (!CompileHostOnly && "Not expecting CUDA actions in host-only compilation." ) ? void (0) : __assert_fail ("!CompileHostOnly && \"Not expecting CUDA actions in host-only compilation.\"" , "clang/lib/Driver/Driver.cpp", 3077, __extension__ __PRETTY_FUNCTION__ )) | ||||
3077 | "Not expecting CUDA actions in host-only compilation.")(static_cast <bool> (!CompileHostOnly && "Not expecting CUDA actions in host-only compilation." ) ? void (0) : __assert_fail ("!CompileHostOnly && \"Not expecting CUDA actions in host-only compilation.\"" , "clang/lib/Driver/Driver.cpp", 3077, __extension__ __PRETTY_FUNCTION__ )); | ||||
3078 | |||||
3079 | if (!Relocatable && CurPhase == phases::Backend && !EmitLLVM && | ||||
3080 | !EmitAsm) { | ||||
3081 | // If we are in backend phase, we attempt to generate the fat binary. | ||||
3082 | // We compile each arch to IR and use a link action to generate code | ||||
3083 | // object containing ISA. Then we use a special "link" action to create | ||||
3084 | // a fat binary containing all the code objects for different GPU's. | ||||
3085 | // The fat binary is then an input to the host action. | ||||
3086 | for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) { | ||||
3087 | if (C.getDriver().isUsingLTO(/*IsOffload=*/true)) { | ||||
3088 | // When LTO is enabled, skip the backend and assemble phases and | ||||
3089 | // use lld to link the bitcode. | ||||
3090 | ActionList AL; | ||||
3091 | AL.push_back(CudaDeviceActions[I]); | ||||
3092 | // Create a link action to link device IR with device library | ||||
3093 | // and generate ISA. | ||||
3094 | CudaDeviceActions[I] = | ||||
3095 | C.MakeAction<LinkJobAction>(AL, types::TY_Image); | ||||
3096 | } else { | ||||
3097 | // When LTO is not enabled, we follow the conventional | ||||
3098 | // compiler phases, including backend and assemble phases. | ||||
3099 | ActionList AL; | ||||
3100 | Action *BackendAction = nullptr; | ||||
3101 | if (ToolChains.front()->getTriple().isSPIRV()) { | ||||
3102 | // Emit LLVM bitcode for SPIR-V targets. SPIR-V device tool chain | ||||
3103 | // (HIPSPVToolChain) runs post-link LLVM IR passes. | ||||
3104 | types::ID Output = Args.hasArg(options::OPT_S) | ||||
3105 | ? types::TY_LLVM_IR | ||||
3106 | : types::TY_LLVM_BC; | ||||
3107 | BackendAction = | ||||
3108 | C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output); | ||||
3109 | } else | ||||
3110 | BackendAction = C.getDriver().ConstructPhaseAction( | ||||
3111 | C, Args, phases::Backend, CudaDeviceActions[I], | ||||
3112 | AssociatedOffloadKind); | ||||
3113 | auto AssembleAction = C.getDriver().ConstructPhaseAction( | ||||
3114 | C, Args, phases::Assemble, BackendAction, | ||||
3115 | AssociatedOffloadKind); | ||||
3116 | AL.push_back(AssembleAction); | ||||
3117 | // Create a link action to link device IR with device library | ||||
3118 | // and generate ISA. | ||||
3119 | CudaDeviceActions[I] = | ||||
3120 | C.MakeAction<LinkJobAction>(AL, types::TY_Image); | ||||
3121 | } | ||||
3122 | |||||
3123 | // OffloadingActionBuilder propagates device arch until an offload | ||||
3124 | // action. Since the next action for creating fatbin does | ||||
3125 | // not have device arch, whereas the above link action and its input | ||||
3126 | // have device arch, an offload action is needed to stop the null | ||||
3127 | // device arch of the next action being propagated to the above link | ||||
3128 | // action. | ||||
3129 | OffloadAction::DeviceDependences DDep; | ||||
3130 | DDep.add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I], | ||||
3131 | AssociatedOffloadKind); | ||||
3132 | CudaDeviceActions[I] = C.MakeAction<OffloadAction>( | ||||
3133 | DDep, CudaDeviceActions[I]->getType()); | ||||
3134 | } | ||||
3135 | |||||
3136 | if (!CompileDeviceOnly || !BundleOutput.hasValue() || | ||||
3137 | BundleOutput.getValue()) { | ||||
3138 | // Create HIP fat binary with a special "link" action. | ||||
3139 | CudaFatBinary = C.MakeAction<LinkJobAction>(CudaDeviceActions, | ||||
3140 | types::TY_HIP_FATBIN); | ||||
3141 | |||||
3142 | if (!CompileDeviceOnly) { | ||||
3143 | DA.add(*CudaFatBinary, *ToolChains.front(), /*BoundArch=*/nullptr, | ||||
3144 | AssociatedOffloadKind); | ||||
3145 | // Clear the fat binary, it is already a dependence to an host | ||||
3146 | // action. | ||||
3147 | CudaFatBinary = nullptr; | ||||
3148 | } | ||||
3149 | |||||
3150 | // Remove the CUDA actions as they are already connected to an host | ||||
3151 | // action or fat binary. | ||||
3152 | CudaDeviceActions.clear(); | ||||
3153 | } | ||||
3154 | |||||
3155 | return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success; | ||||
3156 | } else if (CurPhase == phases::Link) { | ||||
3157 | // Save CudaDeviceActions to DeviceLinkerInputs for each GPU subarch. | ||||
3158 | // This happens to each device action originated from each input file. | ||||
3159 | // Later on, device actions in DeviceLinkerInputs are used to create | ||||
3160 | // device link actions in appendLinkDependences and the created device | ||||
3161 | // link actions are passed to the offload action as device dependence. | ||||
3162 | DeviceLinkerInputs.resize(CudaDeviceActions.size()); | ||||
3163 | auto LI = DeviceLinkerInputs.begin(); | ||||
3164 | for (auto *A : CudaDeviceActions) { | ||||
3165 | LI->push_back(A); | ||||
3166 | ++LI; | ||||
3167 | } | ||||
3168 | |||||
3169 | // We will pass the device action as a host dependence, so we don't | ||||
3170 | // need to do anything else with them. | ||||
3171 | CudaDeviceActions.clear(); | ||||
3172 | return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success; | ||||
3173 | } | ||||
3174 | |||||
3175 | // By default, we produce an action for each device arch. | ||||
3176 | for (Action *&A : CudaDeviceActions) | ||||
3177 | A = C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A, | ||||
3178 | AssociatedOffloadKind); | ||||
3179 | |||||
3180 | if (CompileDeviceOnly && CurPhase == FinalPhase && | ||||
3181 | BundleOutput.hasValue() && BundleOutput.getValue()) { | ||||
3182 | for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) { | ||||
3183 | OffloadAction::DeviceDependences DDep; | ||||
3184 | DDep.add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I], | ||||
3185 | AssociatedOffloadKind); | ||||
3186 | CudaDeviceActions[I] = C.MakeAction<OffloadAction>( | ||||
3187 | DDep, CudaDeviceActions[I]->getType()); | ||||
3188 | } | ||||
3189 | CudaFatBinary = | ||||
3190 | C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions); | ||||
3191 | CudaDeviceActions.clear(); | ||||
3192 | } | ||||
3193 | |||||
3194 | return (CompileDeviceOnly && CurPhase == FinalPhase) ? ABRT_Ignore_Host | ||||
3195 | : ABRT_Success; | ||||
3196 | } | ||||
3197 | |||||
3198 | void appendLinkDeviceActions(ActionList &AL) override { | ||||
3199 | if (DeviceLinkerInputs.size() == 0) | ||||
3200 | return; | ||||
3201 | |||||
3202 | assert(DeviceLinkerInputs.size() == GpuArchList.size() &&(static_cast <bool> (DeviceLinkerInputs.size() == GpuArchList .size() && "Linker inputs and GPU arch list sizes do not match." ) ? void (0) : __assert_fail ("DeviceLinkerInputs.size() == GpuArchList.size() && \"Linker inputs and GPU arch list sizes do not match.\"" , "clang/lib/Driver/Driver.cpp", 3203, __extension__ __PRETTY_FUNCTION__ )) | ||||
3203 | "Linker inputs and GPU arch list sizes do not match.")(static_cast <bool> (DeviceLinkerInputs.size() == GpuArchList .size() && "Linker inputs and GPU arch list sizes do not match." ) ? void (0) : __assert_fail ("DeviceLinkerInputs.size() == GpuArchList.size() && \"Linker inputs and GPU arch list sizes do not match.\"" , "clang/lib/Driver/Driver.cpp", 3203, __extension__ __PRETTY_FUNCTION__ )); | ||||
3204 | |||||
3205 | ActionList Actions; | ||||
3206 | // Append a new link action for each device. | ||||
3207 | unsigned I = 0; | ||||
3208 | for (auto &LI : DeviceLinkerInputs) { | ||||
3209 | // Each entry in DeviceLinkerInputs corresponds to a GPU arch. | ||||
3210 | auto *DeviceLinkAction = | ||||
3211 | C.MakeAction<LinkJobAction>(LI, types::TY_Image); | ||||
3212 | // Linking all inputs for the current GPU arch. | ||||
3213 | // LI contains all the inputs for the linker. | ||||
3214 | OffloadAction::DeviceDependences DeviceLinkDeps; | ||||
3215 | DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0], | ||||
3216 | GpuArchList[I], AssociatedOffloadKind); | ||||
3217 | Actions.push_back(C.MakeAction<OffloadAction>( | ||||
3218 | DeviceLinkDeps, DeviceLinkAction->getType())); | ||||
3219 | ++I; | ||||
3220 | } | ||||
3221 | DeviceLinkerInputs.clear(); | ||||
3222 | |||||
3223 | // Create a host object from all the device images by embedding them | ||||
3224 | // in a fat binary for mixed host-device compilation. For device-only | ||||
3225 | // compilation, creates a fat binary. | ||||
3226 | OffloadAction::DeviceDependences DDeps; | ||||
3227 | if (!CompileDeviceOnly || !BundleOutput.hasValue() || | ||||
3228 | BundleOutput.getValue()) { | ||||
3229 | auto *TopDeviceLinkAction = C.MakeAction<LinkJobAction>( | ||||
3230 | Actions, | ||||
3231 | CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object); | ||||
3232 | DDeps.add(*TopDeviceLinkAction, *ToolChains[0], nullptr, | ||||
3233 | AssociatedOffloadKind); | ||||
3234 | // Offload the host object to the host linker. | ||||
3235 | AL.push_back( | ||||
3236 | C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType())); | ||||
3237 | } else { | ||||
3238 | AL.append(Actions); | ||||
3239 | } | ||||
3240 | } | ||||
3241 | |||||
3242 | Action* appendLinkHostActions(ActionList &AL) override { return AL.back(); } | ||||
3243 | |||||
3244 | void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {} | ||||
3245 | }; | ||||
3246 | |||||
3247 | /// OpenMP action builder. The host bitcode is passed to the device frontend | ||||
3248 | /// and all the device linked images are passed to the host link phase. | ||||
3249 | class OpenMPActionBuilder final : public DeviceActionBuilder { | ||||
3250 | /// The OpenMP actions for the current input. | ||||
3251 | ActionList OpenMPDeviceActions; | ||||
3252 | |||||
3253 | /// The linker inputs obtained for each toolchain. | ||||
3254 | SmallVector<ActionList, 8> DeviceLinkerInputs; | ||||
3255 | |||||
3256 | public: | ||||
3257 | OpenMPActionBuilder(Compilation &C, DerivedArgList &Args, | ||||
3258 | const Driver::InputList &Inputs) | ||||
3259 | : DeviceActionBuilder(C, Args, Inputs, Action::OFK_OpenMP) {} | ||||
3260 | |||||
3261 | ActionBuilderReturnCode | ||||
3262 | getDeviceDependences(OffloadAction::DeviceDependences &DA, | ||||
3263 | phases::ID CurPhase, phases::ID FinalPhase, | ||||
3264 | PhasesTy &Phases) override { | ||||
3265 | if (OpenMPDeviceActions.empty()) | ||||
3266 | return ABRT_Inactive; | ||||
3267 | |||||
3268 | // We should always have an action for each input. | ||||
3269 | assert(OpenMPDeviceActions.size() == ToolChains.size() &&(static_cast <bool> (OpenMPDeviceActions.size() == ToolChains .size() && "Number of OpenMP actions and toolchains do not match." ) ? void (0) : __assert_fail ("OpenMPDeviceActions.size() == ToolChains.size() && \"Number of OpenMP actions and toolchains do not match.\"" , "clang/lib/Driver/Driver.cpp", 3270, __extension__ __PRETTY_FUNCTION__ )) | ||||
3270 | "Number of OpenMP actions and toolchains do not match.")(static_cast <bool> (OpenMPDeviceActions.size() == ToolChains .size() && "Number of OpenMP actions and toolchains do not match." ) ? void (0) : __assert_fail ("OpenMPDeviceActions.size() == ToolChains.size() && \"Number of OpenMP actions and toolchains do not match.\"" , "clang/lib/Driver/Driver.cpp", 3270, __extension__ __PRETTY_FUNCTION__ )); | ||||
3271 | |||||
3272 | // The host only depends on device action in the linking phase, when all | ||||
3273 | // the device images have to be embedded in the host image. | ||||
3274 | if (CurPhase == phases::Link) { | ||||
3275 | assert(ToolChains.size() == DeviceLinkerInputs.size() &&(static_cast <bool> (ToolChains.size() == DeviceLinkerInputs .size() && "Toolchains and linker inputs sizes do not match." ) ? void (0) : __assert_fail ("ToolChains.size() == DeviceLinkerInputs.size() && \"Toolchains and linker inputs sizes do not match.\"" , "clang/lib/Driver/Driver.cpp", 3276, __extension__ __PRETTY_FUNCTION__ )) | ||||
3276 | "Toolchains and linker inputs sizes do not match.")(static_cast <bool> (ToolChains.size() == DeviceLinkerInputs .size() && "Toolchains and linker inputs sizes do not match." ) ? void (0) : __assert_fail ("ToolChains.size() == DeviceLinkerInputs.size() && \"Toolchains and linker inputs sizes do not match.\"" , "clang/lib/Driver/Driver.cpp", 3276, __extension__ __PRETTY_FUNCTION__ )); | ||||
3277 | auto LI = DeviceLinkerInputs.begin(); | ||||
3278 | for (auto *A : OpenMPDeviceActions) { | ||||
3279 | LI->push_back(A); | ||||
3280 | ++LI; | ||||
3281 | } | ||||
3282 | |||||
3283 | // We passed the device action as a host dependence, so we don't need to | ||||
3284 | // do anything else with them. | ||||
3285 | OpenMPDeviceActions.clear(); | ||||
3286 | return ABRT_Success; | ||||
3287 | } | ||||
3288 | |||||
3289 | // By default, we produce an action for each device arch. | ||||
3290 | for (Action *&A : OpenMPDeviceActions) | ||||
3291 | A = C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A); | ||||
3292 | |||||
3293 | return ABRT_Success; | ||||
3294 | } | ||||
3295 | |||||
3296 | ActionBuilderReturnCode addDeviceDepences(Action *HostAction) override { | ||||
3297 | |||||
3298 | // If this is an input action replicate it for each OpenMP toolchain. | ||||
3299 | if (auto *IA = dyn_cast<InputAction>(HostAction)) { | ||||
3300 | OpenMPDeviceActions.clear(); | ||||
3301 | for (unsigned I = 0; I < ToolChains.size(); ++I) | ||||
3302 | OpenMPDeviceActions.push_back( | ||||
3303 | C.MakeAction<InputAction>(IA->getInputArg(), IA->getType())); | ||||
3304 | return ABRT_Success; | ||||
3305 | } | ||||
3306 | |||||
3307 | // If this is an unbundling action use it as is for each OpenMP toolchain. | ||||
3308 | if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) { | ||||
3309 | OpenMPDeviceActions.clear(); | ||||
3310 | auto *IA = cast<InputAction>(UA->getInputs().back()); | ||||
3311 | std::string FileName = IA->getInputArg().getAsString(Args); | ||||
3312 | // Check if the type of the file is the same as the action. Do not | ||||
3313 | // unbundle it if it is not. Do not unbundle .so files, for example, | ||||
3314 | // which are not object files. | ||||
3315 | if (IA->getType() == types::TY_Object && | ||||
3316 | (!llvm::sys::path::has_extension(FileName) || | ||||
3317 | types::lookupTypeForExtension( | ||||
3318 | llvm::sys::path::extension(FileName).drop_front()) != | ||||
3319 | types::TY_Object)) | ||||
3320 | return ABRT_Inactive; | ||||
3321 | for (unsigned I = 0; I < ToolChains.size(); ++I) { | ||||
3322 | OpenMPDeviceActions.push_back(UA); | ||||
3323 | UA->registerDependentActionInfo( | ||||
3324 | ToolChains[I], /*BoundArch=*/StringRef(), Action::OFK_OpenMP); | ||||
3325 | } | ||||
3326 | return ABRT_Success; | ||||
3327 | } | ||||
3328 | |||||
3329 | // When generating code for OpenMP we use the host compile phase result as | ||||
3330 | // a dependence to the device compile phase so that it can learn what | ||||
3331 | // declarations should be emitted. However, this is not the only use for | ||||
3332 | // the host action, so we prevent it from being collapsed. | ||||
3333 | if (isa<CompileJobAction>(HostAction)) { | ||||
3334 | HostAction->setCannotBeCollapsedWithNextDependentAction(); | ||||
3335 | assert(ToolChains.size() == OpenMPDeviceActions.size() &&(static_cast <bool> (ToolChains.size() == OpenMPDeviceActions .size() && "Toolchains and device action sizes do not match." ) ? void (0) : __assert_fail ("ToolChains.size() == OpenMPDeviceActions.size() && \"Toolchains and device action sizes do not match.\"" , "clang/lib/Driver/Driver.cpp", 3336, __extension__ __PRETTY_FUNCTION__ )) | ||||
3336 | "Toolchains and device action sizes do not match.")(static_cast <bool> (ToolChains.size() == OpenMPDeviceActions .size() && "Toolchains and device action sizes do not match." ) ? void (0) : __assert_fail ("ToolChains.size() == OpenMPDeviceActions.size() && \"Toolchains and device action sizes do not match.\"" , "clang/lib/Driver/Driver.cpp", 3336, __extension__ __PRETTY_FUNCTION__ )); | ||||
3337 | OffloadAction::HostDependence HDep( | ||||
3338 | *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(), | ||||
3339 | /*BoundArch=*/nullptr, Action::OFK_OpenMP); | ||||
3340 | auto TC = ToolChains.begin(); | ||||
3341 | for (Action *&A : OpenMPDeviceActions) { | ||||
3342 | assert(isa<CompileJobAction>(A))(static_cast <bool> (isa<CompileJobAction>(A)) ? void (0) : __assert_fail ("isa<CompileJobAction>(A)", "clang/lib/Driver/Driver.cpp" , 3342, __extension__ __PRETTY_FUNCTION__)); | ||||
3343 | OffloadAction::DeviceDependences DDep; | ||||
3344 | DDep.add(*A, **TC, /*BoundArch=*/nullptr, Action::OFK_OpenMP); | ||||
3345 | A = C.MakeAction<OffloadAction>(HDep, DDep); | ||||
3346 | ++TC; | ||||
3347 | } | ||||
3348 | } | ||||
3349 | return ABRT_Success; | ||||
3350 | } | ||||
3351 | |||||
3352 | void appendTopLevelActions(ActionList &AL) override { | ||||
3353 | if (OpenMPDeviceActions.empty()) | ||||
3354 | return; | ||||
3355 | |||||
3356 | // We should always have an action for each input. | ||||
3357 | assert(OpenMPDeviceActions.size() == ToolChains.size() &&(static_cast <bool> (OpenMPDeviceActions.size() == ToolChains .size() && "Number of OpenMP actions and toolchains do not match." ) ? void (0) : __assert_fail ("OpenMPDeviceActions.size() == ToolChains.size() && \"Number of OpenMP actions and toolchains do not match.\"" , "clang/lib/Driver/Driver.cpp", 3358, __extension__ __PRETTY_FUNCTION__ )) | ||||
3358 | "Number of OpenMP actions and toolchains do not match.")(static_cast <bool> (OpenMPDeviceActions.size() == ToolChains .size() && "Number of OpenMP actions and toolchains do not match." ) ? void (0) : __assert_fail ("OpenMPDeviceActions.size() == ToolChains.size() && \"Number of OpenMP actions and toolchains do not match.\"" , "clang/lib/Driver/Driver.cpp", 3358, __extension__ __PRETTY_FUNCTION__ )); | ||||
3359 | |||||
3360 | // Append all device actions followed by the proper offload action. | ||||
3361 | auto TI = ToolChains.begin(); | ||||
3362 | for (auto *A : OpenMPDeviceActions) { | ||||
3363 | OffloadAction::DeviceDependences Dep; | ||||
3364 | Dep.add(*A, **TI, /*BoundArch=*/nullptr, Action::OFK_OpenMP); | ||||
3365 | AL.push_back(C.MakeAction<OffloadAction>(Dep, A->getType())); | ||||
3366 | ++TI; | ||||
3367 | } | ||||
3368 | // We no longer need the action stored in this builder. | ||||
3369 | OpenMPDeviceActions.clear(); | ||||
3370 | } | ||||
3371 | |||||
3372 | void appendLinkDeviceActions(ActionList &AL) override { | ||||
3373 | assert(ToolChains.size() == DeviceLinkerInputs.size() &&(static_cast <bool> (ToolChains.size() == DeviceLinkerInputs .size() && "Toolchains and linker inputs sizes do not match." ) ? void (0) : __assert_fail ("ToolChains.size() == DeviceLinkerInputs.size() && \"Toolchains and linker inputs sizes do not match.\"" , "clang/lib/Driver/Driver.cpp", 3374, __extension__ __PRETTY_FUNCTION__ )) | ||||
3374 | "Toolchains and linker inputs sizes do not match.")(static_cast <bool> (ToolChains.size() == DeviceLinkerInputs .size() && "Toolchains and linker inputs sizes do not match." ) ? void (0) : __assert_fail ("ToolChains.size() == DeviceLinkerInputs.size() && \"Toolchains and linker inputs sizes do not match.\"" , "clang/lib/Driver/Driver.cpp", 3374, __extension__ __PRETTY_FUNCTION__ )); | ||||
3375 | |||||
3376 | // Append a new link action for each device. | ||||
3377 | auto TC = ToolChains.begin(); | ||||
3378 | for (auto &LI : DeviceLinkerInputs) { | ||||
3379 | auto *DeviceLinkAction = | ||||
3380 | C.MakeAction<LinkJobAction>(LI, types::TY_Image); | ||||
3381 | OffloadAction::DeviceDependences DeviceLinkDeps; | ||||
3382 | DeviceLinkDeps.add(*DeviceLinkAction, **TC, /*BoundArch=*/nullptr, | ||||
3383 | Action::OFK_OpenMP); | ||||
3384 | AL.push_back(C.MakeAction<OffloadAction>(DeviceLinkDeps, | ||||
3385 | DeviceLinkAction->getType())); | ||||
3386 | ++TC; | ||||
3387 | } | ||||
3388 | DeviceLinkerInputs.clear(); | ||||
3389 | } | ||||
3390 | |||||
3391 | Action* appendLinkHostActions(ActionList &AL) override { | ||||
3392 | // Create wrapper bitcode from the result of device link actions and compile | ||||
3393 | // it to an object which will be added to the host link command. | ||||
3394 | auto *BC = C.MakeAction<OffloadWrapperJobAction>(AL, types::TY_LLVM_BC); | ||||
3395 | auto *ASM = C.MakeAction<BackendJobAction>(BC, types::TY_PP_Asm); | ||||
3396 | return C.MakeAction<AssembleJobAction>(ASM, types::TY_Object); | ||||
3397 | } | ||||
3398 | |||||
3399 | void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {} | ||||
3400 | |||||
3401 | bool initialize() override { | ||||
3402 | // Get the OpenMP toolchains. If we don't get any, the action builder will | ||||
3403 | // know there is nothing to do related to OpenMP offloading. | ||||
3404 | auto OpenMPTCRange = C.getOffloadToolChains<Action::OFK_OpenMP>(); | ||||
3405 | for (auto TI = OpenMPTCRange.first, TE = OpenMPTCRange.second; TI != TE; | ||||
3406 | ++TI) | ||||
3407 | ToolChains.push_back(TI->second); | ||||
3408 | |||||
3409 | DeviceLinkerInputs.resize(ToolChains.size()); | ||||
3410 | return false; | ||||
3411 | } | ||||
3412 | |||||
3413 | bool canUseBundlerUnbundler() const override { | ||||
3414 | // OpenMP should use bundled files whenever possible. | ||||
3415 | return true; | ||||
3416 | } | ||||
3417 | }; | ||||
3418 | |||||
3419 | /// | ||||
3420 | /// TODO: Add the implementation for other specialized builders here. | ||||
3421 | /// | ||||
3422 | |||||
3423 | /// Specialized builders being used by this offloading action builder. | ||||
3424 | SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders; | ||||
3425 | |||||
3426 | /// Flag set to true if all valid builders allow file bundling/unbundling. | ||||
3427 | bool CanUseBundler; | ||||
3428 | |||||
3429 | public: | ||||
3430 | OffloadingActionBuilder(Compilation &C, DerivedArgList &Args, | ||||
3431 | const Driver::InputList &Inputs) | ||||
3432 | : C(C) { | ||||
3433 | // Create a specialized builder for each device toolchain. | ||||
3434 | |||||
3435 | IsValid = true; | ||||
3436 | |||||
3437 | // Create a specialized builder for CUDA. | ||||
3438 | SpecializedBuilders.push_back(new CudaActionBuilder(C, Args, Inputs)); | ||||
3439 | |||||
3440 | // Create a specialized builder for HIP. | ||||
3441 | SpecializedBuilders.push_back(new HIPActionBuilder(C, Args, Inputs)); | ||||
3442 | |||||
3443 | // Create a specialized builder for OpenMP. | ||||
3444 | SpecializedBuilders.push_back(new OpenMPActionBuilder(C, Args, Inputs)); | ||||
3445 | |||||
3446 | // | ||||
3447 | // TODO: Build other specialized builders here. | ||||
3448 | // | ||||
3449 | |||||
3450 | // Initialize all the builders, keeping track of errors. If all valid | ||||
3451 | // builders agree that we can use bundling, set the flag to true. | ||||
3452 | unsigned ValidBuilders = 0u; | ||||
3453 | unsigned ValidBuildersSupportingBundling = 0u; | ||||
3454 | for (auto *SB : SpecializedBuilders) { | ||||
3455 | IsValid = IsValid && !SB->initialize(); | ||||
3456 | |||||
3457 | // Update the counters if the builder is valid. | ||||
3458 | if (SB->isValid()) { | ||||
3459 | ++ValidBuilders; | ||||
3460 | if (SB->canUseBundlerUnbundler()) | ||||
3461 | ++ValidBuildersSupportingBundling; | ||||
3462 | } | ||||
3463 | } | ||||
3464 | CanUseBundler = | ||||
3465 | ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling; | ||||
3466 | } | ||||
3467 | |||||
3468 | ~OffloadingActionBuilder() { | ||||
3469 | for (auto *SB : SpecializedBuilders) | ||||
3470 | delete SB; | ||||
3471 | } | ||||
3472 | |||||
3473 | /// Record a host action and its originating input argument. | ||||
3474 | void recordHostAction(Action *HostAction, const Arg *InputArg) { | ||||
3475 | assert(HostAction && "Invalid host action")(static_cast <bool> (HostAction && "Invalid host action" ) ? void (0) : __assert_fail ("HostAction && \"Invalid host action\"" , "clang/lib/Driver/Driver.cpp", 3475, __extension__ __PRETTY_FUNCTION__ )); | ||||
3476 | assert(InputArg && "Invalid input argument")(static_cast <bool> (InputArg && "Invalid input argument" ) ? void (0) : __assert_fail ("InputArg && \"Invalid input argument\"" , "clang/lib/Driver/Driver.cpp", 3476, __extension__ __PRETTY_FUNCTION__ )); | ||||
3477 | auto Loc = HostActionToInputArgMap.find(HostAction); | ||||
3478 | if (Loc == HostActionToInputArgMap.end()) | ||||
3479 | HostActionToInputArgMap[HostAction] = InputArg; | ||||
3480 | assert(HostActionToInputArgMap[HostAction] == InputArg &&(static_cast <bool> (HostActionToInputArgMap[HostAction ] == InputArg && "host action mapped to multiple input arguments" ) ? void (0) : __assert_fail ("HostActionToInputArgMap[HostAction] == InputArg && \"host action mapped to multiple input arguments\"" , "clang/lib/Driver/Driver.cpp", 3481, __extension__ __PRETTY_FUNCTION__ )) | ||||
3481 | "host action mapped to multiple input arguments")(static_cast <bool> (HostActionToInputArgMap[HostAction ] == InputArg && "host action mapped to multiple input arguments" ) ? void (0) : __assert_fail ("HostActionToInputArgMap[HostAction] == InputArg && \"host action mapped to multiple input arguments\"" , "clang/lib/Driver/Driver.cpp", 3481, __extension__ __PRETTY_FUNCTION__ )); | ||||
3482 | } | ||||
3483 | |||||
3484 | /// Generate an action that adds device dependences (if any) to a host action. | ||||
3485 | /// If no device dependence actions exist, just return the host action \a | ||||
3486 | /// HostAction. If an error is found or if no builder requires the host action | ||||
3487 | /// to be generated, return nullptr. | ||||
3488 | Action * | ||||
3489 | addDeviceDependencesToHostAction(Action *HostAction, const Arg *InputArg, | ||||
3490 | phases::ID CurPhase, phases::ID FinalPhase, | ||||
3491 | DeviceActionBuilder::PhasesTy &Phases) { | ||||
3492 | if (!IsValid) | ||||
3493 | return nullptr; | ||||
3494 | |||||
3495 | if (SpecializedBuilders.empty()) | ||||
3496 | return HostAction; | ||||
3497 | |||||
3498 | assert(HostAction && "Invalid host action!")(static_cast <bool> (HostAction && "Invalid host action!" ) ? void (0) : __assert_fail ("HostAction && \"Invalid host action!\"" , "clang/lib/Driver/Driver.cpp", 3498, __extension__ __PRETTY_FUNCTION__ )); | ||||
3499 | recordHostAction(HostAction, InputArg); | ||||
3500 | |||||
3501 | OffloadAction::DeviceDependences DDeps; | ||||
3502 | // Check if all the programming models agree we should not emit the host | ||||
3503 | // action. Also, keep track of the offloading kinds employed. | ||||
3504 | auto &OffloadKind = InputArgToOffloadKindMap[InputArg]; | ||||
3505 | unsigned InactiveBuilders = 0u; | ||||
3506 | unsigned IgnoringBuilders = 0u; | ||||
3507 | for (auto *SB : SpecializedBuilders) { | ||||
3508 | if (!SB->isValid()) { | ||||
3509 | ++InactiveBuilders; | ||||
3510 | continue; | ||||
3511 | } | ||||
3512 | |||||
3513 | auto RetCode = | ||||
3514 | SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases); | ||||
3515 | |||||
3516 | // If the builder explicitly says the host action should be ignored, | ||||
3517 | // we need to increment the variable that tracks the builders that request | ||||
3518 | // the host object to be ignored. | ||||
3519 | if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host) | ||||
3520 | ++IgnoringBuilders; | ||||
3521 | |||||
3522 | // Unless the builder was inactive for this action, we have to record the | ||||
3523 | // offload kind because the host will have to use it. | ||||
3524 | if (RetCode != DeviceActionBuilder::ABRT_Inactive) | ||||
3525 | OffloadKind |= SB->getAssociatedOffloadKind(); | ||||
3526 | } | ||||
3527 | |||||
3528 | // If all builders agree that the host object should be ignored, just return | ||||
3529 | // nullptr. | ||||
3530 | if (IgnoringBuilders && | ||||
3531 | SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders)) | ||||
3532 | return nullptr; | ||||
3533 | |||||
3534 | if (DDeps.getActions().empty()) | ||||
3535 | return HostAction; | ||||
3536 | |||||
3537 | // We have dependences we need to bundle together. We use an offload action | ||||
3538 | // for that. | ||||
3539 | OffloadAction::HostDependence HDep( | ||||
3540 | *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(), | ||||
3541 | /*BoundArch=*/nullptr, DDeps); | ||||
3542 | return C.MakeAction<OffloadAction>(HDep, DDeps); | ||||
3543 | } | ||||
3544 | |||||
3545 | /// Generate an action that adds a host dependence to a device action. The | ||||
3546 | /// results will be kept in this action builder. Return true if an error was | ||||
3547 | /// found. | ||||
3548 | bool addHostDependenceToDeviceActions(Action *&HostAction, | ||||
3549 | const Arg *InputArg) { | ||||
3550 | if (!IsValid) | ||||
3551 | return true; | ||||
3552 | |||||
3553 | recordHostAction(HostAction, InputArg); | ||||
3554 | |||||
3555 | // If we are supporting bundling/unbundling and the current action is an | ||||
3556 | // input action of non-source file, we replace the host action by the | ||||
3557 | // unbundling action. The bundler tool has the logic to detect if an input | ||||
3558 | // is a bundle or not and if the input is not a bundle it assumes it is a | ||||
3559 | // host file. Therefore it is safe to create an unbundling action even if | ||||
3560 | // the input is not a bundle. | ||||
3561 | if (CanUseBundler && isa<InputAction>(HostAction) && | ||||
3562 | InputArg->getOption().getKind() == llvm::opt::Option::InputClass && | ||||
3563 | (!types::isSrcFile(HostAction->getType()) || | ||||
3564 | HostAction->getType() == types::TY_PP_HIP)) { | ||||
3565 | auto UnbundlingHostAction = | ||||
3566 | C.MakeAction<OffloadUnbundlingJobAction>(HostAction); | ||||
3567 | UnbundlingHostAction->registerDependentActionInfo( | ||||
3568 | C.getSingleOffloadToolChain<Action::OFK_Host>(), | ||||
3569 | /*BoundArch=*/StringRef(), Action::OFK_Host); | ||||
3570 | HostAction = UnbundlingHostAction; | ||||
3571 | recordHostAction(HostAction, InputArg); | ||||
3572 | } | ||||
3573 | |||||
3574 | assert(HostAction && "Invalid host action!")(static_cast <bool> (HostAction && "Invalid host action!" ) ? void (0) : __assert_fail ("HostAction && \"Invalid host action!\"" , "clang/lib/Driver/Driver.cpp", 3574, __extension__ __PRETTY_FUNCTION__ )); | ||||
3575 | |||||
3576 | // Register the offload kinds that are used. | ||||
3577 | auto &OffloadKind = InputArgToOffloadKindMap[InputArg]; | ||||
3578 | for (auto *SB : SpecializedBuilders) { | ||||
3579 | if (!SB->isValid()) | ||||
3580 | continue; | ||||
3581 | |||||
3582 | auto RetCode = SB->addDeviceDepences(HostAction); | ||||
3583 | |||||
3584 | // Host dependences for device actions are not compatible with that same | ||||
3585 | // action being ignored. | ||||
3586 | assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&(static_cast <bool> (RetCode != DeviceActionBuilder::ABRT_Ignore_Host && "Host dependence not expected to be ignored.!") ? void (0) : __assert_fail ("RetCode != DeviceActionBuilder::ABRT_Ignore_Host && \"Host dependence not expected to be ignored.!\"" , "clang/lib/Driver/Driver.cpp", 3587, __extension__ __PRETTY_FUNCTION__ )) | ||||
3587 | "Host dependence not expected to be ignored.!")(static_cast <bool> (RetCode != DeviceActionBuilder::ABRT_Ignore_Host && "Host dependence not expected to be ignored.!") ? void (0) : __assert_fail ("RetCode != DeviceActionBuilder::ABRT_Ignore_Host && \"Host dependence not expected to be ignored.!\"" , "clang/lib/Driver/Driver.cpp", 3587, __extension__ __PRETTY_FUNCTION__ )); | ||||
3588 | |||||
3589 | // Unless the builder was inactive for this action, we have to record the | ||||
3590 | // offload kind because the host will have to use it. | ||||
3591 | if (RetCode != DeviceActionBuilder::ABRT_Inactive) | ||||
3592 | OffloadKind |= SB->getAssociatedOffloadKind(); | ||||
3593 | } | ||||
3594 | |||||
3595 | // Do not use unbundler if the Host does not depend on device action. | ||||
3596 | if (OffloadKind == Action::OFK_None && CanUseBundler) | ||||
3597 | if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) | ||||
3598 | HostAction = UA->getInputs().back(); | ||||
3599 | |||||
3600 | return false; | ||||
3601 | } | ||||
3602 | |||||
3603 | /// Add the offloading top level actions to the provided action list. This | ||||
3604 | /// function can replace the host action by a bundling action if the | ||||
3605 | /// programming models allow it. | ||||
3606 | bool appendTopLevelActions(ActionList &AL, Action *HostAction, | ||||
3607 | const Arg *InputArg) { | ||||
3608 | if (HostAction) | ||||
3609 | recordHostAction(HostAction, InputArg); | ||||
3610 | |||||
3611 | // Get the device actions to be appended. | ||||
3612 | ActionList OffloadAL; | ||||
3613 | for (auto *SB : SpecializedBuilders) { | ||||
3614 | if (!SB->isValid()) | ||||
3615 | continue; | ||||
3616 | SB->appendTopLevelActions(OffloadAL); | ||||
3617 | } | ||||
3618 | |||||
3619 | // If we can use the bundler, replace the host action by the bundling one in | ||||
3620 | // the resulting list. Otherwise, just append the device actions. For | ||||
3621 | // device only compilation, HostAction is a null pointer, therefore only do | ||||
3622 | // this when HostAction is not a null pointer. | ||||
3623 | if (CanUseBundler && HostAction && | ||||
3624 | HostAction->getType() != types::TY_Nothing && !OffloadAL.empty()) { | ||||
3625 | // Add the host action to the list in order to create the bundling action. | ||||
3626 | OffloadAL.push_back(HostAction); | ||||
3627 | |||||
3628 | // We expect that the host action was just appended to the action list | ||||
3629 | // before this method was called. | ||||
3630 | assert(HostAction == AL.back() && "Host action not in the list??")(static_cast <bool> (HostAction == AL.back() && "Host action not in the list??") ? void (0) : __assert_fail ( "HostAction == AL.back() && \"Host action not in the list??\"" , "clang/lib/Driver/Driver.cpp", 3630, __extension__ __PRETTY_FUNCTION__ )); | ||||
3631 | HostAction = C.MakeAction<OffloadBundlingJobAction>(OffloadAL); | ||||
3632 | recordHostAction(HostAction, InputArg); | ||||
3633 | AL.back() = HostAction; | ||||
3634 | } else | ||||
3635 | AL.append(OffloadAL.begin(), OffloadAL.end()); | ||||
3636 | |||||
3637 | // Propagate to the current host action (if any) the offload information | ||||
3638 | // associated with the current input. | ||||
3639 | if (HostAction) | ||||
3640 | HostAction->propagateHostOffloadInfo(InputArgToOffloadKindMap[InputArg], | ||||
3641 | /*BoundArch=*/nullptr); | ||||
3642 | return false; | ||||
3643 | } | ||||
3644 | |||||
3645 | void appendDeviceLinkActions(ActionList &AL) { | ||||
3646 | for (DeviceActionBuilder *SB : SpecializedBuilders) { | ||||
3647 | if (!SB->isValid()) | ||||
3648 | continue; | ||||
3649 | SB->appendLinkDeviceActions(AL); | ||||
3650 | } | ||||
3651 | } | ||||
3652 | |||||
3653 | Action *makeHostLinkAction() { | ||||
3654 | // Build a list of device linking actions. | ||||
3655 | ActionList DeviceAL; | ||||
3656 | appendDeviceLinkActions(DeviceAL); | ||||
3657 | if (DeviceAL.empty()) | ||||
3658 | return nullptr; | ||||
3659 | |||||
3660 | // Let builders add host linking actions. | ||||
3661 | Action* HA = nullptr; | ||||
3662 | for (DeviceActionBuilder *SB : SpecializedBuilders) { | ||||
3663 | if (!SB->isValid()) | ||||
3664 | continue; | ||||
3665 | HA = SB->appendLinkHostActions(DeviceAL); | ||||
3666 | // This created host action has no originating input argument, therefore | ||||
3667 | // needs to set its offloading kind directly. | ||||
3668 | if (HA) | ||||
3669 | HA->propagateHostOffloadInfo(SB->getAssociatedOffloadKind(), | ||||
3670 | /*BoundArch=*/nullptr); | ||||
3671 | } | ||||
3672 | return HA; | ||||
3673 | } | ||||
3674 | |||||
3675 | /// Processes the host linker action. This currently consists of replacing it | ||||
3676 | /// with an offload action if there are device link objects and propagate to | ||||
3677 | /// the host action all the offload kinds used in the current compilation. The | ||||
3678 | /// resulting action is returned. | ||||
3679 | Action *processHostLinkAction(Action *HostAction) { | ||||
3680 | // Add all the dependences from the device linking actions. | ||||
3681 | OffloadAction::DeviceDependences DDeps; | ||||
3682 | for (auto *SB : SpecializedBuilders) { | ||||
3683 | if (!SB->isValid()) | ||||
3684 | continue; | ||||
3685 | |||||
3686 | SB->appendLinkDependences(DDeps); | ||||
3687 | } | ||||
3688 | |||||
3689 | // Calculate all the offload kinds used in the current compilation. | ||||
3690 | unsigned ActiveOffloadKinds = 0u; | ||||
3691 | for (auto &I : InputArgToOffloadKindMap) | ||||
3692 | ActiveOffloadKinds |= I.second; | ||||
3693 | |||||
3694 | // If we don't have device dependencies, we don't have to create an offload | ||||
3695 | // action. | ||||
3696 | if (DDeps.getActions().empty()) { | ||||
3697 | // Set all the active offloading kinds to the link action. Given that it | ||||
3698 | // is a link action it is assumed to depend on all actions generated so | ||||
3699 | // far. | ||||
3700 | HostAction->setHostOffloadInfo(ActiveOffloadKinds, | ||||
3701 | /*BoundArch=*/nullptr); | ||||
3702 | // Propagate active offloading kinds for each input to the link action. | ||||
3703 | // Each input may have different active offloading kind. | ||||
3704 | for (auto A : HostAction->inputs()) { | ||||
3705 | auto ArgLoc = HostActionToInputArgMap.find(A); | ||||
3706 | if (ArgLoc == HostActionToInputArgMap.end()) | ||||
3707 | continue; | ||||
3708 | auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second); | ||||
3709 | if (OFKLoc == InputArgToOffloadKindMap.end()) | ||||
3710 | continue; | ||||
3711 | A->propagateHostOffloadInfo(OFKLoc->second, /*BoundArch=*/nullptr); | ||||
3712 | } | ||||
3713 | return HostAction; | ||||
3714 | } | ||||
3715 | |||||
3716 | // Create the offload action with all dependences. When an offload action | ||||
3717 | // is created the kinds are propagated to the host action, so we don't have | ||||
3718 | // to do that explicitly here. | ||||
3719 | OffloadAction::HostDependence HDep( | ||||
3720 | *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(), | ||||
3721 | /*BoundArch*/ nullptr, ActiveOffloadKinds); | ||||
3722 | return C.MakeAction<OffloadAction>(HDep, DDeps); | ||||
3723 | } | ||||
3724 | }; | ||||
3725 | } // anonymous namespace. | ||||
3726 | |||||
3727 | void Driver::handleArguments(Compilation &C, DerivedArgList &Args, | ||||
3728 | const InputList &Inputs, | ||||
3729 | ActionList &Actions) const { | ||||
3730 | |||||
3731 | // Ignore /Yc/Yu if both /Yc and /Yu passed but with different filenames. | ||||
3732 | Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc); | ||||
3733 | Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu); | ||||
3734 | if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) { | ||||
3735 | Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl); | ||||
3736 | Args.eraseArg(options::OPT__SLASH_Yc); | ||||
3737 | Args.eraseArg(options::OPT__SLASH_Yu); | ||||
3738 | YcArg = YuArg = nullptr; | ||||
3739 | } | ||||
3740 | if (YcArg && Inputs.size() > 1) { | ||||
3741 | Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl); | ||||
3742 | Args.eraseArg(options::OPT__SLASH_Yc); | ||||
3743 | YcArg = nullptr; | ||||
3744 | } | ||||
3745 | |||||
3746 | Arg *FinalPhaseArg; | ||||
3747 | phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg); | ||||
3748 | |||||
3749 | if (FinalPhase == phases::Link) { | ||||
3750 | if (Args.hasArg(options::OPT_emit_llvm)) | ||||
3751 | Diag(clang::diag::err_drv_emit_llvm_link); | ||||
3752 | if (IsCLMode() && LTOMode != LTOK_None && | ||||
3753 | !Args.getLastArgValue(options::OPT_fuse_ld_EQ) | ||||
3754 | .equals_insensitive("lld")) | ||||
3755 | Diag(clang::diag::err_drv_lto_without_lld); | ||||
3756 | } | ||||
3757 | |||||
3758 | if (FinalPhase == phases::Preprocess || Args.hasArg(options::OPT__SLASH_Y_)) { | ||||
3759 | // If only preprocessing or /Y- is used, all pch handling is disabled. | ||||
3760 | // Rather than check for it everywhere, just remove clang-cl pch-related | ||||
3761 | // flags here. | ||||
3762 | Args.eraseArg(options::OPT__SLASH_Fp); | ||||
3763 | Args.eraseArg(options::OPT__SLASH_Yc); | ||||
3764 | Args.eraseArg(options::OPT__SLASH_Yu); | ||||
3765 | YcArg = YuArg = nullptr; | ||||
3766 | } | ||||
3767 | |||||
3768 | unsigned LastPLSize = 0; | ||||
3769 | for (auto &I : Inputs) { | ||||
3770 | types::ID InputType = I.first; | ||||
3771 | const Arg *InputArg = I.second; | ||||
3772 | |||||
3773 | auto PL = types::getCompilationPhases(InputType); | ||||
3774 | LastPLSize = PL.size(); | ||||
3775 | |||||
3776 | // If the first step comes after the final phase we are doing as part of | ||||
3777 | // this compilation, warn the user about it. | ||||
3778 | phases::ID InitialPhase = PL[0]; | ||||
3779 | if (InitialPhase > FinalPhase) { | ||||
3780 | if (InputArg->isClaimed()) | ||||
3781 | continue; | ||||
3782 | |||||
3783 | // Claim here to avoid the more general unused warning. | ||||
3784 | InputArg->claim(); | ||||
3785 | |||||
3786 | // Suppress all unused style warnings with -Qunused-arguments | ||||
3787 | if (Args.hasArg(options::OPT_Qunused_arguments)) | ||||
3788 | continue; | ||||
3789 | |||||
3790 | // Special case when final phase determined by binary name, rather than | ||||
3791 | // by a command-line argument with a corresponding Arg. | ||||
3792 | if (CCCIsCPP()) | ||||
3793 | Diag(clang::diag::warn_drv_input_file_unused_by_cpp) | ||||
3794 | << InputArg->getAsString(Args) << getPhaseName(InitialPhase); | ||||
3795 | // Special case '-E' warning on a previously preprocessed file to make | ||||
3796 | // more sense. | ||||
3797 | else if (InitialPhase == phases::Compile && | ||||
3798 | (Args.getLastArg(options::OPT__SLASH_EP, | ||||
3799 | options::OPT__SLASH_P) || | ||||
3800 | Args.getLastArg(options::OPT_E) || | ||||
3801 | Args.getLastArg(options::OPT_M, options::OPT_MM)) && | ||||
3802 | getPreprocessedType(InputType) == types::TY_INVALID) | ||||
3803 | Diag(clang::diag::warn_drv_preprocessed_input_file_unused) | ||||
3804 | << InputArg->getAsString(Args) << !!FinalPhaseArg | ||||
3805 | << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : ""); | ||||
3806 | else | ||||
3807 | Diag(clang::diag::warn_drv_input_file_unused) | ||||
3808 | << InputArg->getAsString(Args) << getPhaseName(InitialPhase) | ||||
3809 | << !!FinalPhaseArg | ||||
3810 | << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : ""); | ||||
3811 | continue; | ||||
3812 | } | ||||
3813 | |||||
3814 | if (YcArg) { | ||||
3815 | // Add a separate precompile phase for the compile phase. | ||||
3816 | if (FinalPhase >= phases::Compile) { | ||||
3817 | const types::ID HeaderType = lookupHeaderTypeForSourceType(InputType); | ||||
3818 | // Build the pipeline for the pch file. | ||||
3819 | Action *ClangClPch = C.MakeAction<InputAction>(*InputArg, HeaderType); | ||||
3820 | for (phases::ID Phase : types::getCompilationPhases(HeaderType)) | ||||
3821 | ClangClPch = ConstructPhaseAction(C, Args, Phase, ClangClPch); | ||||
3822 | assert(ClangClPch)(static_cast <bool> (ClangClPch) ? void (0) : __assert_fail ("ClangClPch", "clang/lib/Driver/Driver.cpp", 3822, __extension__ __PRETTY_FUNCTION__)); | ||||
3823 | Actions.push_back(ClangClPch); | ||||
3824 | // The driver currently exits after the first failed command. This | ||||
3825 | // relies on that behavior, to make sure if the pch generation fails, | ||||
3826 | // the main compilation won't run. | ||||
3827 | // FIXME: If the main compilation fails, the PCH generation should | ||||
3828 | // probably not be considered successful either. | ||||
3829 | } | ||||
3830 | } | ||||
3831 | } | ||||
3832 | |||||
3833 | // If we are linking, claim any options which are obviously only used for | ||||
3834 | // compilation. | ||||
3835 | // FIXME: Understand why the last Phase List length is used here. | ||||
3836 | if (FinalPhase == phases::Link && LastPLSize == 1) { | ||||
3837 | Args.ClaimAllArgs(options::OPT_CompileOnly_Group); | ||||
3838 | Args.ClaimAllArgs(options::OPT_cl_compile_Group); | ||||
3839 | } | ||||
3840 | } | ||||
3841 | |||||
3842 | void Driver::BuildActions(Compilation &C, DerivedArgList &Args, | ||||
3843 | const InputList &Inputs, ActionList &Actions) const { | ||||
3844 | llvm::PrettyStackTraceString CrashInfo("Building compilation actions"); | ||||
3845 | |||||
3846 | if (!SuppressMissingInputWarning && Inputs.empty()) { | ||||
3847 | Diag(clang::diag::err_drv_no_input_files); | ||||
3848 | return; | ||||
3849 | } | ||||
3850 | |||||
3851 | // Reject -Z* at the top level, these options should never have been exposed | ||||
3852 | // by gcc. | ||||
3853 | if (Arg *A = Args.getLastArg(options::OPT_Z_Joined)) | ||||
3854 | Diag(clang::diag::err_drv_use_of_Z_option) << A->getAsString(Args); | ||||
3855 | |||||
3856 | // Diagnose misuse of /Fo. | ||||
3857 | if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) { | ||||
3858 | StringRef V = A->getValue(); | ||||
3859 | if (Inputs.size() > 1 && !V.empty() && | ||||
3860 | !llvm::sys::path::is_separator(V.back())) { | ||||
3861 | // Check whether /Fo tries to name an output file for multiple inputs. | ||||
3862 | Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources) | ||||
3863 | << A->getSpelling() << V; | ||||
3864 | Args.eraseArg(options::OPT__SLASH_Fo); | ||||
3865 | } | ||||
3866 | } | ||||
3867 | |||||
3868 | // Diagnose misuse of /Fa. | ||||
3869 | if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) { | ||||
3870 | StringRef V = A->getValue(); | ||||
3871 | if (Inputs.size() > 1 && !V.empty() && | ||||
3872 | !llvm::sys::path::is_separator(V.back())) { | ||||
3873 | // Check whether /Fa tries to name an asm file for multiple inputs. | ||||
3874 | Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources) | ||||
3875 | << A->getSpelling() << V; | ||||
3876 | Args.eraseArg(options::OPT__SLASH_Fa); | ||||
3877 | } | ||||
3878 | } | ||||
3879 | |||||
3880 | // Diagnose misuse of /o. | ||||
3881 | if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) { | ||||
3882 | if (A->getValue()[0] == '\0') { | ||||
3883 | // It has to have a value. | ||||
3884 | Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1; | ||||
3885 | Args.eraseArg(options::OPT__SLASH_o); | ||||
3886 | } | ||||
3887 | } | ||||
3888 | |||||
3889 | handleArguments(C, Args, Inputs, Actions); | ||||
3890 | |||||
3891 | // Builder to be used to build offloading actions. | ||||
3892 | OffloadingActionBuilder OffloadBuilder(C, Args, Inputs); | ||||
3893 | |||||
3894 | // Construct the actions to perform. | ||||
3895 | HeaderModulePrecompileJobAction *HeaderModuleAction = nullptr; | ||||
3896 | ExtractAPIJobAction *ExtractAPIAction = nullptr; | ||||
3897 | ActionList LinkerInputs; | ||||
3898 | ActionList MergerInputs; | ||||
3899 | |||||
3900 | bool UseNewOffloadingDriver = | ||||
3901 | C.isOffloadingHostKind(Action::OFK_OpenMP) && | ||||
3902 | !Args.hasArg(options::OPT_fno_openmp_new_driver); | ||||
3903 | |||||
3904 | for (auto &I : Inputs) { | ||||
3905 | types::ID InputType = I.first; | ||||
3906 | const Arg *InputArg = I.second; | ||||
3907 | |||||
3908 | auto PL = types::getCompilationPhases(*this, Args, InputType); | ||||
3909 | if (PL.empty()) | ||||
3910 | continue; | ||||
3911 | |||||
3912 | auto FullPL = types::getCompilationPhases(InputType); | ||||
3913 | |||||
3914 | // Build the pipeline for this file. | ||||
3915 | Action *Current = C.MakeAction<InputAction>(*InputArg, InputType); | ||||
3916 | |||||
3917 | // Use the current host action in any of the offloading actions, if | ||||
3918 | // required. | ||||
3919 | if (!UseNewOffloadingDriver) | ||||
3920 | if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg)) | ||||
3921 | break; | ||||
3922 | |||||
3923 | for (phases::ID Phase : PL) { | ||||
3924 | |||||
3925 | // Add any offload action the host action depends on. | ||||
3926 | if (!UseNewOffloadingDriver) | ||||
3927 | Current = OffloadBuilder.addDeviceDependencesToHostAction( | ||||
3928 | Current, InputArg, Phase, PL.back(), FullPL); | ||||
3929 | if (!Current) | ||||
3930 | break; | ||||
3931 | |||||
3932 | // Queue linker inputs. | ||||
3933 | if (Phase == phases::Link) { | ||||
3934 | assert(Phase == PL.back() && "linking must be final compilation step.")(static_cast <bool> (Phase == PL.back() && "linking must be final compilation step." ) ? void (0) : __assert_fail ("Phase == PL.back() && \"linking must be final compilation step.\"" , "clang/lib/Driver/Driver.cpp", 3934, __extension__ __PRETTY_FUNCTION__ )); | ||||
3935 | LinkerInputs.push_back(Current); | ||||
3936 | Current = nullptr; | ||||
3937 | break; | ||||
3938 | } | ||||
3939 | |||||
3940 | // TODO: Consider removing this because the merged may not end up being | ||||
3941 | // the final Phase in the pipeline. Perhaps the merged could just merge | ||||
3942 | // and then pass an artifact of some sort to the Link Phase. | ||||
3943 | // Queue merger inputs. | ||||
3944 | if (Phase == phases::IfsMerge) { | ||||
3945 | assert(Phase == PL.back() && "merging must be final compilation step.")(static_cast <bool> (Phase == PL.back() && "merging must be final compilation step." ) ? void (0) : __assert_fail ("Phase == PL.back() && \"merging must be final compilation step.\"" , "clang/lib/Driver/Driver.cpp", 3945, __extension__ __PRETTY_FUNCTION__ )); | ||||
3946 | MergerInputs.push_back(Current); | ||||
3947 | Current = nullptr; | ||||
3948 | break; | ||||
3949 | } | ||||
3950 | |||||
3951 | // Each precompiled header file after a module file action is a module | ||||
3952 | // header of that same module file, rather than being compiled to a | ||||
3953 | // separate PCH. | ||||
3954 | if (Phase == phases::Precompile && HeaderModuleAction && | ||||
3955 | getPrecompiledType(InputType) == types::TY_PCH) { | ||||
3956 | HeaderModuleAction->addModuleHeaderInput(Current); | ||||
3957 | Current = nullptr; | ||||
3958 | break; | ||||
3959 | } | ||||
3960 | |||||
3961 | if (Phase == phases::Precompile && ExtractAPIAction) { | ||||
3962 | ExtractAPIAction->addHeaderInput(Current); | ||||
3963 | Current = nullptr; | ||||
3964 | break; | ||||
3965 | } | ||||
3966 | |||||
3967 | // Try to build the offloading actions and add the result as a dependency | ||||
3968 | // to the host. | ||||
3969 | if (UseNewOffloadingDriver) | ||||
3970 | Current = BuildOffloadingActions(C, Args, I, Current); | ||||
3971 | |||||
3972 | // FIXME: Should we include any prior module file outputs as inputs of | ||||
3973 | // later actions in the same command line? | ||||
3974 | |||||
3975 | // Otherwise construct the appropriate action. | ||||
3976 | Action *NewCurrent = ConstructPhaseAction(C, Args, Phase, Current); | ||||
3977 | |||||
3978 | // We didn't create a new action, so we will just move to the next phase. | ||||
3979 | if (NewCurrent == Current) | ||||
3980 | continue; | ||||
3981 | |||||
3982 | if (auto *HMA = dyn_cast<HeaderModulePrecompileJobAction>(NewCurrent)) | ||||
3983 | HeaderModuleAction = HMA; | ||||
3984 | else if (auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent)) | ||||
3985 | ExtractAPIAction = EAA; | ||||
3986 | |||||
3987 | Current = NewCurrent; | ||||
3988 | |||||
3989 | // Use the current host action in any of the offloading actions, if | ||||
3990 | // required. | ||||
3991 | if (!UseNewOffloadingDriver) | ||||
3992 | if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg)) | ||||
3993 | break; | ||||
3994 | |||||
3995 | if (Current->getType() == types::TY_Nothing) | ||||
3996 | break; | ||||
3997 | } | ||||
3998 | |||||
3999 | // If we ended with something, add to the output list. | ||||
4000 | if (Current) | ||||
4001 | Actions.push_back(Current); | ||||
4002 | |||||
4003 | // Add any top level actions generated for offloading. | ||||
4004 | if (!UseNewOffloadingDriver) | ||||
4005 | OffloadBuilder.appendTopLevelActions(Actions, Current, InputArg); | ||||
4006 | else if (Current) | ||||
4007 | Current->propagateHostOffloadInfo(C.getActiveOffloadKinds(), | ||||
4008 | /*BoundArch=*/nullptr); | ||||
4009 | } | ||||
4010 | |||||
4011 | // Add a link action if necessary. | ||||
4012 | |||||
4013 | if (LinkerInputs.empty()) { | ||||
4014 | Arg *FinalPhaseArg; | ||||
4015 | if (getFinalPhase(Args, &FinalPhaseArg) == phases::Link) | ||||
4016 | OffloadBuilder.appendDeviceLinkActions(Actions); | ||||
4017 | } | ||||
4018 | |||||
4019 | if (!LinkerInputs.empty()) { | ||||
4020 | if (!UseNewOffloadingDriver) | ||||
4021 | if (Action *Wrapper = OffloadBuilder.makeHostLinkAction()) | ||||
4022 | LinkerInputs.push_back(Wrapper); | ||||
4023 | Action *LA; | ||||
4024 | // Check if this Linker Job should emit a static library. | ||||
4025 | if (ShouldEmitStaticLibrary(Args)) { | ||||
4026 | LA = C.MakeAction<StaticLibJobAction>(LinkerInputs, types::TY_Image); | ||||
4027 | } else if (UseNewOffloadingDriver && | ||||
4028 | C.getActiveOffloadKinds() != Action::OFK_None) { | ||||
4029 | LA = C.MakeAction<LinkerWrapperJobAction>(LinkerInputs, types::TY_Image); | ||||
4030 | LA->propagateHostOffloadInfo(C.getActiveOffloadKinds(), | ||||
4031 | /*BoundArch=*/nullptr); | ||||
4032 | } else { | ||||
4033 | LA = C.MakeAction<LinkJobAction>(LinkerInputs, types::TY_Image); | ||||
4034 | } | ||||
4035 | if (!UseNewOffloadingDriver) | ||||
4036 | LA = OffloadBuilder.processHostLinkAction(LA); | ||||
4037 | Actions.push_back(LA); | ||||
4038 | } | ||||
4039 | |||||
4040 | // Add an interface stubs merge action if necessary. | ||||
4041 | if (!MergerInputs.empty()) | ||||
4042 | Actions.push_back( | ||||
4043 | C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image)); | ||||
4044 | |||||
4045 | if (Args.hasArg(options::OPT_emit_interface_stubs)) { | ||||
4046 | auto PhaseList = types::getCompilationPhases( | ||||
4047 | types::TY_IFS_CPP, | ||||
4048 | Args.hasArg(options::OPT_c) ? phases::Compile : phases::IfsMerge); | ||||
4049 | |||||
4050 | ActionList MergerInputs; | ||||
4051 | |||||
4052 | for (auto &I : Inputs) { | ||||
4053 | types::ID InputType = I.first; | ||||
4054 | const Arg *InputArg = I.second; | ||||
4055 | |||||
4056 | // Currently clang and the llvm assembler do not support generating symbol | ||||
4057 | // stubs from assembly, so we skip the input on asm files. For ifs files | ||||
4058 | // we rely on the normal pipeline setup in the pipeline setup code above. | ||||
4059 | if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm || | ||||
4060 | InputType == types::TY_Asm) | ||||
4061 | continue; | ||||
4062 | |||||
4063 | Action *Current = C.MakeAction<InputAction>(*InputArg, InputType); | ||||
4064 | |||||
4065 | for (auto Phase : PhaseList) { | ||||
4066 | switch (Phase) { | ||||
4067 | default: | ||||
4068 | llvm_unreachable(::llvm::llvm_unreachable_internal("IFS Pipeline can only consist of Compile followed by IfsMerge." , "clang/lib/Driver/Driver.cpp", 4069) | ||||
4069 | "IFS Pipeline can only consist of Compile followed by IfsMerge.")::llvm::llvm_unreachable_internal("IFS Pipeline can only consist of Compile followed by IfsMerge." , "clang/lib/Driver/Driver.cpp", 4069); | ||||
4070 | case phases::Compile: { | ||||
4071 | // Only IfsMerge (llvm-ifs) can handle .o files by looking for ifs | ||||
4072 | // files where the .o file is located. The compile action can not | ||||
4073 | // handle this. | ||||
4074 | if (InputType == types::TY_Object) | ||||
4075 | break; | ||||
4076 | |||||
4077 | Current = C.MakeAction<CompileJobAction>(Current, types::TY_IFS_CPP); | ||||
4078 | break; | ||||
4079 | } | ||||
4080 | case phases::IfsMerge: { | ||||
4081 | assert(Phase == PhaseList.back() &&(static_cast <bool> (Phase == PhaseList.back() && "merging must be final compilation step.") ? void (0) : __assert_fail ("Phase == PhaseList.back() && \"merging must be final compilation step.\"" , "clang/lib/Driver/Driver.cpp", 4082, __extension__ __PRETTY_FUNCTION__ )) | ||||
4082 | "merging must be final compilation step.")(static_cast <bool> (Phase == PhaseList.back() && "merging must be final compilation step.") ? void (0) : __assert_fail ("Phase == PhaseList.back() && \"merging must be final compilation step.\"" , "clang/lib/Driver/Driver.cpp", 4082, __extension__ __PRETTY_FUNCTION__ )); | ||||
4083 | MergerInputs.push_back(Current); | ||||
4084 | Current = nullptr; | ||||
4085 | break; | ||||
4086 | } | ||||
4087 | } | ||||
4088 | } | ||||
4089 | |||||
4090 | // If we ended with something, add to the output list. | ||||
4091 | if (Current) | ||||
4092 | Actions.push_back(Current); | ||||
4093 | } | ||||
4094 | |||||
4095 | // Add an interface stubs merge action if necessary. | ||||
4096 | if (!MergerInputs.empty()) | ||||
4097 | Actions.push_back( | ||||
4098 | C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image)); | ||||
4099 | } | ||||
4100 | |||||
4101 | // If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a custom | ||||
4102 | // Compile phase that prints out supported cpu models and quits. | ||||
4103 | if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) { | ||||
4104 | // Use the -mcpu=? flag as the dummy input to cc1. | ||||
4105 | Actions.clear(); | ||||
4106 | Action *InputAc = C.MakeAction<InputAction>(*A, types::TY_C); | ||||
4107 | Actions.push_back( | ||||
4108 | C.MakeAction<PrecompileJobAction>(InputAc, types::TY_Nothing)); | ||||
4109 | for (auto &I : Inputs) | ||||
4110 | I.second->claim(); | ||||
4111 | } | ||||
4112 | |||||
4113 | // Claim ignored clang-cl options. | ||||
4114 | Args.ClaimAllArgs(options::OPT_cl_ignored_Group); | ||||
4115 | |||||
4116 | // Claim --cuda-host-only and --cuda-compile-host-device, which may be passed | ||||
4117 | // to non-CUDA compilations and should not trigger warnings there. | ||||
4118 | Args.ClaimAllArgs(options::OPT_cuda_host_only); | ||||
4119 | Args.ClaimAllArgs(options::OPT_cuda_compile_host_device); | ||||
4120 | } | ||||
4121 | |||||
4122 | Action *Driver::BuildOffloadingActions(Compilation &C, | ||||
4123 | llvm::opt::DerivedArgList &Args, | ||||
4124 | const InputTy &Input, | ||||
4125 | Action *HostAction) const { | ||||
4126 | if (!isa<CompileJobAction>(HostAction)) | ||||
4127 | return HostAction; | ||||
4128 | |||||
4129 | OffloadAction::DeviceDependences DDeps; | ||||
4130 | |||||
4131 | types::ID InputType = Input.first; | ||||
4132 | const Arg *InputArg = Input.second; | ||||
4133 | |||||
4134 | const Action::OffloadKind OffloadKinds[] = {Action::OFK_OpenMP}; | ||||
4135 | |||||
4136 | for (Action::OffloadKind Kind : OffloadKinds) { | ||||
4137 | SmallVector<const ToolChain *, 2> ToolChains; | ||||
4138 | ActionList DeviceActions; | ||||
4139 | |||||
4140 | auto TCRange = C.getOffloadToolChains(Kind); | ||||
4141 | for (auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI) | ||||
4142 | ToolChains.push_back(TI->second); | ||||
4143 | |||||
4144 | if (ToolChains.empty()) | ||||
4145 | continue; | ||||
4146 | |||||
4147 | for (unsigned I = 0; I < ToolChains.size(); ++I) | ||||
4148 | DeviceActions.push_back(C.MakeAction<InputAction>(*InputArg, InputType)); | ||||
4149 | |||||
4150 | if (DeviceActions.empty()) | ||||
4151 | return HostAction; | ||||
4152 | |||||
4153 | auto PL = types::getCompilationPhases(*this, Args, InputType); | ||||
4154 | |||||
4155 | for (phases::ID Phase : PL) { | ||||
4156 | if (Phase == phases::Link) { | ||||
4157 | assert(Phase == PL.back() && "linking must be final compilation step.")(static_cast <bool> (Phase == PL.back() && "linking must be final compilation step." ) ? void (0) : __assert_fail ("Phase == PL.back() && \"linking must be final compilation step.\"" , "clang/lib/Driver/Driver.cpp", 4157, __extension__ __PRETTY_FUNCTION__ )); | ||||
4158 | break; | ||||
4159 | } | ||||
4160 | |||||
4161 | auto TC = ToolChains.begin(); | ||||
4162 | for (Action *&A : DeviceActions) { | ||||
4163 | A = ConstructPhaseAction(C, Args, Phase, A, Kind); | ||||
4164 | |||||
4165 | if (isa<CompileJobAction>(A) && Kind == Action::OFK_OpenMP) { | ||||
4166 | HostAction->setCannotBeCollapsedWithNextDependentAction(); | ||||
4167 | OffloadAction::HostDependence HDep( | ||||
4168 | *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(), | ||||
4169 | /*BourdArch=*/nullptr, Action::OFK_OpenMP); | ||||
4170 | OffloadAction::DeviceDependences DDep; | ||||
4171 | DDep.add(*A, **TC, /*BoundArch=*/nullptr, Kind); | ||||
4172 | A = C.MakeAction<OffloadAction>(HDep, DDep); | ||||
4173 | } | ||||
4174 | ++TC; | ||||
4175 | } | ||||
4176 | } | ||||
4177 | |||||
4178 | auto TC = ToolChains.begin(); | ||||
4179 | for (Action *A : DeviceActions) { | ||||
4180 | DDeps.add(*A, **TC, /*BoundArch=*/nullptr, Kind); | ||||
4181 | TC++; | ||||
4182 | } | ||||
4183 | } | ||||
4184 | |||||
4185 | OffloadAction::HostDependence HDep( | ||||
4186 | *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(), | ||||
4187 | /*BoundArch=*/nullptr, DDeps); | ||||
4188 | return C.MakeAction<OffloadAction>(HDep, DDeps); | ||||
4189 | } | ||||
4190 | |||||
4191 | Action *Driver::ConstructPhaseAction( | ||||
4192 | Compilation &C, const ArgList &Args, phases::ID Phase, Action *Input, | ||||
4193 | Action::OffloadKind TargetDeviceOffloadKind) const { | ||||
4194 | llvm::PrettyStackTraceString CrashInfo("Constructing phase actions"); | ||||
4195 | |||||
4196 | // Some types skip the assembler phase (e.g., llvm-bc), but we can't | ||||
4197 | // encode this in the steps because the intermediate type depends on | ||||
4198 | // arguments. Just special case here. | ||||
4199 | if (Phase == phases::Assemble && Input->getType() != types::TY_PP_Asm) | ||||
4200 | return Input; | ||||
4201 | |||||
4202 | // Build the appropriate action. | ||||
4203 | switch (Phase) { | ||||
4204 | case phases::Link: | ||||
4205 | llvm_unreachable("link action invalid here.")::llvm::llvm_unreachable_internal("link action invalid here." , "clang/lib/Driver/Driver.cpp", 4205); | ||||
4206 | case phases::IfsMerge: | ||||
4207 | llvm_unreachable("ifsmerge action invalid here.")::llvm::llvm_unreachable_internal("ifsmerge action invalid here." , "clang/lib/Driver/Driver.cpp", 4207); | ||||
4208 | case phases::Preprocess: { | ||||
4209 | types::ID OutputTy; | ||||
4210 | // -M and -MM specify the dependency file name by altering the output type, | ||||
4211 | // -if -MD and -MMD are not specified. | ||||
4212 | if (Args.hasArg(options::OPT_M, options::OPT_MM) && | ||||
4213 | !Args.hasArg(options::OPT_MD, options::OPT_MMD)) { | ||||
4214 | OutputTy = types::TY_Dependencies; | ||||
4215 | } else { | ||||
4216 | OutputTy = Input->getType(); | ||||
4217 | if (!Args.hasFlag(options::OPT_frewrite_includes, | ||||
4218 | options::OPT_fno_rewrite_includes, false) && | ||||
4219 | !Args.hasFlag(options::OPT_frewrite_imports, | ||||
4220 | options::OPT_fno_rewrite_imports, false) && | ||||
4221 | !CCGenDiagnostics) | ||||
4222 | OutputTy = types::getPreprocessedType(OutputTy); | ||||
4223 | assert(OutputTy != types::TY_INVALID &&(static_cast <bool> (OutputTy != types::TY_INVALID && "Cannot preprocess this input type!") ? void (0) : __assert_fail ("OutputTy != types::TY_INVALID && \"Cannot preprocess this input type!\"" , "clang/lib/Driver/Driver.cpp", 4224, __extension__ __PRETTY_FUNCTION__ )) | ||||
4224 | "Cannot preprocess this input type!")(static_cast <bool> (OutputTy != types::TY_INVALID && "Cannot preprocess this input type!") ? void (0) : __assert_fail ("OutputTy != types::TY_INVALID && \"Cannot preprocess this input type!\"" , "clang/lib/Driver/Driver.cpp", 4224, __extension__ __PRETTY_FUNCTION__ )); | ||||
4225 | } | ||||
4226 | return C.MakeAction<PreprocessJobAction>(Input, OutputTy); | ||||
4227 | } | ||||
4228 | case phases::Precompile: { | ||||
4229 | // API extraction should not generate an actual precompilation action. | ||||
4230 | if (Args.hasArg(options::OPT_extract_api)) | ||||
4231 | return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO); | ||||
4232 | |||||
4233 | types::ID OutputTy = getPrecompiledType(Input->getType()); | ||||
4234 | assert(OutputTy != types::TY_INVALID &&(static_cast <bool> (OutputTy != types::TY_INVALID && "Cannot precompile this input type!") ? void (0) : __assert_fail ("OutputTy != types::TY_INVALID && \"Cannot precompile this input type!\"" , "clang/lib/Driver/Driver.cpp", 4235, __extension__ __PRETTY_FUNCTION__ )) | ||||
4235 | "Cannot precompile this input type!")(static_cast <bool> (OutputTy != types::TY_INVALID && "Cannot precompile this input type!") ? void (0) : __assert_fail ("OutputTy != types::TY_INVALID && \"Cannot precompile this input type!\"" , "clang/lib/Driver/Driver.cpp", 4235, __extension__ __PRETTY_FUNCTION__ )); | ||||
4236 | |||||
4237 | // If we're given a module name, precompile header file inputs as a | ||||
4238 | // module, not as a precompiled header. | ||||
4239 | const char *ModName = nullptr; | ||||
4240 | if (OutputTy == types::TY_PCH) { | ||||
4241 | if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ)) | ||||
4242 | ModName = A->getValue(); | ||||
4243 | if (ModName) | ||||
4244 | OutputTy = types::TY_ModuleFile; | ||||
4245 | } | ||||
4246 | |||||
4247 | if (Args.hasArg(options::OPT_fsyntax_only)) { | ||||
4248 | // Syntax checks should not emit a PCH file | ||||
4249 | OutputTy = types::TY_Nothing; | ||||
4250 | } | ||||
4251 | |||||
4252 | if (ModName) | ||||
4253 | return C.MakeAction<HeaderModulePrecompileJobAction>(Input, OutputTy, | ||||
4254 | ModName); | ||||
4255 | return C.MakeAction<PrecompileJobAction>(Input, OutputTy); | ||||
4256 | } | ||||
4257 | case phases::Compile: { | ||||
4258 | if (Args.hasArg(options::OPT_fsyntax_only)) | ||||
4259 | return C.MakeAction<CompileJobAction>(Input, types::TY_Nothing); | ||||
4260 | if (Args.hasArg(options::OPT_rewrite_objc)) | ||||
4261 | return C.MakeAction<CompileJobAction>(Input, types::TY_RewrittenObjC); | ||||
4262 | if (Args.hasArg(options::OPT_rewrite_legacy_objc)) | ||||
4263 | return C.MakeAction<CompileJobAction>(Input, | ||||
4264 | types::TY_RewrittenLegacyObjC); | ||||
4265 | if (Args.hasArg(options::OPT__analyze)) | ||||
4266 | return C.MakeAction<AnalyzeJobAction>(Input, types::TY_Plist); | ||||
4267 | if (Args.hasArg(options::OPT__migrate)) | ||||
4268 | return C.MakeAction<MigrateJobAction>(Input, types::TY_Remap); | ||||
4269 | if (Args.hasArg(options::OPT_emit_ast)) | ||||
4270 | return C.MakeAction<CompileJobAction>(Input, types::TY_AST); | ||||
4271 | if (Args.hasArg(options::OPT_module_file_info)) | ||||
4272 | return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile); | ||||
4273 | if (Args.hasArg(options::OPT_verify_pch)) | ||||
4274 | return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing); | ||||
4275 | if (Args.hasArg(options::OPT_extract_api)) | ||||
4276 | return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO); | ||||
4277 | return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC); | ||||
4278 | } | ||||
4279 | case phases::Backend: { | ||||
4280 | if (isUsingLTO() && TargetDeviceOffloadKind == Action::OFK_None) { | ||||
4281 | types::ID Output = | ||||
4282 | Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC; | ||||
4283 | return C.MakeAction<BackendJobAction>(Input, Output); | ||||
4284 | } | ||||
4285 | if (isUsingLTO(/* IsOffload */ true) && | ||||
4286 | TargetDeviceOffloadKind == Action::OFK_OpenMP) { | ||||
4287 | types::ID Output = | ||||
4288 | Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC; | ||||
4289 | return C.MakeAction<BackendJobAction>(Input, Output); | ||||
4290 | } | ||||
4291 | if (Args.hasArg(options::OPT_emit_llvm) || | ||||
4292 | (TargetDeviceOffloadKind == Action::OFK_HIP && | ||||
4293 | Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, | ||||
4294 | false))) { | ||||
4295 | types::ID Output = | ||||
4296 | Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC; | ||||
4297 | return C.MakeAction<BackendJobAction>(Input, Output); | ||||
4298 | } | ||||
4299 | return C.MakeAction<BackendJobAction>(Input, types::TY_PP_Asm); | ||||
4300 | } | ||||
4301 | case phases::Assemble: | ||||
4302 | return C.MakeAction<AssembleJobAction>(std::move(Input), types::TY_Object); | ||||
4303 | } | ||||
4304 | |||||
4305 | llvm_unreachable("invalid phase in ConstructPhaseAction")::llvm::llvm_unreachable_internal("invalid phase in ConstructPhaseAction" , "clang/lib/Driver/Driver.cpp", 4305); | ||||
4306 | } | ||||
4307 | |||||
4308 | void Driver::BuildJobs(Compilation &C) const { | ||||
4309 | llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); | ||||
4310 | |||||
4311 | Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o); | ||||
4312 | |||||
4313 | // It is an error to provide a -o option if we are making multiple output | ||||
4314 | // files. There are exceptions: | ||||
4315 | // | ||||
4316 | // IfsMergeJob: when generating interface stubs enabled we want to be able to | ||||
4317 | // generate the stub file at the same time that we generate the real | ||||
4318 | // library/a.out. So when a .o, .so, etc are the output, with clang interface | ||||
4319 | // stubs there will also be a .ifs and .ifso at the same location. | ||||
4320 | // | ||||
4321 | // CompileJob of type TY_IFS_CPP: when generating interface stubs is enabled | ||||
4322 | // and -c is passed, we still want to be able to generate a .ifs file while | ||||
4323 | // we are also generating .o files. So we allow more than one output file in | ||||
4324 | // this case as well. | ||||
4325 | // | ||||
4326 | if (FinalOutput) { | ||||
4327 | unsigned NumOutputs = 0; | ||||
4328 | unsigned NumIfsOutputs = 0; | ||||
4329 | for (const Action *A : C.getActions()) | ||||
4330 | if (A->getType() != types::TY_Nothing && | ||||
4331 | !(A->getKind() == Action::IfsMergeJobClass || | ||||
4332 | (A->getType() == clang::driver::types::TY_IFS_CPP && | ||||
4333 | A->getKind() == clang::driver::Action::CompileJobClass && | ||||
4334 | 0 == NumIfsOutputs++) || | ||||
4335 | (A->getKind() == Action::BindArchClass && A->getInputs().size() && | ||||
4336 | A->getInputs().front()->getKind() == Action::IfsMergeJobClass))) | ||||
4337 | ++NumOutputs; | ||||
4338 | |||||
4339 | if (NumOutputs > 1) { | ||||
4340 | Diag(clang::diag::err_drv_output_argument_with_multiple_files); | ||||
4341 | FinalOutput = nullptr; | ||||
4342 | } | ||||
4343 | } | ||||
4344 | |||||
4345 | const llvm::Triple &RawTriple = C.getDefaultToolChain().getTriple(); | ||||
4346 | if (RawTriple.isOSAIX()) { | ||||
4347 | if (Arg *A = C.getArgs().getLastArg(options::OPT_G)) | ||||
4348 | Diag(diag::err_drv_unsupported_opt_for_target) | ||||
4349 | << A->getSpelling() << RawTriple.str(); | ||||
4350 | if (LTOMode == LTOK_Thin) | ||||
4351 | Diag(diag::err_drv_clang_unsupported) << "thinLTO on AIX"; | ||||
4352 | } | ||||
4353 | |||||
4354 | // Collect the list of architectures. | ||||
4355 | llvm::StringSet<> ArchNames; | ||||
4356 | if (RawTriple.isOSBinFormatMachO()) | ||||
4357 | for (const Arg *A : C.getArgs()) | ||||
4358 | if (A->getOption().matches(options::OPT_arch)) | ||||
4359 | ArchNames.insert(A->getValue()); | ||||
4360 | |||||
4361 | // Set of (Action, canonical ToolChain triple) pairs we've built jobs for. | ||||
4362 | std::map<std::pair<const Action *, std::string>, InputInfoList> CachedResults; | ||||
4363 | for (Action *A : C.getActions()) { | ||||
4364 | // If we are linking an image for multiple archs then the linker wants | ||||
4365 | // -arch_multiple and -final_output <final image name>. Unfortunately, this | ||||
4366 | // doesn't fit in cleanly because we have to pass this information down. | ||||
4367 | // | ||||
4368 | // FIXME: This is a hack; find a cleaner way to integrate this into the | ||||
4369 | // process. | ||||
4370 | const char *LinkingOutput = nullptr; | ||||
4371 | if (isa<LipoJobAction>(A)) { | ||||
4372 | if (FinalOutput) | ||||
4373 | LinkingOutput = FinalOutput->getValue(); | ||||
4374 | else | ||||
4375 | LinkingOutput = getDefaultImageName(); | ||||
4376 | } | ||||
4377 | |||||
4378 | BuildJobsForAction(C, A, &C.getDefaultToolChain(), | ||||
4379 | /*BoundArch*/ StringRef(), | ||||
4380 | /*AtTopLevel*/ true, | ||||
4381 | /*MultipleArchs*/ ArchNames.size() > 1, | ||||
4382 | /*LinkingOutput*/ LinkingOutput, CachedResults, | ||||
4383 | /*TargetDeviceOffloadKind*/ Action::OFK_None); | ||||
4384 | } | ||||
4385 | |||||
4386 | // If we have more than one job, then disable integrated-cc1 for now. Do this | ||||
4387 | // also when we need to report process execution statistics. | ||||
4388 | if (C.getJobs().size() > 1 || CCPrintProcessStats) | ||||
4389 | for (auto &J : C.getJobs()) | ||||
4390 | J.InProcess = false; | ||||
4391 | |||||
4392 | if (CCPrintProcessStats) { | ||||
4393 | C.setPostCallback([=](const Command &Cmd, int Res) { | ||||
4394 | Optional<llvm::sys::ProcessStatistics> ProcStat = | ||||
4395 | Cmd.getProcessStatistics(); | ||||
4396 | if (!ProcStat) | ||||
4397 | return; | ||||
4398 | |||||
4399 | const char *LinkingOutput = nullptr; | ||||
4400 | if (FinalOutput) | ||||
4401 | LinkingOutput = FinalOutput->getValue(); | ||||
4402 | else if (!Cmd.getOutputFilenames().empty()) | ||||
4403 | LinkingOutput = Cmd.getOutputFilenames().front().c_str(); | ||||
4404 | else | ||||
4405 | LinkingOutput = getDefaultImageName(); | ||||
4406 | |||||
4407 | if (CCPrintStatReportFilename.empty()) { | ||||
4408 | using namespace llvm; | ||||
4409 | // Human readable output. | ||||
4410 | outs() << sys::path::filename(Cmd.getExecutable()) << ": " | ||||
4411 | << "output=" << LinkingOutput; | ||||
4412 | outs() << ", total=" | ||||
4413 | << format("%.3f", ProcStat->TotalTime.count() / 1000.) << " ms" | ||||
4414 | << ", user=" | ||||
4415 | << format("%.3f", ProcStat->UserTime.count() / 1000.) << " ms" | ||||
4416 | << ", mem=" << ProcStat->PeakMemory << " Kb\n"; | ||||
4417 | } else { | ||||
4418 | // CSV format. | ||||
4419 | std::string Buffer; | ||||
4420 | llvm::raw_string_ostream Out(Buffer); | ||||
4421 | llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()), | ||||
4422 | /*Quote*/ true); | ||||
4423 | Out << ','; | ||||
4424 | llvm::sys::printArg(Out, LinkingOutput, true); | ||||
4425 | Out << ',' << ProcStat->TotalTime.count() << ',' | ||||
4426 | << ProcStat->UserTime.count() << ',' << ProcStat->PeakMemory | ||||
4427 | << '\n'; | ||||
4428 | Out.flush(); | ||||
4429 | std::error_code EC; | ||||
4430 | llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC, | ||||
4431 | llvm::sys::fs::OF_Append | | ||||
4432 | llvm::sys::fs::OF_Text); | ||||
4433 | if (EC) | ||||
4434 | return; | ||||
4435 | auto L = OS.lock(); | ||||
4436 | if (!L) { | ||||
4437 | llvm::errs() << "ERROR: Cannot lock file " | ||||
4438 | << CCPrintStatReportFilename << ": " | ||||
4439 | << toString(L.takeError()) << "\n"; | ||||
4440 | return; | ||||
4441 | } | ||||
4442 | OS << Buffer; | ||||
4443 | OS.flush(); | ||||
4444 | } | ||||
4445 | }); | ||||
4446 | } | ||||
4447 | |||||
4448 | // If the user passed -Qunused-arguments or there were errors, don't warn | ||||
4449 | // about any unused arguments. | ||||
4450 | if (Diags.hasErrorOccurred() || | ||||
4451 | C.getArgs().hasArg(options::OPT_Qunused_arguments)) | ||||
4452 | return; | ||||
4453 | |||||
4454 | // Claim -### here. | ||||
4455 | (void)C.getArgs().hasArg(options::OPT__HASH_HASH_HASH); | ||||
4456 | |||||
4457 | // Claim --driver-mode, --rsp-quoting, it was handled earlier. | ||||
4458 | (void)C.getArgs().hasArg(options::OPT_driver_mode); | ||||
4459 | (void)C.getArgs().hasArg(options::OPT_rsp_quoting); | ||||
4460 | |||||
4461 | for (Arg *A : C.getArgs()) { | ||||
4462 | // FIXME: It would be nice to be able to send the argument to the | ||||
4463 | // DiagnosticsEngine, so that extra values, position, and so on could be | ||||
4464 | // printed. | ||||
4465 | if (!A->isClaimed()) { | ||||
4466 | if (A->getOption().hasFlag(options::NoArgumentUnused)) | ||||
4467 | continue; | ||||
4468 | |||||
4469 | // Suppress the warning automatically if this is just a flag, and it is an | ||||
4470 | // instance of an argument we already claimed. | ||||
4471 | const Option &Opt = A->getOption(); | ||||
4472 | if (Opt.getKind() == Option::FlagClass) { | ||||
4473 | bool DuplicateClaimed = false; | ||||
4474 | |||||
4475 | for (const Arg *AA : C.getArgs().filtered(&Opt)) { | ||||
4476 | if (AA->isClaimed()) { | ||||
4477 | DuplicateClaimed = true; | ||||
4478 | break; | ||||
4479 | } | ||||
4480 | } | ||||
4481 | |||||
4482 | if (DuplicateClaimed) | ||||
4483 | continue; | ||||
4484 | } | ||||
4485 | |||||
4486 | // In clang-cl, don't mention unknown arguments here since they have | ||||
4487 | // already been warned about. | ||||
4488 | if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) | ||||
4489 | Diag(clang::diag::warn_drv_unused_argument) | ||||
4490 | << A->getAsString(C.getArgs()); | ||||
4491 | } | ||||
4492 | } | ||||
4493 | } | ||||
4494 | |||||
4495 | namespace { | ||||
4496 | /// Utility class to control the collapse of dependent actions and select the | ||||
4497 | /// tools accordingly. | ||||
4498 | class ToolSelector final { | ||||
4499 | /// The tool chain this selector refers to. | ||||
4500 | const ToolChain &TC; | ||||
4501 | |||||
4502 | /// The compilation this selector refers to. | ||||
4503 | const Compilation &C; | ||||
4504 | |||||
4505 | /// The base action this selector refers to. | ||||
4506 | const JobAction *BaseAction; | ||||
4507 | |||||
4508 | /// Set to true if the current toolchain refers to host actions. | ||||
4509 | bool IsHostSelector; | ||||
4510 | |||||
4511 | /// Set to true if save-temps and embed-bitcode functionalities are active. | ||||
4512 | bool SaveTemps; | ||||
4513 | bool EmbedBitcode; | ||||
4514 | |||||
4515 | /// Get previous dependent action or null if that does not exist. If | ||||
4516 | /// \a CanBeCollapsed is false, that action must be legal to collapse or | ||||
4517 | /// null will be returned. | ||||
4518 | const JobAction *getPrevDependentAction(const ActionList &Inputs, | ||||
4519 | ActionList &SavedOffloadAction, | ||||
4520 | bool CanBeCollapsed = true) { | ||||
4521 | // An option can be collapsed only if it has a single input. | ||||
4522 | if (Inputs.size() != 1) | ||||
4523 | return nullptr; | ||||
4524 | |||||
4525 | Action *CurAction = *Inputs.begin(); | ||||
4526 | if (CanBeCollapsed && | ||||
4527 | !CurAction->isCollapsingWithNextDependentActionLegal()) | ||||
4528 | return nullptr; | ||||
4529 | |||||
4530 | // If the input action is an offload action. Look through it and save any | ||||
4531 | // offload action that can be dropped in the event of a collapse. | ||||
4532 | if (auto *OA = dyn_cast<OffloadAction>(CurAction)) { | ||||
4533 | // If the dependent action is a device action, we will attempt to collapse | ||||
4534 | // only with other device actions. Otherwise, we would do the same but | ||||
4535 | // with host actions only. | ||||
4536 | if (!IsHostSelector) { | ||||
4537 | if (OA->hasSingleDeviceDependence(/*DoNotConsiderHostActions=*/true)) { | ||||
4538 | CurAction = | ||||
4539 | OA->getSingleDeviceDependence(/*DoNotConsiderHostActions=*/true); | ||||
4540 | if (CanBeCollapsed && | ||||
4541 | !CurAction->isCollapsingWithNextDependentActionLegal()) | ||||
4542 | return nullptr; | ||||
4543 | SavedOffloadAction.push_back(OA); | ||||
4544 | return dyn_cast<JobAction>(CurAction); | ||||
4545 | } | ||||
4546 | } else if (OA->hasHostDependence()) { | ||||
4547 | CurAction = OA->getHostDependence(); | ||||
4548 | if (CanBeCollapsed && | ||||
4549 | !CurAction->isCollapsingWithNextDependentActionLegal()) | ||||
4550 | return nullptr; | ||||
4551 | SavedOffloadAction.push_back(OA); | ||||
4552 | return dyn_cast<JobAction>(CurAction); | ||||
4553 | } | ||||
4554 | return nullptr; | ||||
4555 | } | ||||
4556 | |||||
4557 | return dyn_cast<JobAction>(CurAction); | ||||
4558 | } | ||||
4559 | |||||
4560 | /// Return true if an assemble action can be collapsed. | ||||
4561 | bool canCollapseAssembleAction() const { | ||||
4562 | return TC.useIntegratedAs() && !SaveTemps && | ||||
4563 | !C.getArgs().hasArg(options::OPT_via_file_asm) && | ||||
4564 | !C.getArgs().hasArg(options::OPT__SLASH_FA) && | ||||
4565 | !C.getArgs().hasArg(options::OPT__SLASH_Fa); | ||||
4566 | } | ||||
4567 | |||||
4568 | /// Return true if a preprocessor action can be collapsed. | ||||
4569 | bool canCollapsePreprocessorAction() const { | ||||
4570 | return !C.getArgs().hasArg(options::OPT_no_integrated_cpp) && | ||||
4571 | !C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps && | ||||
4572 | !C.getArgs().hasArg(options::OPT_rewrite_objc); | ||||
4573 | } | ||||
4574 | |||||
4575 | /// Struct that relates an action with the offload actions that would be | ||||
4576 | /// collapsed with it. | ||||
4577 | struct JobActionInfo final { | ||||
4578 | /// The action this info refers to. | ||||
4579 | const JobAction *JA = nullptr; | ||||
4580 | /// The offload actions we need to take care off if this action is | ||||
4581 | /// collapsed. | ||||
4582 | ActionList SavedOffloadAction; | ||||
4583 | }; | ||||
4584 | |||||
4585 | /// Append collapsed offload actions from the give nnumber of elements in the | ||||
4586 | /// action info array. | ||||
4587 | static void AppendCollapsedOffloadAction(ActionList &CollapsedOffloadAction, | ||||
4588 | ArrayRef<JobActionInfo> &ActionInfo, | ||||
4589 | unsigned ElementNum) { | ||||
4590 | assert(ElementNum <= ActionInfo.size() && "Invalid number of elements.")(static_cast <bool> (ElementNum <= ActionInfo.size() && "Invalid number of elements.") ? void (0) : __assert_fail ("ElementNum <= ActionInfo.size() && \"Invalid number of elements.\"" , "clang/lib/Driver/Driver.cpp", 4590, __extension__ __PRETTY_FUNCTION__ )); | ||||
4591 | for (unsigned I = 0; I < ElementNum; ++I) | ||||
4592 | CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(), | ||||
4593 | ActionInfo[I].SavedOffloadAction.end()); | ||||
4594 | } | ||||
4595 | |||||
4596 | /// Functions that attempt to perform the combining. They detect if that is | ||||
4597 | /// legal, and if so they update the inputs \a Inputs and the offload action | ||||
4598 | /// that were collapsed in \a CollapsedOffloadAction. A tool that deals with | ||||
4599 | /// the combined action is returned. If the combining is not legal or if the | ||||
4600 | /// tool does not exist, null is returned. | ||||
4601 | /// Currently three kinds of collapsing are supported: | ||||
4602 | /// - Assemble + Backend + Compile; | ||||
4603 | /// - Assemble + Backend ; | ||||
4604 | /// - Backend + Compile. | ||||
4605 | const Tool * | ||||
4606 | combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo, | ||||
4607 | ActionList &Inputs, | ||||
4608 | ActionList &CollapsedOffloadAction) { | ||||
4609 | if (ActionInfo.size() < 3 || !canCollapseAssembleAction()) | ||||
4610 | return nullptr; | ||||
4611 | auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA); | ||||
4612 | auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA); | ||||
4613 | auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA); | ||||
4614 | if (!AJ || !BJ || !CJ) | ||||
4615 | return nullptr; | ||||
4616 | |||||
4617 | // Get compiler tool. | ||||
4618 | const Tool *T = TC.SelectTool(*CJ); | ||||
4619 | if (!T) | ||||
4620 | return nullptr; | ||||
4621 | |||||
4622 | // Can't collapse if we don't have codegen support unless we are | ||||
4623 | // emitting LLVM IR. | ||||
4624 | bool OutputIsLLVM = types::isLLVMIR(ActionInfo[0].JA->getType()); | ||||
4625 | if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR())) | ||||
4626 | return nullptr; | ||||
4627 | |||||
4628 | // When using -fembed-bitcode, it is required to have the same tool (clang) | ||||
4629 | // for both CompilerJA and BackendJA. Otherwise, combine two stages. | ||||
4630 | if (EmbedBitcode) { | ||||
4631 | const Tool *BT = TC.SelectTool(*BJ); | ||||
4632 | if (BT == T) | ||||
4633 | return nullptr; | ||||
4634 | } | ||||
4635 | |||||
4636 | if (!T->hasIntegratedAssembler()) | ||||
4637 | return nullptr; | ||||
4638 | |||||
4639 | Inputs = CJ->getInputs(); | ||||
4640 | AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo, | ||||
4641 | /*NumElements=*/3); | ||||
4642 | return T; | ||||
4643 | } | ||||
4644 | const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo, | ||||
4645 | ActionList &Inputs, | ||||
4646 | ActionList &CollapsedOffloadAction) { | ||||
4647 | if (ActionInfo.size() < 2 || !canCollapseAssembleAction()) | ||||
4648 | return nullptr; | ||||
4649 | auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA); | ||||
4650 | auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA); | ||||
4651 | if (!AJ || !BJ) | ||||
4652 | return nullptr; | ||||
4653 | |||||
4654 | // Get backend tool. | ||||
4655 | const Tool *T = TC.SelectTool(*BJ); | ||||
4656 | if (!T) | ||||
4657 | return nullptr; | ||||
4658 | |||||
4659 | if (!T->hasIntegratedAssembler()) | ||||
4660 | return nullptr; | ||||
4661 | |||||
4662 | Inputs = BJ->getInputs(); | ||||
4663 | AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo, | ||||
4664 | /*NumElements=*/2); | ||||
4665 | return T; | ||||
4666 | } | ||||
4667 | const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo, | ||||
4668 | ActionList &Inputs, | ||||
4669 | ActionList &CollapsedOffloadAction) { | ||||
4670 | if (ActionInfo.size() < 2) | ||||
4671 | return nullptr; | ||||
4672 | auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA); | ||||
4673 | auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA); | ||||
4674 | if (!BJ || !CJ) | ||||
4675 | return nullptr; | ||||
4676 | |||||
4677 | // Check if the initial input (to the compile job or its predessor if one | ||||
4678 | // exists) is LLVM bitcode. In that case, no preprocessor step is required | ||||
4679 | // and we can still collapse the compile and backend jobs when we have | ||||
4680 | // -save-temps. I.e. there is no need for a separate compile job just to | ||||
4681 | // emit unoptimized bitcode. | ||||
4682 | bool InputIsBitcode = true; | ||||
4683 | for (size_t i = 1; i < ActionInfo.size(); i++) | ||||
4684 | if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC && | ||||
4685 | ActionInfo[i].JA->getType() != types::TY_LTO_BC) { | ||||
4686 | InputIsBitcode = false; | ||||
4687 | break; | ||||
4688 | } | ||||
4689 | if (!InputIsBitcode && !canCollapsePreprocessorAction()) | ||||
4690 | return nullptr; | ||||
4691 | |||||
4692 | // Get compiler tool. | ||||
4693 | const Tool *T = TC.SelectTool(*CJ); | ||||
4694 | if (!T) | ||||
4695 | return nullptr; | ||||
4696 | |||||
4697 | // Can't collapse if we don't have codegen support unless we are | ||||
4698 | // emitting LLVM IR. | ||||
4699 | bool OutputIsLLVM = types::isLLVMIR(ActionInfo[0].JA->getType()); | ||||
4700 | if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR())) | ||||
4701 | return nullptr; | ||||
4702 | |||||
4703 | if (T->canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode)) | ||||
4704 | return nullptr; | ||||
4705 | |||||
4706 | Inputs = CJ->getInputs(); | ||||
4707 | AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo, | ||||
4708 | /*NumElements=*/2); | ||||
4709 | return T; | ||||
4710 | } | ||||
4711 | |||||
4712 | /// Updates the inputs if the obtained tool supports combining with | ||||
4713 | /// preprocessor action, and the current input is indeed a preprocessor | ||||
4714 | /// action. If combining results in the collapse of offloading actions, those | ||||
4715 | /// are appended to \a CollapsedOffloadAction. | ||||
4716 | void combineWithPreprocessor(const Tool *T, ActionList &Inputs, | ||||
4717 | ActionList &CollapsedOffloadAction) { | ||||
4718 | if (!T || !canCollapsePreprocessorAction() || !T->hasIntegratedCPP()) | ||||
4719 | return; | ||||
4720 | |||||
4721 | // Attempt to get a preprocessor action dependence. | ||||
4722 | ActionList PreprocessJobOffloadActions; | ||||
4723 | ActionList NewInputs; | ||||
4724 | for (Action *A : Inputs) { | ||||
4725 | auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions); | ||||
4726 | if (!PJ || !isa<PreprocessJobAction>(PJ)) { | ||||
4727 | NewInputs.push_back(A); | ||||
4728 | continue; | ||||
4729 | } | ||||
4730 | |||||
4731 | // This is legal to combine. Append any offload action we found and add the | ||||
4732 | // current input to preprocessor inputs. | ||||
4733 | CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(), | ||||
4734 | PreprocessJobOffloadActions.end()); | ||||
4735 | NewInputs.append(PJ->input_begin(), PJ->input_end()); | ||||
4736 | } | ||||
4737 | Inputs = NewInputs; | ||||
4738 | } | ||||
4739 | |||||
4740 | public: | ||||
4741 | ToolSelector(const JobAction *BaseAction, const ToolChain &TC, | ||||
4742 | const Compilation &C, bool SaveTemps, bool EmbedBitcode) | ||||
4743 | : TC(TC), C(C), BaseAction(BaseAction), SaveTemps(SaveTemps), | ||||
4744 | EmbedBitcode(EmbedBitcode) { | ||||
4745 | assert(BaseAction && "Invalid base action.")(static_cast <bool> (BaseAction && "Invalid base action." ) ? void (0) : __assert_fail ("BaseAction && \"Invalid base action.\"" , "clang/lib/Driver/Driver.cpp", 4745, __extension__ __PRETTY_FUNCTION__ )); | ||||
4746 | IsHostSelector = BaseAction->getOffloadingDeviceKind() == Action::OFK_None; | ||||
4747 | } | ||||
4748 | |||||
4749 | /// Check if a chain of actions can be combined and return the tool that can | ||||
4750 | /// handle the combination of actions. The pointer to the current inputs \a | ||||
4751 | /// Inputs and the list of offload actions \a CollapsedOffloadActions | ||||
4752 | /// connected to collapsed actions are updated accordingly. The latter enables | ||||
4753 | /// the caller of the selector to process them afterwards instead of just | ||||
4754 | /// dropping them. If no suitable tool is found, null will be returned. | ||||
4755 | const Tool *getTool(ActionList &Inputs, | ||||
4756 | ActionList &CollapsedOffloadAction) { | ||||
4757 | // | ||||
4758 | // Get the largest chain of actions that we could combine. | ||||
4759 | // | ||||
4760 | |||||
4761 | SmallVector<JobActionInfo, 5> ActionChain(1); | ||||
4762 | ActionChain.back().JA = BaseAction; | ||||
4763 | while (ActionChain.back().JA) { | ||||
4764 | const Action *CurAction = ActionChain.back().JA; | ||||
4765 | |||||
4766 | // Grow the chain by one element. | ||||
4767 | ActionChain.resize(ActionChain.size() + 1); | ||||
4768 | JobActionInfo &AI = ActionChain.back(); | ||||
4769 | |||||
4770 | // Attempt to fill it with the | ||||
4771 | AI.JA = | ||||
4772 | getPrevDependentAction(CurAction->getInputs(), AI.SavedOffloadAction); | ||||
4773 | } | ||||
4774 | |||||
4775 | // Pop the last action info as it could not be filled. | ||||
4776 | ActionChain.pop_back(); | ||||
4777 | |||||
4778 | // | ||||
4779 | // Attempt to combine actions. If all combining attempts failed, just return | ||||
4780 | // the tool of the provided action. At the end we attempt to combine the | ||||
4781 | // action with any preprocessor action it may depend on. | ||||
4782 | // | ||||
4783 | |||||
4784 | const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs, | ||||
4785 | CollapsedOffloadAction); | ||||
4786 | if (!T) | ||||
4787 | T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction); | ||||
4788 | if (!T) | ||||
4789 | T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction); | ||||
4790 | if (!T) { | ||||
4791 | Inputs = BaseAction->getInputs(); | ||||
4792 | T = TC.SelectTool(*BaseAction); | ||||
4793 | } | ||||
4794 | |||||
4795 | combineWithPreprocessor(T, Inputs, CollapsedOffloadAction); | ||||
4796 | return T; | ||||
4797 | } | ||||
4798 | }; | ||||
4799 | } | ||||
4800 | |||||
4801 | /// Return a string that uniquely identifies the result of a job. The bound arch | ||||
4802 | /// is not necessarily represented in the toolchain's triple -- for example, | ||||
4803 | /// armv7 and armv7s both map to the same triple -- so we need both in our map. | ||||
4804 | /// Also, we need to add the offloading device kind, as the same tool chain can | ||||
4805 | /// be used for host and device for some programming models, e.g. OpenMP. | ||||
4806 | static std::string GetTriplePlusArchString(const ToolChain *TC, | ||||
4807 | StringRef BoundArch, | ||||
4808 | Action::OffloadKind OffloadKind) { | ||||
4809 | std::string TriplePlusArch = TC->getTriple().normalize(); | ||||
4810 | if (!BoundArch.empty()) { | ||||
4811 | TriplePlusArch += "-"; | ||||
4812 | TriplePlusArch += BoundArch; | ||||
4813 | } | ||||
4814 | TriplePlusArch += "-"; | ||||
4815 | TriplePlusArch += Action::GetOffloadKindName(OffloadKind); | ||||
4816 | return TriplePlusArch; | ||||
4817 | } | ||||
4818 | |||||
4819 | InputInfoList Driver::BuildJobsForAction( | ||||
4820 | Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, | ||||
4821 | bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, | ||||
4822 | std::map<std::pair<const Action *, std::string>, InputInfoList> | ||||
4823 | &CachedResults, | ||||
4824 | Action::OffloadKind TargetDeviceOffloadKind) const { | ||||
4825 | std::pair<const Action *, std::string> ActionTC = { | ||||
4826 | A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)}; | ||||
4827 | auto CachedResult = CachedResults.find(ActionTC); | ||||
4828 | if (CachedResult != CachedResults.end()) { | ||||
4829 | return CachedResult->second; | ||||
4830 | } | ||||
4831 | InputInfoList Result = BuildJobsForActionNoCache( | ||||
4832 | C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput, | ||||
4833 | CachedResults, TargetDeviceOffloadKind); | ||||
4834 | CachedResults[ActionTC] = Result; | ||||
4835 | return Result; | ||||
4836 | } | ||||
4837 | |||||
4838 | InputInfoList Driver::BuildJobsForActionNoCache( | ||||
4839 | Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, | ||||
4840 | bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, | ||||
4841 | std::map<std::pair<const Action *, std::string>, InputInfoList> | ||||
4842 | &CachedResults, | ||||
4843 | Action::OffloadKind TargetDeviceOffloadKind) const { | ||||
4844 | llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); | ||||
4845 | |||||
4846 | InputInfoList OffloadDependencesInputInfo; | ||||
4847 | bool BuildingForOffloadDevice = TargetDeviceOffloadKind != Action::OFK_None; | ||||
4848 | if (const OffloadAction *OA = dyn_cast<OffloadAction>(A)) { | ||||
4849 | // The 'Darwin' toolchain is initialized only when its arguments are | ||||
4850 | // computed. Get the default arguments for OFK_None to ensure that | ||||
4851 | // initialization is performed before processing the offload action. | ||||
4852 | // FIXME: Remove when darwin's toolchain is initialized during construction. | ||||
4853 | C.getArgsForToolChain(TC, BoundArch, Action::OFK_None); | ||||
4854 | |||||
4855 | // The offload action is expected to be used in four different situations. | ||||
4856 | // | ||||
4857 | // a) Set a toolchain/architecture/kind for a host action: | ||||
4858 | // Host Action 1 -> OffloadAction -> Host Action 2 | ||||
4859 | // | ||||
4860 | // b) Set a toolchain/architecture/kind for a device action; | ||||
4861 | // Device Action 1 -> OffloadAction -> Device Action 2 | ||||
4862 | // | ||||
4863 | // c) Specify a device dependence to a host action; | ||||
4864 | // Device Action 1 _ | ||||
4865 | // \ | ||||
4866 | // Host Action 1 ---> OffloadAction -> Host Action 2 | ||||
4867 | // | ||||
4868 | // d) Specify a host dependence to a device action. | ||||
4869 | // Host Action 1 _ | ||||
4870 | // \ | ||||
4871 | // Device Action 1 ---> OffloadAction -> Device Action 2 | ||||
4872 | // | ||||
4873 | // For a) and b), we just return the job generated for the dependence. For | ||||
4874 | // c) and d) we override the current action with the host/device dependence | ||||
4875 | // if the current toolchain is host/device and set the offload dependences | ||||
4876 | // info with the jobs obtained from the device/host dependence(s). | ||||
4877 | |||||
4878 | // If there is a single device option, just generate the job for it. | ||||
4879 | if (OA->hasSingleDeviceDependence()) { | ||||
4880 | InputInfoList DevA; | ||||
4881 | OA->doOnEachDeviceDependence([&](Action *DepA, const ToolChain *DepTC, | ||||
4882 | const char *DepBoundArch) { | ||||
4883 | DevA = | ||||
4884 | BuildJobsForAction(C, DepA, DepTC, DepBoundArch, AtTopLevel, | ||||
4885 | /*MultipleArchs*/ !!DepBoundArch, LinkingOutput, | ||||
4886 | CachedResults, DepA->getOffloadingDeviceKind()); | ||||
4887 | }); | ||||
4888 | return DevA; | ||||
4889 | } | ||||
4890 | |||||
4891 | // If 'Action 2' is host, we generate jobs for the device dependences and | ||||
4892 | // override the current action with the host dependence. Otherwise, we | ||||
4893 | // generate the host dependences and override the action with the device | ||||
4894 | // dependence. The dependences can't therefore be a top-level action. | ||||
4895 | OA->doOnEachDependence( | ||||
4896 | /*IsHostDependence=*/BuildingForOffloadDevice, | ||||
4897 | [&](Action *DepA, const ToolChain *DepTC, const char *DepBoundArch) { | ||||
4898 | OffloadDependencesInputInfo.append(BuildJobsForAction( | ||||
4899 | C, DepA, DepTC, DepBoundArch, /*AtTopLevel=*/false, | ||||
4900 | /*MultipleArchs*/ !!DepBoundArch, LinkingOutput, CachedResults, | ||||
4901 | DepA->getOffloadingDeviceKind())); | ||||
4902 | }); | ||||
4903 | |||||
4904 | A = BuildingForOffloadDevice | ||||
4905 | ? OA->getSingleDeviceDependence(/*DoNotConsiderHostActions=*/true) | ||||
4906 | : OA->getHostDependence(); | ||||
4907 | |||||
4908 | // We may have already built this action as a part of the offloading | ||||
4909 | // toolchain, return the cached input if so. | ||||
4910 | std::pair<const Action *, std::string> ActionTC = { | ||||
4911 | OA->getHostDependence(), | ||||
4912 | GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)}; | ||||
4913 | if (CachedResults.find(ActionTC) != CachedResults.end()) { | ||||
4914 | InputInfoList Inputs = CachedResults[ActionTC]; | ||||
4915 | Inputs.append(OffloadDependencesInputInfo); | ||||
4916 | return Inputs; | ||||
4917 | } | ||||
4918 | } | ||||
4919 | |||||
4920 | if (const InputAction *IA = dyn_cast<InputAction>(A)) { | ||||
4921 | // FIXME: It would be nice to not claim this here; maybe the old scheme of | ||||
4922 | // just using Args was better? | ||||
4923 | const Arg &Input = IA->getInputArg(); | ||||
4924 | Input.claim(); | ||||
4925 | if (Input.getOption().matches(options::OPT_INPUT)) { | ||||
4926 | const char *Name = Input.getValue(); | ||||
4927 | return {InputInfo(A, Name, /* _BaseInput = */ Name)}; | ||||
4928 | } | ||||
4929 | return {InputInfo(A, &Input, /* _BaseInput = */ "")}; | ||||
4930 | } | ||||
4931 | |||||
4932 | if (const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) { | ||||
4933 | const ToolChain *TC; | ||||
4934 | StringRef ArchName = BAA->getArchName(); | ||||
4935 | |||||
4936 | if (!ArchName.empty()) | ||||
4937 | TC = &getToolChain(C.getArgs(), | ||||
4938 | computeTargetTriple(*this, TargetTriple, | ||||
4939 | C.getArgs(), ArchName)); | ||||
4940 | else | ||||
4941 | TC = &C.getDefaultToolChain(); | ||||
4942 | |||||
4943 | return BuildJobsForAction(C, *BAA->input_begin(), TC, ArchName, AtTopLevel, | ||||
4944 | MultipleArchs, LinkingOutput, CachedResults, | ||||
4945 | TargetDeviceOffloadKind); | ||||
4946 | } | ||||
4947 | |||||
4948 | |||||
4949 | ActionList Inputs = A->getInputs(); | ||||
4950 | |||||
4951 | const JobAction *JA = cast<JobAction>(A); | ||||
4952 | ActionList CollapsedOffloadActions; | ||||
4953 | |||||
4954 | ToolSelector TS(JA, *TC, C, isSaveTempsEnabled(), | ||||
4955 | embedBitcodeInObject() && !isUsingLTO()); | ||||
4956 | const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions); | ||||
4957 | |||||
4958 | if (!T) | ||||
4959 | return {InputInfo()}; | ||||
4960 | |||||
4961 | if (BuildingForOffloadDevice && | ||||
4962 | A->getOffloadingDeviceKind() == Action::OFK_OpenMP) { | ||||
4963 | if (TC->getTriple().isAMDGCN()) { | ||||
4964 | // AMDGCN treats backend and assemble actions as no-op because | ||||
4965 | // linker does not support object files. | ||||
4966 | if (const BackendJobAction *BA = dyn_cast<BackendJobAction>(A)) { | ||||
4967 | return BuildJobsForAction(C, *BA->input_begin(), TC, BoundArch, | ||||
4968 | AtTopLevel, MultipleArchs, LinkingOutput, | ||||
4969 | CachedResults, TargetDeviceOffloadKind); | ||||
4970 | } | ||||
4971 | |||||
4972 | if (const AssembleJobAction *AA = dyn_cast<AssembleJobAction>(A)) { | ||||
4973 | return BuildJobsForAction(C, *AA->input_begin(), TC, BoundArch, | ||||
4974 | AtTopLevel, MultipleArchs, LinkingOutput, | ||||
4975 | CachedResults, TargetDeviceOffloadKind); | ||||
4976 | } | ||||
4977 | } | ||||
4978 | } | ||||
4979 | |||||
4980 | // If we've collapsed action list that contained OffloadAction we | ||||
4981 | // need to build jobs for host/device-side inputs it may have held. | ||||
4982 | for (const auto *OA : CollapsedOffloadActions) | ||||
4983 | cast<OffloadAction>(OA)->doOnEachDependence( | ||||
4984 | /*IsHostDependence=*/BuildingForOffloadDevice, | ||||
4985 | [&](Action *DepA, const ToolChain *DepTC, const char *DepBoundArch) { | ||||
4986 | OffloadDependencesInputInfo.append(BuildJobsForAction( | ||||
4987 | C, DepA, DepTC, DepBoundArch, /* AtTopLevel */ false, | ||||
4988 | /*MultipleArchs=*/!!DepBoundArch, LinkingOutput, CachedResults, | ||||
4989 | DepA->getOffloadingDeviceKind())); | ||||
4990 | }); | ||||
4991 | |||||
4992 | // Only use pipes when there is exactly one input. | ||||
4993 | InputInfoList InputInfos; | ||||
4994 | for (const Action *Input : Inputs) { | ||||
4995 | // Treat dsymutil and verify sub-jobs as being at the top-level too, they | ||||
4996 | // shouldn't get temporary output names. | ||||
4997 | // FIXME: Clean this up. | ||||
4998 | bool SubJobAtTopLevel = | ||||
4999 | AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A)); | ||||
5000 | InputInfos.append(BuildJobsForAction( | ||||
5001 | C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput, | ||||
5002 | CachedResults, A->getOffloadingDeviceKind())); | ||||
5003 | } | ||||
5004 | |||||
5005 | // Always use the first file input as the base input. | ||||
5006 | const char *BaseInput = InputInfos[0].getBaseInput(); | ||||
5007 | for (auto &Info : InputInfos) { | ||||
5008 | if (Info.isFilename()) { | ||||
5009 | BaseInput = Info.getBaseInput(); | ||||
5010 | break; | ||||
5011 | } | ||||
5012 | } | ||||
5013 | |||||
5014 | // ... except dsymutil actions, which use their actual input as the base | ||||
5015 | // input. | ||||
5016 | if (JA->getType() == types::TY_dSYM) | ||||
5017 | BaseInput = InputInfos[0].getFilename(); | ||||
5018 | |||||
5019 | // ... and in header module compilations, which use the module name. | ||||
5020 | if (auto *ModuleJA = dyn_cast<HeaderModulePrecompileJobAction>(JA)) | ||||
5021 | BaseInput = ModuleJA->getModuleName(); | ||||
5022 | |||||
5023 | // Append outputs of offload device jobs to the input list | ||||
5024 | if (!OffloadDependencesInputInfo.empty()) | ||||
5025 | InputInfos.append(OffloadDependencesInputInfo.begin(), | ||||
5026 | OffloadDependencesInputInfo.end()); | ||||
5027 | |||||
5028 | // Set the effective triple of the toolchain for the duration of this job. | ||||
5029 | llvm::Triple EffectiveTriple; | ||||
5030 | const ToolChain &ToolTC = T->getToolChain(); | ||||
5031 | const ArgList &Args = | ||||
5032 | C.getArgsForToolChain(TC, BoundArch, A->getOffloadingDeviceKind()); | ||||
5033 | if (InputInfos.size() != 1) { | ||||
5034 | EffectiveTriple = llvm::Triple(ToolTC.ComputeEffectiveClangTriple(Args)); | ||||
5035 | } else { | ||||
5036 | // Pass along the input type if it can be unambiguously determined. | ||||
5037 | EffectiveTriple = llvm::Triple( | ||||
5038 | ToolTC.ComputeEffectiveClangTriple(Args, InputInfos[0].getType())); | ||||
5039 | } | ||||
5040 | RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple); | ||||
5041 | |||||
5042 | // Determine the place to write output to, if any. | ||||
5043 | InputInfo Result; | ||||
5044 | InputInfoList UnbundlingResults; | ||||
5045 | if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) { | ||||
5046 | // If we have an unbundling job, we need to create results for all the | ||||
5047 | // outputs. We also update the results cache so that other actions using | ||||
5048 | // this unbundling action can get the right results. | ||||
5049 | for (auto &UI : UA->getDependentActionsInfo()) { | ||||
5050 | assert(UI.DependentOffloadKind != Action::OFK_None &&(static_cast <bool> (UI.DependentOffloadKind != Action:: OFK_None && "Unbundling with no offloading??") ? void (0) : __assert_fail ("UI.DependentOffloadKind != Action::OFK_None && \"Unbundling with no offloading??\"" , "clang/lib/Driver/Driver.cpp", 5051, __extension__ __PRETTY_FUNCTION__ )) | ||||
5051 | "Unbundling with no offloading??")(static_cast <bool> (UI.DependentOffloadKind != Action:: OFK_None && "Unbundling with no offloading??") ? void (0) : __assert_fail ("UI.DependentOffloadKind != Action::OFK_None && \"Unbundling with no offloading??\"" , "clang/lib/Driver/Driver.cpp", 5051, __extension__ __PRETTY_FUNCTION__ )); | ||||
5052 | |||||
5053 | // Unbundling actions are never at the top level. When we generate the | ||||
5054 | // offloading prefix, we also do that for the host file because the | ||||
5055 | // unbundling action does not change the type of the output which can | ||||
5056 | // cause a overwrite. | ||||
5057 | std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix( | ||||
5058 | UI.DependentOffloadKind, | ||||
5059 | UI.DependentToolChain->getTriple().normalize(), | ||||
5060 | /*CreatePrefixForHost=*/true); | ||||
5061 | auto CurI = InputInfo( | ||||
5062 | UA, | ||||
5063 | GetNamedOutputPath(C, *UA, BaseInput, UI.DependentBoundArch, | ||||
5064 | /*AtTopLevel=*/false, | ||||
5065 | MultipleArchs || | ||||
5066 | UI.DependentOffloadKind == Action::OFK_HIP, | ||||
5067 | OffloadingPrefix), | ||||
5068 | BaseInput); | ||||
5069 | // Save the unbundling result. | ||||
5070 | UnbundlingResults.push_back(CurI); | ||||
5071 | |||||
5072 | // Get the unique string identifier for this dependence and cache the | ||||
5073 | // result. | ||||
5074 | StringRef Arch; | ||||
5075 | if (TargetDeviceOffloadKind == Action::OFK_HIP) { | ||||
5076 | if (UI.DependentOffloadKind == Action::OFK_Host) | ||||
5077 | Arch = StringRef(); | ||||
5078 | else | ||||
5079 | Arch = UI.DependentBoundArch; | ||||
5080 | } else | ||||
5081 | Arch = BoundArch; | ||||
5082 | |||||
5083 | CachedResults[{A, GetTriplePlusArchString(UI.DependentToolChain, Arch, | ||||
5084 | UI.DependentOffloadKind)}] = { | ||||
5085 | CurI}; | ||||
5086 | } | ||||
5087 | |||||
5088 | // Now that we have all the results generated, select the one that should be | ||||
5089 | // returned for the current depending action. | ||||
5090 | std::pair<const Action *, std::string> ActionTC = { | ||||
5091 | A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)}; | ||||
5092 | assert(CachedResults.find(ActionTC) != CachedResults.end() &&(static_cast <bool> (CachedResults.find(ActionTC) != CachedResults .end() && "Result does not exist??") ? void (0) : __assert_fail ("CachedResults.find(ActionTC) != CachedResults.end() && \"Result does not exist??\"" , "clang/lib/Driver/Driver.cpp", 5093, __extension__ __PRETTY_FUNCTION__ )) | ||||
5093 | "Result does not exist??")(static_cast <bool> (CachedResults.find(ActionTC) != CachedResults .end() && "Result does not exist??") ? void (0) : __assert_fail ("CachedResults.find(ActionTC) != CachedResults.end() && \"Result does not exist??\"" , "clang/lib/Driver/Driver.cpp", 5093, __extension__ __PRETTY_FUNCTION__ )); | ||||
5094 | Result = CachedResults[ActionTC].front(); | ||||
5095 | } else if (JA->getType() == types::TY_Nothing) | ||||
5096 | Result = {InputInfo(A, BaseInput)}; | ||||
5097 | else { | ||||
5098 | // We only have to generate a prefix for the host if this is not a top-level | ||||
5099 | // action. | ||||
5100 | std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix( | ||||
5101 | A->getOffloadingDeviceKind(), TC->getTriple().normalize(), | ||||
5102 | /*CreatePrefixForHost=*/!!A->getOffloadingHostActiveKinds() && | ||||
5103 | !AtTopLevel); | ||||
5104 | if (isa<OffloadWrapperJobAction>(JA)) { | ||||
5105 | if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) | ||||
5106 | BaseInput = FinalOutput->getValue(); | ||||
5107 | else | ||||
5108 | BaseInput = getDefaultImageName(); | ||||
5109 | BaseInput = | ||||
5110 | C.getArgs().MakeArgString(std::string(BaseInput) + "-wrapper"); | ||||
5111 | } | ||||
5112 | Result = InputInfo(A, GetNamedOutputPath(C, *JA, BaseInput, BoundArch, | ||||
5113 | AtTopLevel, MultipleArchs, | ||||
5114 | OffloadingPrefix), | ||||
5115 | BaseInput); | ||||
5116 | } | ||||
5117 | |||||
5118 | if (CCCPrintBindings && !CCGenDiagnostics) { | ||||
5119 | llvm::errs() << "# \"" << T->getToolChain().getTripleString() << '"' | ||||
5120 | << " - \"" << T->getName() << "\", inputs: ["; | ||||
5121 | for (unsigned i = 0, e = InputInfos.size(); i != e; ++i) { | ||||
5122 | llvm::errs() << InputInfos[i].getAsString(); | ||||
5123 | if (i + 1 != e) | ||||
5124 | llvm::errs() << ", "; | ||||
5125 | } | ||||
5126 | if (UnbundlingResults.empty()) | ||||
5127 | llvm::errs() << "], output: " << Result.getAsString() << "\n"; | ||||
5128 | else { | ||||
5129 | llvm::errs() << "], outputs: ["; | ||||
5130 | for (unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) { | ||||
5131 | llvm::errs() << UnbundlingResults[i].getAsString(); | ||||
5132 | if (i + 1 != e) | ||||
5133 | llvm::errs() << ", "; | ||||
5134 | } | ||||
5135 | llvm::errs() << "] \n"; | ||||
5136 | } | ||||
5137 | } else { | ||||
5138 | if (UnbundlingResults.empty()) | ||||
5139 | T->ConstructJob( | ||||
5140 | C, *JA, Result, InputInfos, | ||||
5141 | C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()), | ||||
5142 | LinkingOutput); | ||||
5143 | else | ||||
5144 | T->ConstructJobMultipleOutputs( | ||||
5145 | C, *JA, UnbundlingResults, InputInfos, | ||||
5146 | C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()), | ||||
5147 | LinkingOutput); | ||||
5148 | } | ||||
5149 | return {Result}; | ||||
5150 | } | ||||
5151 | |||||
5152 | const char *Driver::getDefaultImageName() const { | ||||
5153 | llvm::Triple Target(llvm::Triple::normalize(TargetTriple)); | ||||
5154 | return Target.isOSWindows() ? "a.exe" : "a.out"; | ||||
5155 | } | ||||
5156 | |||||
5157 | /// Create output filename based on ArgValue, which could either be a | ||||
5158 | /// full filename, filename without extension, or a directory. If ArgValue | ||||
5159 | /// does not provide a filename, then use BaseName, and use the extension | ||||
5160 | /// suitable for FileType. | ||||
5161 | static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, | ||||
5162 | StringRef BaseName, | ||||
5163 | types::ID FileType) { | ||||
5164 | SmallString<128> Filename = ArgValue; | ||||
5165 | |||||
5166 | if (ArgValue.empty()) { | ||||
5167 | // If the argument is empty, output to BaseName in the current dir. | ||||
5168 | Filename = BaseName; | ||||
5169 | } else if (llvm::sys::path::is_separator(Filename.back())) { | ||||
5170 | // If the argument is a directory, output to BaseName in that dir. | ||||
5171 | llvm::sys::path::append(Filename, BaseName); | ||||
5172 | } | ||||
5173 | |||||
5174 | if (!llvm::sys::path::has_extension(ArgValue)) { | ||||
5175 | // If the argument didn't provide an extension, then set it. | ||||
5176 | const char *Extension = types::getTypeTempSuffix(FileType, true); | ||||
5177 | |||||
5178 | if (FileType == types::TY_Image && | ||||
5179 | Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) { | ||||
5180 | // The output file is a dll. | ||||
5181 | Extension = "dll"; | ||||
5182 | } | ||||
5183 | |||||
5184 | llvm::sys::path::replace_extension(Filename, Extension); | ||||
5185 | } | ||||
5186 | |||||
5187 | return Args.MakeArgString(Filename.c_str()); | ||||
5188 | } | ||||
5189 | |||||
5190 | static bool HasPreprocessOutput(const Action &JA) { | ||||
5191 | if (isa<PreprocessJobAction>(JA)) | ||||
5192 | return true; | ||||
5193 | if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.getInputs()[0])) | ||||
5194 | return true; | ||||
5195 | if (isa<OffloadBundlingJobAction>(JA) && | ||||
5196 | HasPreprocessOutput(*(JA.getInputs()[0]))) | ||||
5197 | return true; | ||||
5198 | return false; | ||||
5199 | } | ||||
5200 | |||||
5201 | const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, | ||||
5202 | const char *BaseInput, | ||||
5203 | StringRef OrigBoundArch, bool AtTopLevel, | ||||
5204 | bool MultipleArchs, | ||||
5205 | StringRef OffloadingPrefix) const { | ||||
5206 | std::string BoundArch = OrigBoundArch.str(); | ||||
5207 | if (is_style_windows(llvm::sys::path::Style::native)) { | ||||
| |||||
5208 | // BoundArch may contains ':', which is invalid in file names on Windows, | ||||
5209 | // therefore replace it with '%'. | ||||
5210 | std::replace(BoundArch.begin(), BoundArch.end(), ':', '@'); | ||||
5211 | } | ||||
5212 | |||||
5213 | llvm::PrettyStackTraceString CrashInfo("Computing output path"); | ||||
5214 | // Output to a user requested destination? | ||||
5215 | if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) { | ||||
5216 | if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) | ||||
5217 | return C.addResultFile(FinalOutput->getValue(), &JA); | ||||
5218 | } | ||||
5219 | |||||
5220 | // For /P, preprocess to file named after BaseInput. | ||||
5221 | if (C.getArgs().hasArg(options::OPT__SLASH_P)) { | ||||
5222 | assert(AtTopLevel && isa<PreprocessJobAction>(JA))(static_cast <bool> (AtTopLevel && isa<PreprocessJobAction >(JA)) ? void (0) : __assert_fail ("AtTopLevel && isa<PreprocessJobAction>(JA)" , "clang/lib/Driver/Driver.cpp", 5222, __extension__ __PRETTY_FUNCTION__ )); | ||||
5223 | StringRef BaseName = llvm::sys::path::filename(BaseInput); | ||||
5224 | StringRef NameArg; | ||||
5225 | if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi)) | ||||
5226 | NameArg = A->getValue(); | ||||
5227 | return C.addResultFile( | ||||
5228 | MakeCLOutputFilename(C.getArgs(), NameArg, BaseName, types::TY_PP_C), | ||||
5229 | &JA); | ||||
5230 | } | ||||
5231 | |||||
5232 | // Default to writing to stdout? | ||||
5233 | if (AtTopLevel
| ||||
5234 | return "-"; | ||||
5235 | } | ||||
5236 | |||||
5237 | if (JA.getType() == types::TY_ModuleFile && | ||||
5238 | C.getArgs().getLastArg(options::OPT_module_file_info)) { | ||||
5239 | return "-"; | ||||
5240 | } | ||||
5241 | |||||
5242 | // Is this the assembly listing for /FA? | ||||
5243 | if (JA.getType() == types::TY_PP_Asm && | ||||
5244 | (C.getArgs().hasArg(options::OPT__SLASH_FA) || | ||||
5245 | C.getArgs().hasArg(options::OPT__SLASH_Fa))) { | ||||
5246 | // Use /Fa and the input filename to determine the asm file name. | ||||
5247 | StringRef BaseName = llvm::sys::path::filename(BaseInput); | ||||
5248 | StringRef FaValue = C.getArgs().getLastArgValue(options::OPT__SLASH_Fa); | ||||
5249 | return C.addResultFile( | ||||
5250 | MakeCLOutputFilename(C.getArgs(), FaValue, BaseName, JA.getType()), | ||||
5251 | &JA); | ||||
5252 | } | ||||
5253 | |||||
5254 | // Output to a temporary file? | ||||
5255 | if ((!AtTopLevel
| ||||
5256 | !C.getArgs().hasArg(options::OPT__SLASH_Fo)) || | ||||
5257 | CCGenDiagnostics
| ||||
5258 | StringRef Name = llvm::sys::path::filename(BaseInput); | ||||
5259 | std::pair<StringRef, StringRef> Split = Name.split('.'); | ||||
5260 | SmallString<128> TmpName; | ||||
5261 | const char *Suffix = types::getTypeTempSuffix(JA.getType(), IsCLMode()); | ||||
5262 | Arg *A = C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir); | ||||
5263 | if (CCGenDiagnostics
| ||||
5264 | SmallString<128> CrashDirectory(A->getValue()); | ||||
5265 | if (!getVFS().exists(CrashDirectory)) | ||||
5266 | llvm::sys::fs::create_directories(CrashDirectory); | ||||
5267 | llvm::sys::path::append(CrashDirectory, Split.first); | ||||
5268 | const char *Middle = Suffix ? "-%%%%%%." : "-%%%%%%"; | ||||
5269 | std::error_code EC = llvm::sys::fs::createUniqueFile( | ||||
5270 | CrashDirectory + Middle + Suffix, TmpName); | ||||
5271 | if (EC) { | ||||
5272 | Diag(clang::diag::err_unable_to_make_temp) << EC.message(); | ||||
5273 | return ""; | ||||
5274 | } | ||||
5275 | } else { | ||||
5276 | if (MultipleArchs && !BoundArch.empty()) { | ||||
5277 | TmpName = GetTemporaryDirectory(Split.first); | ||||
5278 | llvm::sys::path::append(TmpName, | ||||
5279 | Split.first + "-" + BoundArch + "." + Suffix); | ||||
5280 | } else { | ||||
5281 | TmpName = GetTemporaryPath(Split.first, Suffix); | ||||
5282 | } | ||||
5283 | } | ||||
5284 | return C.addTempFile(C.getArgs().MakeArgString(TmpName)); | ||||
5285 | } | ||||
5286 | |||||
5287 | SmallString<128> BasePath(BaseInput); | ||||
5288 | SmallString<128> ExternalPath(""); | ||||
5289 | StringRef BaseName; | ||||
5290 | |||||
5291 | // Dsymutil actions should use the full path. | ||||
5292 | if (isa<DsymutilJobAction>(JA) && C.getArgs().hasArg(options::OPT_dsym_dir)) { | ||||
5293 | ExternalPath += C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue(); | ||||
5294 | // We use posix style here because the tests (specifically | ||||
5295 | // darwin-dsymutil.c) demonstrate that posix style paths are acceptable | ||||
5296 | // even on Windows and if we don't then the similar test covering this | ||||
5297 | // fails. | ||||
5298 | llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix, | ||||
5299 | llvm::sys::path::filename(BasePath)); | ||||
5300 | BaseName = ExternalPath; | ||||
5301 | } else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA)) | ||||
5302 | BaseName = BasePath; | ||||
5303 | else | ||||
5304 | BaseName = llvm::sys::path::filename(BasePath); | ||||
5305 | |||||
5306 | // Determine what the derived output name should be. | ||||
5307 | const char *NamedOutput; | ||||
5308 | |||||
5309 | if ((JA.getType() == types::TY_Object || JA.getType() == types::TY_LTO_BC) && | ||||
5310 | C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) { | ||||
5311 | // The /Fo or /o flag decides the object filename. | ||||
5312 | StringRef Val = | ||||
5313 | C.getArgs() | ||||
5314 | .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o) | ||||
5315 | ->getValue(); | ||||
5316 | NamedOutput = | ||||
5317 | MakeCLOutputFilename(C.getArgs(), Val, BaseName, types::TY_Object); | ||||
5318 | } else if (JA.getType() == types::TY_Image && | ||||
5319 | C.getArgs().hasArg(options::OPT__SLASH_Fe, | ||||
5320 | options::OPT__SLASH_o)) { | ||||
5321 | // The /Fe or /o flag names the linked file. | ||||
5322 | StringRef Val = | ||||
5323 | C.getArgs() | ||||
5324 | .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o) | ||||
5325 | ->getValue(); | ||||
5326 | NamedOutput = | ||||
5327 | MakeCLOutputFilename(C.getArgs(), Val, BaseName, types::TY_Image); | ||||
5328 | } else if (JA.getType() == types::TY_Image) { | ||||
5329 | if (IsCLMode()) { | ||||
5330 | // clang-cl uses BaseName for the executable name. | ||||
5331 | NamedOutput = | ||||
5332 | MakeCLOutputFilename(C.getArgs(), "", BaseName, types::TY_Image); | ||||
5333 | } else { | ||||
5334 | SmallString<128> Output(getDefaultImageName()); | ||||
5335 | // HIP image for device compilation with -fno-gpu-rdc is per compilation | ||||
5336 | // unit. | ||||
5337 | bool IsHIPNoRDC = JA.getOffloadingDeviceKind() == Action::OFK_HIP && | ||||
5338 | !C.getArgs().hasFlag(options::OPT_fgpu_rdc, | ||||
5339 | options::OPT_fno_gpu_rdc, false); | ||||
5340 | if (IsHIPNoRDC) { | ||||
5341 | Output = BaseName; | ||||
5342 | llvm::sys::path::replace_extension(Output, ""); | ||||
5343 | } | ||||
5344 | Output += OffloadingPrefix; | ||||
5345 | if (MultipleArchs && !BoundArch.empty()) { | ||||
5346 | Output += "-"; | ||||
5347 | Output.append(BoundArch); | ||||
5348 | } | ||||
5349 | if (IsHIPNoRDC) | ||||
5350 | Output += ".out"; | ||||
5351 | NamedOutput = C.getArgs().MakeArgString(Output.c_str()); | ||||
5352 | } | ||||
5353 | } else if (JA.getType() == types::TY_PCH && IsCLMode()) { | ||||
5354 | NamedOutput = C.getArgs().MakeArgString(GetClPchPath(C, BaseName)); | ||||
5355 | } else { | ||||
5356 | const char *Suffix = types::getTypeTempSuffix(JA.getType(), IsCLMode()); | ||||
5357 | assert(Suffix && "All types used for output should have a suffix.")(static_cast <bool> (Suffix && "All types used for output should have a suffix." ) ? void (0) : __assert_fail ("Suffix && \"All types used for output should have a suffix.\"" , "clang/lib/Driver/Driver.cpp", 5357, __extension__ __PRETTY_FUNCTION__ )); | ||||
5358 | |||||
5359 | std::string::size_type End = std::string::npos; | ||||
5360 | if (!types::appendSuffixForType(JA.getType())) | ||||
5361 | End = BaseName.rfind('.'); | ||||
5362 | SmallString<128> Suffixed(BaseName.substr(0, End)); | ||||
5363 | Suffixed += OffloadingPrefix; | ||||
5364 | if (MultipleArchs && !BoundArch.empty()) { | ||||
5365 | Suffixed += "-"; | ||||
5366 | Suffixed.append(BoundArch); | ||||
5367 | } | ||||
5368 | // When using both -save-temps and -emit-llvm, use a ".tmp.bc" suffix for | ||||
5369 | // the unoptimized bitcode so that it does not get overwritten by the ".bc" | ||||
5370 | // optimized bitcode output. | ||||
5371 | auto IsHIPRDCInCompilePhase = [](const JobAction &JA, | ||||
5372 | const llvm::opt::DerivedArgList &Args) { | ||||
5373 | // The relocatable compilation in HIP implies -emit-llvm. Similarly, use a | ||||
5374 | // ".tmp.bc" suffix for the unoptimized bitcode (generated in the compile | ||||
5375 | // phase.) | ||||
5376 | return isa<CompileJobAction>(JA) && | ||||
5377 | JA.getOffloadingDeviceKind() == Action::OFK_HIP && | ||||
5378 | Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, | ||||
5379 | false); | ||||
5380 | }; | ||||
5381 | if (!AtTopLevel && JA.getType() == types::TY_LLVM_BC && | ||||
5382 | (C.getArgs().hasArg(options::OPT_emit_llvm) || | ||||
5383 | IsHIPRDCInCompilePhase(JA, C.getArgs()))) | ||||
5384 | Suffixed += ".tmp"; | ||||
5385 | Suffixed += '.'; | ||||
5386 | Suffixed += Suffix; | ||||
5387 | NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str()); | ||||
5388 | } | ||||
5389 | |||||
5390 | // Prepend object file path if -save-temps=obj | ||||
5391 | if (!AtTopLevel && isSaveTempsObj() && C.getArgs().hasArg(options::OPT_o) && | ||||
5392 | JA.getType() != types::TY_PCH) { | ||||
5393 | Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o); | ||||
5394 | SmallString<128> TempPath(FinalOutput->getValue()); | ||||
5395 | llvm::sys::path::remove_filename(TempPath); | ||||
5396 | StringRef OutputFileName = llvm::sys::path::filename(NamedOutput); | ||||
5397 | llvm::sys::path::append(TempPath, OutputFileName); | ||||
5398 | NamedOutput = C.getArgs().MakeArgString(TempPath.c_str()); | ||||
5399 | } | ||||
5400 | |||||
5401 | // If we're saving temps and the temp file conflicts with the input file, | ||||
5402 | // then avoid overwriting input file. | ||||
5403 | if (!AtTopLevel && isSaveTempsEnabled() && NamedOutput == BaseName) { | ||||
5404 | bool SameFile = false; | ||||
5405 | SmallString<256> Result; | ||||
5406 | llvm::sys::fs::current_path(Result); | ||||
5407 | llvm::sys::path::append(Result, BaseName); | ||||
5408 | llvm::sys::fs::equivalent(BaseInput, Result.c_str(), SameFile); | ||||
5409 | // Must share the same path to conflict. | ||||
5410 | if (SameFile) { | ||||
5411 | StringRef Name = llvm::sys::path::filename(BaseInput); | ||||
5412 | std::pair<StringRef, StringRef> Split = Name.split('.'); | ||||
5413 | std::string TmpName = GetTemporaryPath( | ||||
5414 | Split.first, types::getTypeTempSuffix(JA.getType(), IsCLMode())); | ||||
5415 | return C.addTempFile(C.getArgs().MakeArgString(TmpName)); | ||||
5416 | } | ||||
5417 | } | ||||
5418 | |||||
5419 | // As an annoying special case, PCH generation doesn't strip the pathname. | ||||
5420 | if (JA.getType() == types::TY_PCH && !IsCLMode()) { | ||||
5421 | llvm::sys::path::remove_filename(BasePath); | ||||
5422 | if (BasePath.empty()) | ||||
5423 | BasePath = NamedOutput; | ||||
5424 | else | ||||
5425 | llvm::sys::path::append(BasePath, NamedOutput); | ||||
5426 | return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str()), &JA); | ||||
5427 | } else { | ||||
5428 | return C.addResultFile(NamedOutput, &JA); | ||||
5429 | } | ||||
5430 | } | ||||
5431 | |||||
5432 | std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const { | ||||
5433 | // Search for Name in a list of paths. | ||||
5434 | auto SearchPaths = [&](const llvm::SmallVectorImpl<std::string> &P) | ||||
5435 | -> llvm::Optional<std::string> { | ||||
5436 | // Respect a limited subset of the '-Bprefix' functionality in GCC by | ||||
5437 | // attempting to use this prefix when looking for file paths. | ||||
5438 | for (const auto &Dir : P) { | ||||
5439 | if (Dir.empty()) | ||||
5440 | continue; | ||||
5441 | SmallString<128> P(Dir[0] == '=' ? SysRoot + Dir.substr(1) : Dir); | ||||
5442 | llvm::sys::path::append(P, Name); | ||||
5443 | if (llvm::sys::fs::exists(Twine(P))) | ||||
5444 | return std::string(P); | ||||
5445 | } | ||||
5446 | return None; | ||||
5447 | }; | ||||
5448 | |||||
5449 | if (auto P = SearchPaths(PrefixDirs)) | ||||
5450 | return *P; | ||||
5451 | |||||
5452 | SmallString<128> R(ResourceDir); | ||||
5453 | llvm::sys::path::append(R, Name); | ||||
5454 | if (llvm::sys::fs::exists(Twine(R))) | ||||
5455 | return std::string(R.str()); | ||||
5456 | |||||
5457 | SmallString<128> P(TC.getCompilerRTPath()); | ||||
5458 | llvm::sys::path::append(P, Name); | ||||
5459 | if (llvm::sys::fs::exists(Twine(P))) | ||||
5460 | return std::string(P.str()); | ||||
5461 | |||||
5462 | SmallString<128> D(Dir); | ||||
5463 | llvm::sys::path::append(D, "..", Name); | ||||
5464 | if (llvm::sys::fs::exists(Twine(D))) | ||||
5465 | return std::string(D.str()); | ||||
5466 | |||||
5467 | if (auto P = SearchPaths(TC.getLibraryPaths())) | ||||
5468 | return *P; | ||||
5469 | |||||
5470 | if (auto P = SearchPaths(TC.getFilePaths())) | ||||
5471 | return *P; | ||||
5472 | |||||
5473 | return std::string(Name); | ||||
5474 | } | ||||
5475 | |||||
5476 | void Driver::generatePrefixedToolNames( | ||||
5477 | StringRef Tool, const ToolChain &TC, | ||||
5478 | SmallVectorImpl<std::string> &Names) const { | ||||
5479 | // FIXME: Needs a better variable than TargetTriple | ||||
5480 | Names.emplace_back((TargetTriple + "-" + Tool).str()); | ||||
5481 | Names.emplace_back(Tool); | ||||
5482 | } | ||||
5483 | |||||
5484 | static bool ScanDirForExecutable(SmallString<128> &Dir, StringRef Name) { | ||||
5485 | llvm::sys::path::append(Dir, Name); | ||||
5486 | if (llvm::sys::fs::can_execute(Twine(Dir))) | ||||
5487 | return true; | ||||
5488 | llvm::sys::path::remove_filename(Dir); | ||||
5489 | return false; | ||||
5490 | } | ||||
5491 | |||||
5492 | std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const { | ||||
5493 | SmallVector<std::string, 2> TargetSpecificExecutables; | ||||
5494 | generatePrefixedToolNames(Name, TC, TargetSpecificExecutables); | ||||
5495 | |||||
5496 | // Respect a limited subset of the '-Bprefix' functionality in GCC by | ||||
5497 | // attempting to use this prefix when looking for program paths. | ||||
5498 | for (const auto &PrefixDir : PrefixDirs) { | ||||
5499 | if (llvm::sys::fs::is_directory(PrefixDir)) { | ||||
5500 | SmallString<128> P(PrefixDir); | ||||
5501 | if (ScanDirForExecutable(P, Name)) | ||||
5502 | return std::string(P.str()); | ||||
5503 | } else { | ||||
5504 | SmallString<128> P((PrefixDir + Name).str()); | ||||
5505 | if (llvm::sys::fs::can_execute(Twine(P))) | ||||
5506 | return std::string(P.str()); | ||||
5507 | } | ||||
5508 | } | ||||
5509 | |||||
5510 | const ToolChain::path_list &List = TC.getProgramPaths(); | ||||
5511 | for (const auto &TargetSpecificExecutable : TargetSpecificExecutables) { | ||||
5512 | // For each possible name of the tool look for it in | ||||
5513 | // program paths first, then the path. | ||||
5514 | // Higher priority names will be first, meaning that | ||||
5515 | // a higher priority name in the path will be found | ||||
5516 | // instead of a lower priority name in the program path. | ||||
5517 | // E.g. <triple>-gcc on the path will be found instead | ||||
5518 | // of gcc in the program path | ||||
5519 | for (const auto &Path : List) { | ||||
5520 | SmallString<128> P(Path); | ||||
5521 | if (ScanDirForExecutable(P, TargetSpecificExecutable)) | ||||
5522 | return std::string(P.str()); | ||||
5523 | } | ||||
5524 | |||||
5525 | // Fall back to the path | ||||
5526 | if (llvm::ErrorOr<std::string> P = | ||||
5527 | llvm::sys::findProgramByName(TargetSpecificExecutable)) | ||||
5528 | return *P; | ||||
5529 | } | ||||
5530 | |||||
5531 | return std::string(Name); | ||||
5532 | } | ||||
5533 | |||||
5534 | std::string Driver::GetTemporaryPath(StringRef Prefix, StringRef Suffix) const { | ||||
5535 | SmallString<128> Path; | ||||
5536 | std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path); | ||||
5537 | if (EC) { | ||||
5538 | Diag(clang::diag::err_unable_to_make_temp) << EC.message(); | ||||
5539 | return ""; | ||||
5540 | } | ||||
5541 | |||||
5542 | return std::string(Path.str()); | ||||
5543 | } | ||||
5544 | |||||
5545 | std::string Driver::GetTemporaryDirectory(StringRef Prefix) const { | ||||
5546 | SmallString<128> Path; | ||||
5547 | std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path); | ||||
5548 | if (EC) { | ||||
5549 | Diag(clang::diag::err_unable_to_make_temp) << EC.message(); | ||||
5550 | return ""; | ||||
5551 | } | ||||
5552 | |||||
5553 | return std::string(Path.str()); | ||||
5554 | } | ||||
5555 | |||||
5556 | std::string Driver::GetClPchPath(Compilation &C, StringRef BaseName) const { | ||||
5557 | SmallString<128> Output; | ||||
5558 | if (Arg *FpArg = C.getArgs().getLastArg(options::OPT__SLASH_Fp)) { | ||||
5559 | // FIXME: If anybody needs it, implement this obscure rule: | ||||
5560 | // "If you specify a directory without a file name, the default file name | ||||
5561 | // is VCx0.pch., where x is the major version of Visual C++ in use." | ||||
5562 | Output = FpArg->getValue(); | ||||
5563 | |||||
5564 | // "If you do not specify an extension as part of the path name, an | ||||
5565 | // extension of .pch is assumed. " | ||||
5566 | if (!llvm::sys::path::has_extension(Output)) | ||||
5567 | Output += ".pch"; | ||||
5568 | } else { | ||||
5569 | if (Arg *YcArg = C.getArgs().getLastArg(options::OPT__SLASH_Yc)) | ||||
5570 | Output = YcArg->getValue(); | ||||
5571 | if (Output.empty()) | ||||
5572 | Output = BaseName; | ||||
5573 | llvm::sys::path::replace_extension(Output, ".pch"); | ||||
5574 | } | ||||
5575 | return std::string(Output.str()); | ||||
5576 | } | ||||
5577 | |||||
5578 | const ToolChain &Driver::getToolChain(const ArgList &Args, | ||||
5579 | const llvm::Triple &Target) const { | ||||
5580 | |||||
5581 | auto &TC = ToolChains[Target.str()]; | ||||
5582 | if (!TC) { | ||||
5583 | switch (Target.getOS()) { | ||||
5584 | case llvm::Triple::AIX: | ||||
5585 | TC = std::make_unique<toolchains::AIX>(*this, Target, Args); | ||||
5586 | break; | ||||
5587 | case llvm::Triple::Haiku: | ||||
5588 | TC = std::make_unique<toolchains::Haiku>(*this, Target, Args); | ||||
5589 | break; | ||||
5590 | case llvm::Triple::Ananas: | ||||
5591 | TC = std::make_unique<toolchains::Ananas>(*this, Target, Args); | ||||
5592 | break; | ||||
5593 | case llvm::Triple::CloudABI: | ||||
5594 | TC = std::make_unique<toolchains::CloudABI>(*this, Target, Args); | ||||
5595 | break; | ||||
5596 | case llvm::Triple::Darwin: | ||||
5597 | case llvm::Triple::MacOSX: | ||||
5598 | case llvm::Triple::IOS: | ||||
5599 | case llvm::Triple::TvOS: | ||||
5600 | case llvm::Triple::WatchOS: | ||||
5601 | TC = std::make_unique<toolchains::DarwinClang>(*this, Target, Args); | ||||
5602 | break; | ||||
5603 | case llvm::Triple::DragonFly: | ||||
5604 | TC = std::make_unique<toolchains::DragonFly>(*this, Target, Args); | ||||
5605 | break; | ||||
5606 | case llvm::Triple::OpenBSD: | ||||
5607 | TC = std::make_unique<toolchains::OpenBSD>(*this, Target, Args); | ||||
5608 | break; | ||||
5609 | case llvm::Triple::NetBSD: | ||||
5610 | TC = std::make_unique<toolchains::NetBSD>(*this, Target, Args); | ||||
5611 | break; | ||||
5612 | case llvm::Triple::FreeBSD: | ||||
5613 | if (Target.isPPC()) | ||||
5614 | TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*this, Target, | ||||
5615 | Args); | ||||
5616 | else | ||||
5617 | TC = std::make_unique<toolchains::FreeBSD>(*this, Target, Args); | ||||
5618 | break; | ||||
5619 | case llvm::Triple::Minix: | ||||
5620 | TC = std::make_unique<toolchains::Minix>(*this, Target, Args); | ||||
5621 | break; | ||||
5622 | case llvm::Triple::Linux: | ||||
5623 | case llvm::Triple::ELFIAMCU: | ||||
5624 | if (Target.getArch() == llvm::Triple::hexagon) | ||||
5625 | TC = std::make_unique<toolchains::HexagonToolChain>(*this, Target, | ||||
5626 | Args); | ||||
5627 | else if ((Target.getVendor() == llvm::Triple::MipsTechnologies) && | ||||
5628 | !Target.hasEnvironment()) | ||||
5629 | TC = std::make_unique<toolchains::MipsLLVMToolChain>(*this, Target, | ||||
5630 | Args); | ||||
5631 | else if (Target.isPPC()) | ||||
5632 | TC = std::make_unique<toolchains::PPCLinuxToolChain>(*this, Target, | ||||
5633 | Args); | ||||
5634 | else if (Target.getArch() == llvm::Triple::ve) | ||||
5635 | TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args); | ||||
5636 | |||||
5637 | else | ||||
5638 | TC = std::make_unique<toolchains::Linux>(*this, Target, Args); | ||||
5639 | break; | ||||
5640 | case llvm::Triple::NaCl: | ||||
5641 | TC = std::make_unique<toolchains::NaClToolChain>(*this, Target, Args); | ||||
5642 | break; | ||||
5643 | case llvm::Triple::Fuchsia: | ||||
5644 | TC = std::make_unique<toolchains::Fuchsia>(*this, Target, Args); | ||||
5645 | break; | ||||
5646 | case llvm::Triple::Solaris: | ||||
5647 | TC = std::make_unique<toolchains::Solaris>(*this, Target, Args); | ||||
5648 | break; | ||||
5649 | case llvm::Triple::AMDHSA: | ||||
5650 | TC = std::make_unique<toolchains::ROCMToolChain>(*this, Target, Args); | ||||
5651 | break; | ||||
5652 | case llvm::Triple::AMDPAL: | ||||
5653 | case llvm::Triple::Mesa3D: | ||||
5654 | TC = std::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args); | ||||
5655 | break; | ||||
5656 | case llvm::Triple::Win32: | ||||
5657 | switch (Target.getEnvironment()) { | ||||
5658 | default: | ||||
5659 | if (Target.isOSBinFormatELF()) | ||||
5660 | TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args); | ||||
5661 | else if (Target.isOSBinFormatMachO()) | ||||
5662 | TC = std::make_unique<toolchains::MachO>(*this, Target, Args); | ||||
5663 | else | ||||
5664 | TC = std::make_unique<toolchains::Generic_GCC>(*this, Target, Args); | ||||
5665 | break; | ||||
5666 | case llvm::Triple::GNU: | ||||
5667 | TC = std::make_unique<toolchains::MinGW>(*this, Target, Args); | ||||
5668 | break; | ||||
5669 | case llvm::Triple::Itanium: | ||||
5670 | TC = std::make_unique<toolchains::CrossWindowsToolChain>(*this, Target, | ||||
5671 | Args); | ||||
5672 | break; | ||||
5673 | case llvm::Triple::MSVC: | ||||
5674 | case llvm::Triple::UnknownEnvironment: | ||||
5675 | if (Args.getLastArgValue(options::OPT_fuse_ld_EQ) | ||||
5676 | .startswith_insensitive("bfd")) | ||||
5677 | TC = std::make_unique<toolchains::CrossWindowsToolChain>( | ||||
5678 | *this, Target, Args); | ||||
5679 | else | ||||
5680 | TC = | ||||
5681 | std::make_unique<toolchains::MSVCToolChain>(*this, Target, Args); | ||||
5682 | break; | ||||
5683 | } | ||||
5684 | break; | ||||
5685 | case llvm::Triple::PS4: | ||||
5686 | TC = std::make_unique<toolchains::PS4CPU>(*this, Target, Args); | ||||
5687 | break; | ||||
5688 | case llvm::Triple::PS5: | ||||
5689 | TC = std::make_unique<toolchains::PS5CPU>(*this, Target, Args); | ||||
5690 | break; | ||||
5691 | case llvm::Triple::Contiki: | ||||
5692 | TC = std::make_unique<toolchains::Contiki>(*this, Target, Args); | ||||
5693 | break; | ||||
5694 | case llvm::Triple::Hurd: | ||||
5695 | TC = std::make_unique<toolchains::Hurd>(*this, Target, Args); | ||||
5696 | break; | ||||
5697 | case llvm::Triple::ZOS: | ||||
5698 | TC = std::make_unique<toolchains::ZOS>(*this, Target, Args); | ||||
5699 | break; | ||||
5700 | case llvm::Triple::ShaderModel: | ||||
5701 | TC = std::make_unique<toolchains::HLSLToolChain>(*this, Target, Args); | ||||
5702 | break; | ||||
5703 | default: | ||||
5704 | // Of these targets, Hexagon is the only one that might have | ||||
5705 | // an OS of Linux, in which case it got handled above already. | ||||
5706 | switch (Target.getArch()) { | ||||
5707 | case llvm::Triple::tce: | ||||
5708 | TC = std::make_unique<toolchains::TCEToolChain>(*this, Target, Args); | ||||
5709 | break; | ||||
5710 | case llvm::Triple::tcele: | ||||
5711 | TC = std::make_unique<toolchains::TCELEToolChain>(*this, Target, Args); | ||||
5712 | break; | ||||
5713 | case llvm::Triple::hexagon: | ||||
5714 | TC = std::make_unique<toolchains::HexagonToolChain>(*this, Target, | ||||
5715 | Args); | ||||
5716 | break; | ||||
5717 | case llvm::Triple::lanai: | ||||
5718 | TC = std::make_unique<toolchains::LanaiToolChain>(*this, Target, Args); | ||||
5719 | break; | ||||
5720 | case llvm::Triple::xcore: | ||||
5721 | TC = std::make_unique<toolchains::XCoreToolChain>(*this, Target, Args); | ||||
5722 | break; | ||||
5723 | case llvm::Triple::wasm32: | ||||
5724 | case llvm::Triple::wasm64: | ||||
5725 | TC = std::make_unique<toolchains::WebAssembly>(*this, Target, Args); | ||||
5726 | break; | ||||
5727 | case llvm::Triple::avr: | ||||
5728 | TC = std::make_unique<toolchains::AVRToolChain>(*this, Target, Args); | ||||
5729 | break; | ||||
5730 | case llvm::Triple::msp430: | ||||
5731 | TC = | ||||
5732 | std::make_unique<toolchains::MSP430ToolChain>(*this, Target, Args); | ||||
5733 | break; | ||||
5734 | case llvm::Triple::riscv32: | ||||
5735 | case llvm::Triple::riscv64: | ||||
5736 | if (toolchains::RISCVToolChain::hasGCCToolchain(*this, Args)) | ||||
5737 | TC = | ||||
5738 | std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args); | ||||
5739 | else | ||||
5740 | TC = std::make_unique<toolchains::BareMetal>(*this, Target, Args); | ||||
5741 | break; | ||||
5742 | case llvm::Triple::ve: | ||||
5743 | TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args); | ||||
5744 | break; | ||||
5745 | case llvm::Triple::spirv32: | ||||
5746 | case llvm::Triple::spirv64: | ||||
5747 | TC = std::make_unique<toolchains::SPIRVToolChain>(*this, Target, Args); | ||||
5748 | break; | ||||
5749 | case llvm::Triple::csky: | ||||
5750 | TC = std::make_unique<toolchains::CSKYToolChain>(*this, Target, Args); | ||||
5751 | break; | ||||
5752 | default: | ||||
5753 | if (Target.getVendor() == llvm::Triple::Myriad) | ||||
5754 | TC = std::make_unique<toolchains::MyriadToolChain>(*this, Target, | ||||
5755 | Args); | ||||
5756 | else if (toolchains::BareMetal::handlesTarget(Target)) | ||||
5757 | TC = std::make_unique<toolchains::BareMetal>(*this, Target, Args); | ||||
5758 | else if (Target.isOSBinFormatELF()) | ||||
5759 | TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args); | ||||
5760 | else if (Target.isOSBinFormatMachO()) | ||||
5761 | TC = std::make_unique<toolchains::MachO>(*this, Target, Args); | ||||
5762 | else | ||||
5763 | TC = std::make_unique<toolchains::Generic_GCC>(*this, Target, Args); | ||||
5764 | } | ||||
5765 | } | ||||
5766 | } | ||||
5767 | |||||
5768 | // Intentionally omitted from the switch above: llvm::Triple::CUDA. CUDA | ||||
5769 | // compiles always need two toolchains, the CUDA toolchain and the host | ||||
5770 | // toolchain. So the only valid way to create a CUDA toolchain is via | ||||
5771 | // CreateOffloadingDeviceToolChains. | ||||
5772 | |||||
5773 | return *TC; | ||||
5774 | } | ||||
5775 | |||||
5776 | const ToolChain &Driver::getOffloadingDeviceToolChain( | ||||
5777 | const ArgList &Args, const llvm::Triple &Target, const ToolChain &HostTC, | ||||
5778 | const Action::OffloadKind &TargetDeviceOffloadKind) const { | ||||
5779 | // Use device / host triples as the key into the ToolChains map because the | ||||
5780 | // device ToolChain we create depends on both. | ||||
5781 | auto &TC = ToolChains[Target.str() + "/" + HostTC.getTriple().str()]; | ||||
5782 | if (!TC) { | ||||
5783 | // Categorized by offload kind > arch rather than OS > arch like | ||||
5784 | // the normal getToolChain call, as it seems a reasonable way to categorize | ||||
5785 | // things. | ||||
5786 | switch (TargetDeviceOffloadKind) { | ||||
5787 | case Action::OFK_HIP: { | ||||
5788 | if (Target.getArch() == llvm::Triple::amdgcn && | ||||
5789 | Target.getVendor() == llvm::Triple::AMD && | ||||
5790 | Target.getOS() == llvm::Triple::AMDHSA) | ||||
5791 | TC = std::make_unique<toolchains::HIPAMDToolChain>(*this, Target, | ||||
5792 | HostTC, Args); | ||||
5793 | else if (Target.getArch() == llvm::Triple::spirv64 && | ||||
5794 | Target.getVendor() == llvm::Triple::UnknownVendor && | ||||
5795 | Target.getOS() == llvm::Triple::UnknownOS) | ||||
5796 | TC = std::make_unique<toolchains::HIPSPVToolChain>(*this, Target, | ||||
5797 | HostTC, Args); | ||||
5798 | break; | ||||
5799 | } | ||||
5800 | default: | ||||
5801 | break; | ||||
5802 | } | ||||
5803 | } | ||||
5804 | |||||
5805 | return *TC; | ||||
5806 | } | ||||
5807 | |||||
5808 | bool Driver::ShouldUseClangCompiler(const JobAction &JA) const { | ||||
5809 | // Say "no" if there is not exactly one input of a type clang understands. | ||||
5810 | if (JA.size() != 1 || | ||||
5811 | !types::isAcceptedByClang((*JA.input_begin())->getType())) | ||||
5812 | return false; | ||||
5813 | |||||
5814 | // And say "no" if this is not a kind of action clang understands. | ||||
5815 | if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) && | ||||
5816 | !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) && | ||||
5817 | !isa<ExtractAPIJobAction>(JA)) | ||||
5818 | return false; | ||||
5819 | |||||
5820 | return true; | ||||
5821 | } | ||||
5822 | |||||
5823 | bool Driver::ShouldUseFlangCompiler(const JobAction &JA) const { | ||||
5824 | // Say "no" if there is not exactly one input of a type flang understands. | ||||
5825 | if (JA.size() != 1 || | ||||
5826 | !types::isFortran((*JA.input_begin())->getType())) | ||||
5827 | return false; | ||||
5828 | |||||
5829 | // And say "no" if this is not a kind of action flang understands. | ||||
5830 | if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA)) | ||||
5831 | return false; | ||||
5832 | |||||
5833 | return true; | ||||
5834 | } | ||||
5835 | |||||
5836 | bool Driver::ShouldEmitStaticLibrary(const ArgList &Args) const { | ||||
5837 | // Only emit static library if the flag is set explicitly. | ||||
5838 | if (Args.hasArg(options::OPT_emit_static_lib)) | ||||
5839 | return true; | ||||
5840 | return false; | ||||
5841 | } | ||||
5842 | |||||
5843 | /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the | ||||
5844 | /// grouped values as integers. Numbers which are not provided are set to 0. | ||||
5845 | /// | ||||
5846 | /// \return True if the entire string was parsed (9.2), or all groups were | ||||
5847 | /// parsed (10.3.5extrastuff). | ||||
5848 | bool Driver::GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, | ||||
5849 | unsigned &Micro, bool &HadExtra) { | ||||
5850 | HadExtra = false; | ||||
5851 | |||||
5852 | Major = Minor = Micro = 0; | ||||
5853 | if (Str.empty()) | ||||
5854 | return false; | ||||
5855 | |||||
5856 | if (Str.consumeInteger(10, Major)) | ||||
5857 | return false; | ||||
5858 | if (Str.empty()) | ||||
5859 | return true; | ||||
5860 | if (Str[0] != '.') | ||||
5861 | return false; | ||||
5862 | |||||
5863 | Str = Str.drop_front(1); | ||||
5864 | |||||
5865 | if (Str.consumeInteger(10, Minor)) | ||||
5866 | return false; | ||||
5867 | if (Str.empty()) | ||||
5868 | return true; | ||||
5869 | if (Str[0] != '.') | ||||
5870 | return false; | ||||
5871 | Str = Str.drop_front(1); | ||||
5872 | |||||
5873 | if (Str.consumeInteger(10, Micro)) | ||||
5874 | return false; | ||||
5875 | if (!Str.empty()) | ||||
5876 | HadExtra = true; | ||||
5877 | return true; | ||||
5878 | } | ||||
5879 | |||||
5880 | /// Parse digits from a string \p Str and fulfill \p Digits with | ||||
5881 | /// the parsed numbers. This method assumes that the max number of | ||||
5882 | /// digits to look for is equal to Digits.size(). | ||||
5883 | /// | ||||
5884 | /// \return True if the entire string was parsed and there are | ||||
5885 | /// no extra characters remaining at the end. | ||||
5886 | bool Driver::GetReleaseVersion(StringRef Str, | ||||
5887 | MutableArrayRef<unsigned> Digits) { | ||||
5888 | if (Str.empty()) | ||||
5889 | return false; | ||||
5890 | |||||
5891 | unsigned CurDigit = 0; | ||||
5892 | while (CurDigit < Digits.size()) { | ||||
5893 | unsigned Digit; | ||||
5894 | if (Str.consumeInteger(10, Digit)) | ||||
5895 | return false; | ||||
5896 | Digits[CurDigit] = Digit; | ||||
5897 | if (Str.empty()) | ||||
5898 | return true; | ||||
5899 | if (Str[0] != '.') | ||||
5900 | return false; | ||||
5901 | Str = Str.drop_front(1); | ||||
5902 | CurDigit++; | ||||
5903 | } | ||||
5904 | |||||
5905 | // More digits than requested, bail out... | ||||
5906 | return false; | ||||
5907 | } | ||||
5908 | |||||
5909 | std::pair<unsigned, unsigned> | ||||
5910 | Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const { | ||||
5911 | unsigned IncludedFlagsBitmask = 0; | ||||
5912 | unsigned ExcludedFlagsBitmask = options::NoDriverOption; | ||||
5913 | |||||
5914 | if (IsClCompatMode) { | ||||
5915 | // Include CL and Core options. | ||||
5916 | IncludedFlagsBitmask |= options::CLOption; | ||||
5917 | IncludedFlagsBitmask |= options::CoreOption; | ||||
5918 | } else { | ||||
5919 | ExcludedFlagsBitmask |= options::CLOption; | ||||
5920 | } | ||||
5921 | if (IsDXCMode()) { | ||||
5922 | // Include DXC and Core options. | ||||
5923 | IncludedFlagsBitmask |= options::DXCOption; | ||||
5924 | IncludedFlagsBitmask |= options::CoreOption; | ||||
5925 | } else { | ||||
5926 | ExcludedFlagsBitmask |= options::DXCOption; | ||||
5927 | } | ||||
5928 | return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask); | ||||
5929 | } | ||||
5930 | |||||
5931 | bool clang::driver::isOptimizationLevelFast(const ArgList &Args) { | ||||
5932 | return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group, false); | ||||
5933 | } | ||||
5934 | |||||
5935 | bool clang::driver::willEmitRemarks(const ArgList &Args) { | ||||
5936 | // -fsave-optimization-record enables it. | ||||
5937 | if (Args.hasFlag(options::OPT_fsave_optimization_record, | ||||
5938 | options::OPT_fno_save_optimization_record, false)) | ||||
5939 | return true; | ||||
5940 | |||||
5941 | // -fsave-optimization-record=<format> enables it as well. | ||||
5942 | if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ, | ||||
5943 | options::OPT_fno_save_optimization_record, false)) | ||||
5944 | return true; | ||||
5945 | |||||
5946 | // -foptimization-record-file alone enables it too. | ||||
5947 | if (Args.hasFlag(options::OPT_foptimization_record_file_EQ, | ||||
5948 | options::OPT_fno_save_optimization_record, false)) | ||||
5949 | return true; | ||||
5950 | |||||
5951 | // -foptimization-record-passes alone enables it too. | ||||
5952 | if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ, | ||||
5953 | options::OPT_fno_save_optimization_record, false)) | ||||
5954 | return true; | ||||
5955 | return false; | ||||
5956 | } | ||||
5957 | |||||
5958 | llvm::StringRef clang::driver::getDriverMode(StringRef ProgName, | ||||
5959 | ArrayRef<const char *> Args) { | ||||
5960 | static const std::string OptName = | ||||
5961 | getDriverOptTable().getOption(options::OPT_driver_mode).getPrefixedName(); | ||||
5962 | llvm::StringRef Opt; | ||||
5963 | for (StringRef Arg : Args) { | ||||
5964 | if (!Arg.startswith(OptName)) | ||||
5965 | continue; | ||||
5966 | Opt = Arg; | ||||
5967 | } | ||||
5968 | if (Opt.empty()) | ||||
5969 | Opt = ToolChain::getTargetAndModeFromProgramName(ProgName).DriverMode; | ||||
5970 | return Opt.consume_front(OptName) ? Opt : ""; | ||||
5971 | } | ||||
5972 | |||||
5973 | bool driver::IsClangCL(StringRef DriverMode) { return DriverMode.equals("cl"); } |
1 | //===- Twine.h - Fast Temporary String Concatenation ------------*- C++ -*-===// | |||
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 | #ifndef LLVM_ADT_TWINE_H | |||
10 | #define LLVM_ADT_TWINE_H | |||
11 | ||||
12 | #include "llvm/ADT/SmallVector.h" | |||
13 | #include "llvm/ADT/StringRef.h" | |||
14 | #include "llvm/Support/ErrorHandling.h" | |||
15 | #include <cassert> | |||
16 | #include <cstdint> | |||
17 | #include <string> | |||
18 | #if __cplusplus201402L > 201402L | |||
19 | #include <string_view> | |||
20 | #endif | |||
21 | ||||
22 | namespace llvm { | |||
23 | ||||
24 | class formatv_object_base; | |||
25 | class raw_ostream; | |||
26 | ||||
27 | /// Twine - A lightweight data structure for efficiently representing the | |||
28 | /// concatenation of temporary values as strings. | |||
29 | /// | |||
30 | /// A Twine is a kind of rope, it represents a concatenated string using a | |||
31 | /// binary-tree, where the string is the preorder of the nodes. Since the | |||
32 | /// Twine can be efficiently rendered into a buffer when its result is used, | |||
33 | /// it avoids the cost of generating temporary values for intermediate string | |||
34 | /// results -- particularly in cases when the Twine result is never | |||
35 | /// required. By explicitly tracking the type of leaf nodes, we can also avoid | |||
36 | /// the creation of temporary strings for conversions operations (such as | |||
37 | /// appending an integer to a string). | |||
38 | /// | |||
39 | /// A Twine is not intended for use directly and should not be stored, its | |||
40 | /// implementation relies on the ability to store pointers to temporary stack | |||
41 | /// objects which may be deallocated at the end of a statement. Twines should | |||
42 | /// only be used accepted as const references in arguments, when an API wishes | |||
43 | /// to accept possibly-concatenated strings. | |||
44 | /// | |||
45 | /// Twines support a special 'null' value, which always concatenates to form | |||
46 | /// itself, and renders as an empty string. This can be returned from APIs to | |||
47 | /// effectively nullify any concatenations performed on the result. | |||
48 | /// | |||
49 | /// \b Implementation | |||
50 | /// | |||
51 | /// Given the nature of a Twine, it is not possible for the Twine's | |||
52 | /// concatenation method to construct interior nodes; the result must be | |||
53 | /// represented inside the returned value. For this reason a Twine object | |||
54 | /// actually holds two values, the left- and right-hand sides of a | |||
55 | /// concatenation. We also have nullary Twine objects, which are effectively | |||
56 | /// sentinel values that represent empty strings. | |||
57 | /// | |||
58 | /// Thus, a Twine can effectively have zero, one, or two children. The \see | |||
59 | /// isNullary(), \see isUnary(), and \see isBinary() predicates exist for | |||
60 | /// testing the number of children. | |||
61 | /// | |||
62 | /// We maintain a number of invariants on Twine objects (FIXME: Why): | |||
63 | /// - Nullary twines are always represented with their Kind on the left-hand | |||
64 | /// side, and the Empty kind on the right-hand side. | |||
65 | /// - Unary twines are always represented with the value on the left-hand | |||
66 | /// side, and the Empty kind on the right-hand side. | |||
67 | /// - If a Twine has another Twine as a child, that child should always be | |||
68 | /// binary (otherwise it could have been folded into the parent). | |||
69 | /// | |||
70 | /// These invariants are check by \see isValid(). | |||
71 | /// | |||
72 | /// \b Efficiency Considerations | |||
73 | /// | |||
74 | /// The Twine is designed to yield efficient and small code for common | |||
75 | /// situations. For this reason, the concat() method is inlined so that | |||
76 | /// concatenations of leaf nodes can be optimized into stores directly into a | |||
77 | /// single stack allocated object. | |||
78 | /// | |||
79 | /// In practice, not all compilers can be trusted to optimize concat() fully, | |||
80 | /// so we provide two additional methods (and accompanying operator+ | |||
81 | /// overloads) to guarantee that particularly important cases (cstring plus | |||
82 | /// StringRef) codegen as desired. | |||
83 | class Twine { | |||
84 | /// NodeKind - Represent the type of an argument. | |||
85 | enum NodeKind : unsigned char { | |||
86 | /// An empty string; the result of concatenating anything with it is also | |||
87 | /// empty. | |||
88 | NullKind, | |||
89 | ||||
90 | /// The empty string. | |||
91 | EmptyKind, | |||
92 | ||||
93 | /// A pointer to a Twine instance. | |||
94 | TwineKind, | |||
95 | ||||
96 | /// A pointer to a C string instance. | |||
97 | CStringKind, | |||
98 | ||||
99 | /// A pointer to an std::string instance. | |||
100 | StdStringKind, | |||
101 | ||||
102 | /// A Pointer and Length representation. Used for std::string_view, | |||
103 | /// StringRef, and SmallString. Can't use a StringRef here | |||
104 | /// because they are not trivally constructible. | |||
105 | PtrAndLengthKind, | |||
106 | ||||
107 | /// A pointer to a formatv_object_base instance. | |||
108 | FormatvObjectKind, | |||
109 | ||||
110 | /// A char value, to render as a character. | |||
111 | CharKind, | |||
112 | ||||
113 | /// An unsigned int value, to render as an unsigned decimal integer. | |||
114 | DecUIKind, | |||
115 | ||||
116 | /// An int value, to render as a signed decimal integer. | |||
117 | DecIKind, | |||
118 | ||||
119 | /// A pointer to an unsigned long value, to render as an unsigned decimal | |||
120 | /// integer. | |||
121 | DecULKind, | |||
122 | ||||
123 | /// A pointer to a long value, to render as a signed decimal integer. | |||
124 | DecLKind, | |||
125 | ||||
126 | /// A pointer to an unsigned long long value, to render as an unsigned | |||
127 | /// decimal integer. | |||
128 | DecULLKind, | |||
129 | ||||
130 | /// A pointer to a long long value, to render as a signed decimal integer. | |||
131 | DecLLKind, | |||
132 | ||||
133 | /// A pointer to a uint64_t value, to render as an unsigned hexadecimal | |||
134 | /// integer. | |||
135 | UHexKind | |||
136 | }; | |||
137 | ||||
138 | union Child | |||
139 | { | |||
140 | const Twine *twine; | |||
141 | const char *cString; | |||
142 | const std::string *stdString; | |||
143 | struct { | |||
144 | const char *ptr; | |||
145 | size_t length; | |||
146 | } ptrAndLength; | |||
147 | const formatv_object_base *formatvObject; | |||
148 | char character; | |||
149 | unsigned int decUI; | |||
150 | int decI; | |||
151 | const unsigned long *decUL; | |||
152 | const long *decL; | |||
153 | const unsigned long long *decULL; | |||
154 | const long long *decLL; | |||
155 | const uint64_t *uHex; | |||
156 | }; | |||
157 | ||||
158 | /// LHS - The prefix in the concatenation, which may be uninitialized for | |||
159 | /// Null or Empty kinds. | |||
160 | Child LHS; | |||
161 | ||||
162 | /// RHS - The suffix in the concatenation, which may be uninitialized for | |||
163 | /// Null or Empty kinds. | |||
164 | Child RHS; | |||
165 | ||||
166 | /// LHSKind - The NodeKind of the left hand side, \see getLHSKind(). | |||
167 | NodeKind LHSKind = EmptyKind; | |||
168 | ||||
169 | /// RHSKind - The NodeKind of the right hand side, \see getRHSKind(). | |||
170 | NodeKind RHSKind = EmptyKind; | |||
171 | ||||
172 | /// Construct a nullary twine; the kind must be NullKind or EmptyKind. | |||
173 | explicit Twine(NodeKind Kind) : LHSKind(Kind) { | |||
174 | assert(isNullary() && "Invalid kind!")(static_cast <bool> (isNullary() && "Invalid kind!" ) ? void (0) : __assert_fail ("isNullary() && \"Invalid kind!\"" , "llvm/include/llvm/ADT/Twine.h", 174, __extension__ __PRETTY_FUNCTION__ )); | |||
175 | } | |||
176 | ||||
177 | /// Construct a binary twine. | |||
178 | explicit Twine(const Twine &LHS, const Twine &RHS) | |||
179 | : LHSKind(TwineKind), RHSKind(TwineKind) { | |||
180 | this->LHS.twine = &LHS; | |||
181 | this->RHS.twine = &RHS; | |||
182 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 182, __extension__ __PRETTY_FUNCTION__ )); | |||
183 | } | |||
184 | ||||
185 | /// Construct a twine from explicit values. | |||
186 | explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind) | |||
187 | : LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) { | |||
188 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 188, __extension__ __PRETTY_FUNCTION__ )); | |||
189 | } | |||
190 | ||||
191 | /// Check for the null twine. | |||
192 | bool isNull() const { | |||
193 | return getLHSKind() == NullKind; | |||
194 | } | |||
195 | ||||
196 | /// Check for the empty twine. | |||
197 | bool isEmpty() const { | |||
198 | return getLHSKind() == EmptyKind; | |||
199 | } | |||
200 | ||||
201 | /// Check if this is a nullary twine (null or empty). | |||
202 | bool isNullary() const { | |||
203 | return isNull() || isEmpty(); | |||
204 | } | |||
205 | ||||
206 | /// Check if this is a unary twine. | |||
207 | bool isUnary() const { | |||
208 | return getRHSKind() == EmptyKind && !isNullary(); | |||
209 | } | |||
210 | ||||
211 | /// Check if this is a binary twine. | |||
212 | bool isBinary() const { | |||
213 | return getLHSKind() != NullKind && getRHSKind() != EmptyKind; | |||
214 | } | |||
215 | ||||
216 | /// Check if this is a valid twine (satisfying the invariants on | |||
217 | /// order and number of arguments). | |||
218 | bool isValid() const { | |||
219 | // Nullary twines always have Empty on the RHS. | |||
220 | if (isNullary() && getRHSKind() != EmptyKind) | |||
221 | return false; | |||
222 | ||||
223 | // Null should never appear on the RHS. | |||
224 | if (getRHSKind() == NullKind) | |||
225 | return false; | |||
226 | ||||
227 | // The RHS cannot be non-empty if the LHS is empty. | |||
228 | if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind) | |||
229 | return false; | |||
230 | ||||
231 | // A twine child should always be binary. | |||
232 | if (getLHSKind() == TwineKind && | |||
233 | !LHS.twine->isBinary()) | |||
234 | return false; | |||
235 | if (getRHSKind() == TwineKind && | |||
236 | !RHS.twine->isBinary()) | |||
237 | return false; | |||
238 | ||||
239 | return true; | |||
240 | } | |||
241 | ||||
242 | /// Get the NodeKind of the left-hand side. | |||
243 | NodeKind getLHSKind() const { return LHSKind; } | |||
244 | ||||
245 | /// Get the NodeKind of the right-hand side. | |||
246 | NodeKind getRHSKind() const { return RHSKind; } | |||
247 | ||||
248 | /// Print one child from a twine. | |||
249 | void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const; | |||
250 | ||||
251 | /// Print the representation of one child from a twine. | |||
252 | void printOneChildRepr(raw_ostream &OS, Child Ptr, | |||
253 | NodeKind Kind) const; | |||
254 | ||||
255 | public: | |||
256 | /// @name Constructors | |||
257 | /// @{ | |||
258 | ||||
259 | /// Construct from an empty string. | |||
260 | /*implicit*/ Twine() { | |||
261 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 261, __extension__ __PRETTY_FUNCTION__ )); | |||
262 | } | |||
263 | ||||
264 | Twine(const Twine &) = default; | |||
265 | ||||
266 | /// Construct from a C string. | |||
267 | /// | |||
268 | /// We take care here to optimize "" into the empty twine -- this will be | |||
269 | /// optimized out for string constants. This allows Twine arguments have | |||
270 | /// default "" values, without introducing unnecessary string constants. | |||
271 | /*implicit*/ Twine(const char *Str) { | |||
272 | if (Str[0] != '\0') { | |||
| ||||
273 | LHS.cString = Str; | |||
274 | LHSKind = CStringKind; | |||
275 | } else | |||
276 | LHSKind = EmptyKind; | |||
277 | ||||
278 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 278, __extension__ __PRETTY_FUNCTION__ )); | |||
279 | } | |||
280 | /// Delete the implicit conversion from nullptr as Twine(const char *) | |||
281 | /// cannot take nullptr. | |||
282 | /*implicit*/ Twine(std::nullptr_t) = delete; | |||
283 | ||||
284 | /// Construct from an std::string. | |||
285 | /*implicit*/ Twine(const std::string &Str) : LHSKind(StdStringKind) { | |||
286 | LHS.stdString = &Str; | |||
287 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 287, __extension__ __PRETTY_FUNCTION__ )); | |||
288 | } | |||
289 | ||||
290 | #if __cplusplus201402L > 201402L | |||
291 | /// Construct from an std::string_view by converting it to a pointer and | |||
292 | /// length. This handles string_views on a pure API basis, and avoids | |||
293 | /// storing one (or a pointer to one) inside a Twine, which avoids problems | |||
294 | /// when mixing code compiled under various C++ standards. | |||
295 | /*implicit*/ Twine(const std::string_view &Str) | |||
296 | : LHSKind(PtrAndLengthKind) { | |||
297 | LHS.ptrAndLength.ptr = Str.data(); | |||
298 | LHS.ptrAndLength.length = Str.length(); | |||
299 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 299, __extension__ __PRETTY_FUNCTION__ )); | |||
300 | } | |||
301 | #endif | |||
302 | ||||
303 | /// Construct from a StringRef. | |||
304 | /*implicit*/ Twine(const StringRef &Str) : LHSKind(PtrAndLengthKind) { | |||
305 | LHS.ptrAndLength.ptr = Str.data(); | |||
306 | LHS.ptrAndLength.length = Str.size(); | |||
307 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 307, __extension__ __PRETTY_FUNCTION__ )); | |||
308 | } | |||
309 | ||||
310 | /// Construct from a SmallString. | |||
311 | /*implicit*/ Twine(const SmallVectorImpl<char> &Str) | |||
312 | : LHSKind(PtrAndLengthKind) { | |||
313 | LHS.ptrAndLength.ptr = Str.data(); | |||
314 | LHS.ptrAndLength.length = Str.size(); | |||
315 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 315, __extension__ __PRETTY_FUNCTION__ )); | |||
316 | } | |||
317 | ||||
318 | /// Construct from a formatv_object_base. | |||
319 | /*implicit*/ Twine(const formatv_object_base &Fmt) | |||
320 | : LHSKind(FormatvObjectKind) { | |||
321 | LHS.formatvObject = &Fmt; | |||
322 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 322, __extension__ __PRETTY_FUNCTION__ )); | |||
323 | } | |||
324 | ||||
325 | /// Construct from a char. | |||
326 | explicit Twine(char Val) : LHSKind(CharKind) { | |||
327 | LHS.character = Val; | |||
328 | } | |||
329 | ||||
330 | /// Construct from a signed char. | |||
331 | explicit Twine(signed char Val) : LHSKind(CharKind) { | |||
332 | LHS.character = static_cast<char>(Val); | |||
333 | } | |||
334 | ||||
335 | /// Construct from an unsigned char. | |||
336 | explicit Twine(unsigned char Val) : LHSKind(CharKind) { | |||
337 | LHS.character = static_cast<char>(Val); | |||
338 | } | |||
339 | ||||
340 | /// Construct a twine to print \p Val as an unsigned decimal integer. | |||
341 | explicit Twine(unsigned Val) : LHSKind(DecUIKind) { | |||
342 | LHS.decUI = Val; | |||
343 | } | |||
344 | ||||
345 | /// Construct a twine to print \p Val as a signed decimal integer. | |||
346 | explicit Twine(int Val) : LHSKind(DecIKind) { | |||
347 | LHS.decI = Val; | |||
348 | } | |||
349 | ||||
350 | /// Construct a twine to print \p Val as an unsigned decimal integer. | |||
351 | explicit Twine(const unsigned long &Val) : LHSKind(DecULKind) { | |||
352 | LHS.decUL = &Val; | |||
353 | } | |||
354 | ||||
355 | /// Construct a twine to print \p Val as a signed decimal integer. | |||
356 | explicit Twine(const long &Val) : LHSKind(DecLKind) { | |||
357 | LHS.decL = &Val; | |||
358 | } | |||
359 | ||||
360 | /// Construct a twine to print \p Val as an unsigned decimal integer. | |||
361 | explicit Twine(const unsigned long long &Val) : LHSKind(DecULLKind) { | |||
362 | LHS.decULL = &Val; | |||
363 | } | |||
364 | ||||
365 | /// Construct a twine to print \p Val as a signed decimal integer. | |||
366 | explicit Twine(const long long &Val) : LHSKind(DecLLKind) { | |||
367 | LHS.decLL = &Val; | |||
368 | } | |||
369 | ||||
370 | // FIXME: Unfortunately, to make sure this is as efficient as possible we | |||
371 | // need extra binary constructors from particular types. We can't rely on | |||
372 | // the compiler to be smart enough to fold operator+()/concat() down to the | |||
373 | // right thing. Yet. | |||
374 | ||||
375 | /// Construct as the concatenation of a C string and a StringRef. | |||
376 | /*implicit*/ Twine(const char *LHS, const StringRef &RHS) | |||
377 | : LHSKind(CStringKind), RHSKind(PtrAndLengthKind) { | |||
378 | this->LHS.cString = LHS; | |||
379 | this->RHS.ptrAndLength.ptr = RHS.data(); | |||
380 | this->RHS.ptrAndLength.length = RHS.size(); | |||
381 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 381, __extension__ __PRETTY_FUNCTION__ )); | |||
382 | } | |||
383 | ||||
384 | /// Construct as the concatenation of a StringRef and a C string. | |||
385 | /*implicit*/ Twine(const StringRef &LHS, const char *RHS) | |||
386 | : LHSKind(PtrAndLengthKind), RHSKind(CStringKind) { | |||
387 | this->LHS.ptrAndLength.ptr = LHS.data(); | |||
388 | this->LHS.ptrAndLength.length = LHS.size(); | |||
389 | this->RHS.cString = RHS; | |||
390 | assert(isValid() && "Invalid twine!")(static_cast <bool> (isValid() && "Invalid twine!" ) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\"" , "llvm/include/llvm/ADT/Twine.h", 390, __extension__ __PRETTY_FUNCTION__ )); | |||
391 | } | |||
392 | ||||
393 | /// Since the intended use of twines is as temporary objects, assignments | |||
394 | /// when concatenating might cause undefined behavior or stack corruptions | |||
395 | Twine &operator=(const Twine &) = delete; | |||
396 | ||||
397 | /// Create a 'null' string, which is an empty string that always | |||
398 | /// concatenates to form another empty string. | |||
399 | static Twine createNull() { | |||
400 | return Twine(NullKind); | |||
401 | } | |||
402 | ||||
403 | /// @} | |||
404 | /// @name Numeric Conversions | |||
405 | /// @{ | |||
406 | ||||
407 | // Construct a twine to print \p Val as an unsigned hexadecimal integer. | |||
408 | static Twine utohexstr(const uint64_t &Val) { | |||
409 | Child LHS, RHS; | |||
410 | LHS.uHex = &Val; | |||
411 | RHS.twine = nullptr; | |||
412 | return Twine(LHS, UHexKind, RHS, EmptyKind); | |||
413 | } | |||
414 | ||||
415 | /// @} | |||
416 | /// @name Predicate Operations | |||
417 | /// @{ | |||
418 | ||||
419 | /// Check if this twine is trivially empty; a false return value does not | |||
420 | /// necessarily mean the twine is empty. | |||
421 | bool isTriviallyEmpty() const { | |||
422 | return isNullary(); | |||
423 | } | |||
424 | ||||
425 | /// Return true if this twine can be dynamically accessed as a single | |||
426 | /// StringRef value with getSingleStringRef(). | |||
427 | bool isSingleStringRef() const { | |||
428 | if (getRHSKind() != EmptyKind) return false; | |||
429 | ||||
430 | switch (getLHSKind()) { | |||
431 | case EmptyKind: | |||
432 | case CStringKind: | |||
433 | case StdStringKind: | |||
434 | case PtrAndLengthKind: | |||
435 | return true; | |||
436 | default: | |||
437 | return false; | |||
438 | } | |||
439 | } | |||
440 | ||||
441 | /// @} | |||
442 | /// @name String Operations | |||
443 | /// @{ | |||
444 | ||||
445 | Twine concat(const Twine &Suffix) const; | |||
446 | ||||
447 | /// @} | |||
448 | /// @name Output & Conversion. | |||
449 | /// @{ | |||
450 | ||||
451 | /// Return the twine contents as a std::string. | |||
452 | std::string str() const; | |||
453 | ||||
454 | /// Append the concatenated string into the given SmallString or SmallVector. | |||
455 | void toVector(SmallVectorImpl<char> &Out) const; | |||
456 | ||||
457 | /// This returns the twine as a single StringRef. This method is only valid | |||
458 | /// if isSingleStringRef() is true. | |||
459 | StringRef getSingleStringRef() const { | |||
460 | assert(isSingleStringRef() &&"This cannot be had as a single stringref!")(static_cast <bool> (isSingleStringRef() &&"This cannot be had as a single stringref!" ) ? void (0) : __assert_fail ("isSingleStringRef() &&\"This cannot be had as a single stringref!\"" , "llvm/include/llvm/ADT/Twine.h", 460, __extension__ __PRETTY_FUNCTION__ )); | |||
461 | switch (getLHSKind()) { | |||
462 | default: llvm_unreachable("Out of sync with isSingleStringRef")::llvm::llvm_unreachable_internal("Out of sync with isSingleStringRef" , "llvm/include/llvm/ADT/Twine.h", 462); | |||
463 | case EmptyKind: | |||
464 | return StringRef(); | |||
465 | case CStringKind: | |||
466 | return StringRef(LHS.cString); | |||
467 | case StdStringKind: | |||
468 | return StringRef(*LHS.stdString); | |||
469 | case PtrAndLengthKind: | |||
470 | return StringRef(LHS.ptrAndLength.ptr, LHS.ptrAndLength.length); | |||
471 | } | |||
472 | } | |||
473 | ||||
474 | /// This returns the twine as a single StringRef if it can be | |||
475 | /// represented as such. Otherwise the twine is written into the given | |||
476 | /// SmallVector and a StringRef to the SmallVector's data is returned. | |||
477 | StringRef toStringRef(SmallVectorImpl<char> &Out) const { | |||
478 | if (isSingleStringRef()) | |||
479 | return getSingleStringRef(); | |||
480 | toVector(Out); | |||
481 | return StringRef(Out.data(), Out.size()); | |||
482 | } | |||
483 | ||||
484 | /// This returns the twine as a single null terminated StringRef if it | |||
485 | /// can be represented as such. Otherwise the twine is written into the | |||
486 | /// given SmallVector and a StringRef to the SmallVector's data is returned. | |||
487 | /// | |||
488 | /// The returned StringRef's size does not include the null terminator. | |||
489 | StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const; | |||
490 | ||||
491 | /// Write the concatenated string represented by this twine to the | |||
492 | /// stream \p OS. | |||
493 | void print(raw_ostream &OS) const; | |||
494 | ||||
495 | /// Dump the concatenated string represented by this twine to stderr. | |||
496 | void dump() const; | |||
497 | ||||
498 | /// Write the representation of this twine to the stream \p OS. | |||
499 | void printRepr(raw_ostream &OS) const; | |||
500 | ||||
501 | /// Dump the representation of this twine to stderr. | |||
502 | void dumpRepr() const; | |||
503 | ||||
504 | /// @} | |||
505 | }; | |||
506 | ||||
507 | /// @name Twine Inline Implementations | |||
508 | /// @{ | |||
509 | ||||
510 | inline Twine Twine::concat(const Twine &Suffix) const { | |||
511 | // Concatenation with null is null. | |||
512 | if (isNull() || Suffix.isNull()) | |||
513 | return Twine(NullKind); | |||
514 | ||||
515 | // Concatenation with empty yields the other side. | |||
516 | if (isEmpty()) | |||
517 | return Suffix; | |||
518 | if (Suffix.isEmpty()) | |||
519 | return *this; | |||
520 | ||||
521 | // Otherwise we need to create a new node, taking care to fold in unary | |||
522 | // twines. | |||
523 | Child NewLHS, NewRHS; | |||
524 | NewLHS.twine = this; | |||
525 | NewRHS.twine = &Suffix; | |||
526 | NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind; | |||
527 | if (isUnary()) { | |||
528 | NewLHS = LHS; | |||
529 | NewLHSKind = getLHSKind(); | |||
530 | } | |||
531 | if (Suffix.isUnary()) { | |||
532 | NewRHS = Suffix.LHS; | |||
533 | NewRHSKind = Suffix.getLHSKind(); | |||
534 | } | |||
535 | ||||
536 | return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind); | |||
537 | } | |||
538 | ||||
539 | inline Twine operator+(const Twine &LHS, const Twine &RHS) { | |||
540 | return LHS.concat(RHS); | |||
541 | } | |||
542 | ||||
543 | /// Additional overload to guarantee simplified codegen; this is equivalent to | |||
544 | /// concat(). | |||
545 | ||||
546 | inline Twine operator+(const char *LHS, const StringRef &RHS) { | |||
547 | return Twine(LHS, RHS); | |||
548 | } | |||
549 | ||||
550 | /// Additional overload to guarantee simplified codegen; this is equivalent to | |||
551 | /// concat(). | |||
552 | ||||
553 | inline Twine operator+(const StringRef &LHS, const char *RHS) { | |||
554 | return Twine(LHS, RHS); | |||
555 | } | |||
556 | ||||
557 | inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) { | |||
558 | RHS.print(OS); | |||
559 | return OS; | |||
560 | } | |||
561 | ||||
562 | /// @} | |||
563 | ||||
564 | } // end namespace llvm | |||
565 | ||||
566 | #endif // LLVM_ADT_TWINE_H |