clang  19.0.0git
Driver.cpp
Go to the documentation of this file.
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 #include "clang/Driver/Driver.h"
9 #include "ToolChains/AIX.h"
10 #include "ToolChains/AMDGPU.h"
12 #include "ToolChains/AVR.h"
13 #include "ToolChains/Arch/RISCV.h"
14 #include "ToolChains/BareMetal.h"
16 #include "ToolChains/Clang.h"
18 #include "ToolChains/Cuda.h"
19 #include "ToolChains/Darwin.h"
20 #include "ToolChains/DragonFly.h"
21 #include "ToolChains/FreeBSD.h"
22 #include "ToolChains/Fuchsia.h"
23 #include "ToolChains/Gnu.h"
24 #include "ToolChains/HIPAMD.h"
25 #include "ToolChains/HIPSPV.h"
26 #include "ToolChains/HLSL.h"
27 #include "ToolChains/Haiku.h"
28 #include "ToolChains/Hexagon.h"
29 #include "ToolChains/Hurd.h"
30 #include "ToolChains/Lanai.h"
31 #include "ToolChains/Linux.h"
32 #include "ToolChains/MSP430.h"
33 #include "ToolChains/MSVC.h"
34 #include "ToolChains/MinGW.h"
35 #include "ToolChains/MipsLinux.h"
36 #include "ToolChains/NaCl.h"
37 #include "ToolChains/NetBSD.h"
38 #include "ToolChains/OHOS.h"
39 #include "ToolChains/OpenBSD.h"
40 #include "ToolChains/PPCFreeBSD.h"
41 #include "ToolChains/PPCLinux.h"
42 #include "ToolChains/PS4CPU.h"
44 #include "ToolChains/SPIRV.h"
45 #include "ToolChains/SYCL.h"
46 #include "ToolChains/Solaris.h"
47 #include "ToolChains/TCE.h"
48 #include "ToolChains/VEToolchain.h"
49 #include "ToolChains/WebAssembly.h"
50 #include "ToolChains/XCore.h"
51 #include "ToolChains/ZOS.h"
53 #include "clang/Basic/TargetID.h"
54 #include "clang/Basic/Version.h"
55 #include "clang/Config/config.h"
56 #include "clang/Driver/Action.h"
59 #include "clang/Driver/InputInfo.h"
60 #include "clang/Driver/Job.h"
61 #include "clang/Driver/Options.h"
62 #include "clang/Driver/Phases.h"
64 #include "clang/Driver/Tool.h"
65 #include "clang/Driver/ToolChain.h"
66 #include "clang/Driver/Types.h"
67 #include "llvm/ADT/ArrayRef.h"
68 #include "llvm/ADT/MapVector.h"
69 #include "llvm/ADT/STLExtras.h"
70 #include "llvm/ADT/StringExtras.h"
71 #include "llvm/ADT/StringRef.h"
72 #include "llvm/ADT/StringSet.h"
73 #include "llvm/ADT/StringSwitch.h"
74 #include "llvm/BinaryFormat/Magic.h"
75 #include "llvm/Config/llvm-config.h"
76 #include "llvm/MC/TargetRegistry.h"
77 #include "llvm/Option/Arg.h"
78 #include "llvm/Option/ArgList.h"
79 #include "llvm/Option/OptSpecifier.h"
80 #include "llvm/Option/OptTable.h"
81 #include "llvm/Option/Option.h"
82 #include "llvm/SYCLLowerIR/DeviceConfigFile.hpp"
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/FileUtilities.h"
88 #include "llvm/Support/FormatVariadic.h"
89 #include "llvm/Support/LineIterator.h"
90 #include "llvm/Support/MD5.h"
91 #include "llvm/Support/Path.h"
92 #include "llvm/Support/PrettyStackTrace.h"
93 #include "llvm/Support/Process.h"
94 #include "llvm/Support/Program.h"
95 #include "llvm/Support/Regex.h"
96 #include "llvm/Support/StringSaver.h"
97 #include "llvm/Support/VirtualFileSystem.h"
98 #include "llvm/Support/raw_ostream.h"
99 #include "llvm/TargetParser/Host.h"
100 #include "llvm/TargetParser/RISCVISAInfo.h"
101 #include <cstdlib> // ::getenv
102 #include <map>
103 #include <memory>
104 #include <optional>
105 #include <regex>
106 #include <sstream>
107 #include <set>
108 #include <utility>
109 #if LLVM_ON_UNIX
110 #include <unistd.h> // getpid
111 #endif
112 
113 using namespace clang::driver;
114 using namespace clang;
115 using namespace llvm::opt;
116 
117 static std::optional<llvm::Triple> getOffloadTargetTriple(const Driver &D,
118  const ArgList &Args) {
119  auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
120  // Offload compilation flow does not support multiple targets for now. We
121  // need the HIPActionBuilder (and possibly the CudaActionBuilder{,Base}too)
122  // to support multiple tool chains first.
123  switch (OffloadTargets.size()) {
124  default:
125  D.Diag(diag::err_drv_only_one_offload_target_supported);
126  return std::nullopt;
127  case 0:
128  D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << "";
129  return std::nullopt;
130  case 1:
131  break;
132  }
133  return llvm::Triple(OffloadTargets[0]);
134 }
135 
136 static std::optional<llvm::Triple>
137 getNVIDIAOffloadTargetTriple(const Driver &D, const ArgList &Args,
138  const llvm::Triple &HostTriple) {
139  if (!Args.hasArg(options::OPT_offload_EQ)) {
140  return llvm::Triple(HostTriple.isArch64Bit() ? "nvptx64-nvidia-cuda"
141  : "nvptx-nvidia-cuda");
142  }
143  auto TT = getOffloadTargetTriple(D, Args);
144  if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
145  TT->getArch() == llvm::Triple::spirv64)) {
146  if (Args.hasArg(options::OPT_emit_llvm))
147  return TT;
148  D.Diag(diag::err_drv_cuda_offload_only_emit_bc);
149  return std::nullopt;
150  }
151  D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
152  return std::nullopt;
153 }
154 static std::optional<llvm::Triple>
155 getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) {
156  if (!Args.hasArg(options::OPT_offload_EQ)) {
157  return llvm::Triple("amdgcn-amd-amdhsa"); // Default HIP triple.
158  }
159  auto TT = getOffloadTargetTriple(D, Args);
160  if (!TT)
161  return std::nullopt;
162  if (TT->getArch() == llvm::Triple::amdgcn &&
163  TT->getVendor() == llvm::Triple::AMD &&
164  TT->getOS() == llvm::Triple::AMDHSA)
165  return TT;
166  if (TT->getArch() == llvm::Triple::spirv64)
167  return TT;
168  D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
169  return std::nullopt;
170 }
171 
172 // static
173 std::string Driver::GetResourcesPath(StringRef BinaryPath,
174  StringRef CustomResourceDir) {
175  // Since the resource directory is embedded in the module hash, it's important
176  // that all places that need it call this function, so that they get the
177  // exact same string ("a/../b/" and "b/" get different hashes, for example).
178 
179  // Dir is bin/ or lib/, depending on where BinaryPath is.
180  std::string Dir = std::string(llvm::sys::path::parent_path(BinaryPath));
181 
182  SmallString<128> P(Dir);
183  if (CustomResourceDir != "") {
184  llvm::sys::path::append(P, CustomResourceDir);
185  } else {
186  // On Windows, libclang.dll is in bin/.
187  // On non-Windows, libclang.so/.dylib is in lib/.
188  // With a static-library build of libclang, LibClangPath will contain the
189  // path of the embedding binary, which for LLVM binaries will be in bin/.
190  // ../lib gets us to lib/ in both cases.
191  P = llvm::sys::path::parent_path(Dir);
192  // This search path is also created in the COFF driver of lld, so any
193  // changes here also needs to happen in lld/COFF/Driver.cpp
194  llvm::sys::path::append(P, CLANG_INSTALL_LIBDIR_BASENAME, "clang",
195  CLANG_VERSION_MAJOR_STRING);
196  }
197 
198  return std::string(P);
199 }
200 
201 Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
202  DiagnosticsEngine &Diags, std::string Title,
204  : Diags(Diags), VFS(std::move(VFS)), DumpDeviceCode(false), Mode(GCCMode),
205  SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
206  Offload(OffloadHostDevice), CXX20HeaderType(HeaderMode_None),
207  ModulesModeCXX20(false), LTOMode(LTOK_None), OffloadLTOMode(LTOK_None),
208  ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
209  DriverTitle(Title), CCCPrintBindings(false), CCPrintOptions(false),
210  CCLogDiagnostics(false), CCGenDiagnostics(false),
211  CCPrintProcessStats(false), CCPrintInternalStats(false),
212  TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
213  CheckInputsExist(true), ProbePrecompiled(true),
214  SuppressMissingInputWarning(false) {
215  // Provide a sane fallback if no VFS is specified.
216  if (!this->VFS)
217  this->VFS = llvm::vfs::getRealFileSystem();
218 
219  Name = std::string(llvm::sys::path::filename(ClangExecutable));
220  Dir = std::string(llvm::sys::path::parent_path(ClangExecutable));
221 
222  if ((!SysRoot.empty()) && llvm::sys::path::is_relative(SysRoot)) {
223  // Prepend InstalledDir if SysRoot is relative
225  llvm::sys::path::append(P, SysRoot);
226  SysRoot = std::string(P);
227  }
228 
229 #if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
230  SystemConfigDir = CLANG_CONFIG_FILE_SYSTEM_DIR;
231 #endif
232 #if defined(CLANG_CONFIG_FILE_USER_DIR)
233  {
235  llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
236  UserConfigDir = static_cast<std::string>(P);
237  }
238 #endif
239 }
240 
241 void Driver::setDriverMode(StringRef Value) {
242  static StringRef OptName =
243  getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
244  if (auto M = llvm::StringSwitch<std::optional<DriverMode>>(Value)
245  .Case("gcc", GCCMode)
246  .Case("g++", GXXMode)
247  .Case("cpp", CPPMode)
248  .Case("cl", CLMode)
249  .Case("flang", FlangMode)
250  .Case("dxc", DXCMode)
251  .Default(std::nullopt))
252  Mode = *M;
253  else
254  Diag(diag::err_drv_unsupported_option_argument) << OptName << Value;
255 }
256 
257 void Driver::setResourceDirectory() {
258  // Compute the path to the resource directory, depending on the driver mode.
259  switch (Mode) {
260  case GCCMode:
261  case GXXMode:
262  case CPPMode:
263  case CLMode:
264  case DXCMode:
265  ResourceDir = GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR);
266  break;
267  case FlangMode:
268  SmallString<64> customResourcePathRelativeToDriver{".."};
269  ResourceDir =
270  GetResourcesPath(ClangExecutable, customResourcePathRelativeToDriver);
271  break;
272  }
273 }
274 
276  bool UseDriverMode, bool &ContainsError) {
277  llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
278  ContainsError = false;
279 
280  llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
281  unsigned MissingArgIndex, MissingArgCount;
282  InputArgList Args = getOpts().ParseArgs(ArgStrings, MissingArgIndex,
283  MissingArgCount, VisibilityMask);
284 
285  // Check for missing argument error.
286  if (MissingArgCount) {
287  Diag(diag::err_drv_missing_argument)
288  << Args.getArgString(MissingArgIndex) << MissingArgCount;
289  ContainsError |=
290  Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
292  }
293 
294  // Check for unsupported options.
295  for (const Arg *A : Args) {
296  if (A->getOption().hasFlag(options::Unsupported)) {
297  Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
298  ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
299  SourceLocation()) >
301  continue;
302  }
303 
304  // Deprecated options emit a diagnostic about deprecation, but are still
305  // supported until removed. It's possible to have a deprecated option which
306  // aliases with a non-deprecated option, so always compute the argument
307  // actually used before checking for deprecation.
308  const Arg *Used = A;
309  while (Used->getAlias())
310  Used = Used->getAlias();
311  if (Used->getOption().hasFlag(options::Deprecated)) {
312  Diag(diag::warn_drv_deprecated_option_release) << Used->getAsString(Args);
313  ContainsError |= Diags.getDiagnosticLevel(
314  diag::warn_drv_deprecated_option_release,
316  }
317 
318  // Warn about -mcpu= without an argument.
319  if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue("")) {
320  Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
321  ContainsError |= Diags.getDiagnosticLevel(
322  diag::warn_drv_empty_joined_argument,
324  }
325  }
326 
327  for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
328  unsigned DiagID;
329  auto ArgString = A->getAsString(Args);
330  std::string Nearest;
331  if (getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
332  if (!IsCLMode() &&
333  getOpts().findExact(ArgString, Nearest,
335  DiagID = diag::err_drv_unknown_argument_with_suggestion;
336  Diags.Report(DiagID) << ArgString << "-Xclang " + Nearest;
337  } else {
338  DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
339  : diag::err_drv_unknown_argument;
340  Diags.Report(DiagID) << ArgString;
341  }
342  } else {
343  DiagID = IsCLMode()
344  ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
345  : diag::err_drv_unknown_argument_with_suggestion;
346  Diags.Report(DiagID) << ArgString << Nearest;
347  }
348  ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) >
350  }
351 
352  for (const Arg *A : Args.filtered(options::OPT_o)) {
353  if (ArgStrings[A->getIndex()] == A->getSpelling())
354  continue;
355 
356  // Warn on joined arguments that are similar to a long argument.
357  std::string ArgString = ArgStrings[A->getIndex()];
358  std::string Nearest;
359  if (getOpts().findExact("-" + ArgString, Nearest, VisibilityMask))
360  Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
361  << A->getAsString(Args) << Nearest;
362  }
363 
364  return Args;
365 }
366 
367 // Determine which compilation mode we are in. We look for options which
368 // affect the phase, starting with the earliest phases, and record which
369 // option we used to determine the final phase.
370 phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
371  Arg **FinalPhaseArg) const {
372  Arg *PhaseArg = nullptr;
373  phases::ID FinalPhase;
374 
375  // -{E,EP,P,M,MM} only run the preprocessor.
376  if (CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
377  (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
378  (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
379  (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
381  FinalPhase = phases::Preprocess;
382 
383  // --precompile only runs up to precompilation.
384  // Options that cause the output of C++20 compiled module interfaces or
385  // header units have the same effect.
386  } else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
387  (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
388  (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
389  options::OPT_fmodule_header_EQ))) {
390  FinalPhase = phases::Precompile;
391  // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
392  } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
393  (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
394  (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
395  (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
396  (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
397  (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
398  (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
399  (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
400  (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
401  (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
402  FinalPhase = phases::Compile;
403 
404  // -S only runs up to the backend.
405  } else if ((PhaseArg = DAL.getLastArg(options::OPT_S)) ||
406  (PhaseArg = DAL.getLastArg(options::OPT_fsycl_device_only))) {
407  FinalPhase = phases::Backend;
408 
409  // -c compilation only runs up to the assembler.
410  } else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
411  FinalPhase = phases::Assemble;
412 
413  } else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
414  FinalPhase = phases::IfsMerge;
415 
416  // Otherwise do everything.
417  } else
418  FinalPhase = phases::Link;
419 
420  if (FinalPhaseArg)
421  *FinalPhaseArg = PhaseArg;
422 
423  return FinalPhase;
424 }
425 
426 static Arg *MakeInputArg(DerivedArgList &Args, const OptTable &Opts,
427  StringRef Value, bool Claim = true) {
428  Arg *A = new Arg(Opts.getOption(options::OPT_INPUT), Value,
429  Args.getBaseArgs().MakeIndex(Value), Value.data());
430  Args.AddSynthesizedArg(A);
431  if (Claim)
432  A->claim();
433  return A;
434 }
435 
436 DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
437  const llvm::opt::OptTable &Opts = getOpts();
438  DerivedArgList *DAL = new DerivedArgList(Args);
439 
440  bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
441  bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
442  bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
443  bool IgnoreUnused = false;
444  for (Arg *A : Args) {
445  if (IgnoreUnused)
446  A->claim();
447 
448  if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
449  IgnoreUnused = true;
450  continue;
451  }
452  if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
453  IgnoreUnused = false;
454  continue;
455  }
456 
457  // Unfortunately, we have to parse some forwarding options (-Xassembler,
458  // -Xlinker, -Xpreprocessor) because we either integrate their functionality
459  // (assembler and preprocessor), or bypass a previous driver ('collect2').
460 
461  // Rewrite linker options, to replace --no-demangle with a custom internal
462  // option.
463  if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
464  A->getOption().matches(options::OPT_Xlinker)) &&
465  A->containsValue("--no-demangle")) {
466  // Add the rewritten no-demangle argument.
467  DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
468 
469  // Add the remaining values as Xlinker arguments.
470  for (StringRef Val : A->getValues())
471  if (Val != "--no-demangle")
472  DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
473 
474  continue;
475  }
476 
477  // Rewrite preprocessor options, to replace -Wp,-MD,FOO which is used by
478  // some build systems. We don't try to be complete here because we don't
479  // care to encourage this usage model.
480  if (A->getOption().matches(options::OPT_Wp_COMMA) &&
481  (A->getValue(0) == StringRef("-MD") ||
482  A->getValue(0) == StringRef("-MMD"))) {
483  // Rewrite to -MD/-MMD along with -MF.
484  if (A->getValue(0) == StringRef("-MD"))
485  DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
486  else
487  DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
488  if (A->getNumValues() == 2)
489  DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
490  continue;
491  }
492 
493  // Rewrite reserved library names.
494  if (A->getOption().matches(options::OPT_l)) {
495  StringRef Value = A->getValue();
496 
497  // Rewrite unless -nostdlib is present.
498  if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
499  Value == "stdc++") {
500  DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
501  continue;
502  }
503 
504  // Rewrite unconditionally.
505  if (Value == "cc_kext") {
506  DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
507  continue;
508  }
509  }
510 
511  // Pick up inputs via the -- option.
512  if (A->getOption().matches(options::OPT__DASH_DASH)) {
513  A->claim();
514  for (StringRef Val : A->getValues())
515  DAL->append(MakeInputArg(*DAL, Opts, Val, false));
516  continue;
517  }
518 
519  if (A->getOption().matches(options::OPT_offload_lib_Group)) {
520  if (!A->getNumValues()) {
521  Diag(clang::diag::warn_drv_unused_argument) << A->getSpelling();
522  continue;
523  }
524  }
525 
526  DAL->append(A);
527  }
528 
529  // DXC mode quits before assembly if an output object file isn't specified.
530  if (IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
531  DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_S));
532 
533  // Enforce -static if -miamcu is present.
534  if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false))
535  DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_static));
536 
537  // Use of -fintelfpga implies -g and -fsycl
538  if (Args.hasArg(options::OPT_fintelfpga)) {
539  if (!Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false))
540  DAL->AddFlagArg(0, Opts.getOption(options::OPT_fsycl));
541  // if any -gN option is provided, use that.
542  if (Arg *A = Args.getLastArg(options::OPT_gN_Group))
543  DAL->append(A);
544  else
545  DAL->AddFlagArg(0, Opts.getOption(options::OPT_g_Flag));
546  }
547 
548 // Add a default value of -mlinker-version=, if one was given and the user
549 // didn't specify one.
550 #if defined(HOST_LINK_VERSION)
551  if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
552  strlen(HOST_LINK_VERSION) > 0) {
553  DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
554  HOST_LINK_VERSION);
555  DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
556  }
557 #endif
558 
559  return DAL;
560 }
561 
562 /// Compute target triple from args.
563 ///
564 /// This routine provides the logic to compute a target triple from various
565 /// args passed to the driver and the default triple string.
566 static llvm::Triple computeTargetTriple(const Driver &D,
567  StringRef TargetTriple,
568  const ArgList &Args,
569  StringRef DarwinArchName = "") {
570  // FIXME: Already done in Compilation *Driver::BuildCompilation
571  if (const Arg *A = Args.getLastArg(options::OPT_target))
572  TargetTriple = A->getValue();
573 
574  llvm::Triple Target(llvm::Triple::normalize(TargetTriple));
575 
576  // GNU/Hurd's triples should have been -hurd-gnu*, but were historically made
577  // -gnu* only, and we can not change this, so we have to detect that case as
578  // being the Hurd OS.
579  if (TargetTriple.contains("-unknown-gnu") || TargetTriple.contains("-pc-gnu"))
580  Target.setOSName("hurd");
581 
582  // Handle Apple-specific options available here.
583  if (Target.isOSBinFormatMachO()) {
584  // If an explicit Darwin arch name is given, that trumps all.
585  if (!DarwinArchName.empty()) {
587  Args);
588  return Target;
589  }
590 
591  // Handle the Darwin '-arch' flag.
592  if (Arg *A = Args.getLastArg(options::OPT_arch)) {
593  StringRef ArchName = A->getValue();
595  }
596  }
597 
598  // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
599  // '-mbig-endian'/'-EB'.
600  if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
601  options::OPT_mbig_endian)) {
602  llvm::Triple T = A->getOption().matches(options::OPT_mlittle_endian)
603  ? Target.getLittleEndianArchVariant()
604  : Target.getBigEndianArchVariant();
605  if (T.getArch() != llvm::Triple::UnknownArch) {
606  Target = std::move(T);
607  Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
608  }
609  }
610 
611  // Skip further flag support on OSes which don't support '-m32' or '-m64'.
612  if (Target.getArch() == llvm::Triple::tce)
613  return Target;
614 
615  // On AIX, the env OBJECT_MODE may affect the resulting arch variant.
616  if (Target.isOSAIX()) {
617  if (std::optional<std::string> ObjectModeValue =
618  llvm::sys::Process::GetEnv("OBJECT_MODE")) {
619  StringRef ObjectMode = *ObjectModeValue;
620  llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
621 
622  if (ObjectMode == "64") {
623  AT = Target.get64BitArchVariant().getArch();
624  } else if (ObjectMode == "32") {
625  AT = Target.get32BitArchVariant().getArch();
626  } else {
627  D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
628  }
629 
630  if (AT != llvm::Triple::UnknownArch && AT != Target.getArch())
631  Target.setArch(AT);
632  }
633  }
634 
635  // The `-maix[32|64]` flags are only valid for AIX targets.
636  if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
637  A && !Target.isOSAIX())
638  D.Diag(diag::err_drv_unsupported_opt_for_target)
639  << A->getAsString(Args) << Target.str();
640 
641  // Handle pseudo-target flags '-m64', '-mx32', '-m32' and '-m16'.
642  Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
643  options::OPT_m32, options::OPT_m16,
644  options::OPT_maix32, options::OPT_maix64);
645  if (A) {
646  llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
647 
648  if (A->getOption().matches(options::OPT_m64) ||
649  A->getOption().matches(options::OPT_maix64)) {
650  AT = Target.get64BitArchVariant().getArch();
651  if (Target.getEnvironment() == llvm::Triple::GNUX32)
652  Target.setEnvironment(llvm::Triple::GNU);
653  else if (Target.getEnvironment() == llvm::Triple::MuslX32)
654  Target.setEnvironment(llvm::Triple::Musl);
655  } else if (A->getOption().matches(options::OPT_mx32) &&
656  Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
657  AT = llvm::Triple::x86_64;
658  if (Target.getEnvironment() == llvm::Triple::Musl)
659  Target.setEnvironment(llvm::Triple::MuslX32);
660  else
661  Target.setEnvironment(llvm::Triple::GNUX32);
662  } else if (A->getOption().matches(options::OPT_m32) ||
663  A->getOption().matches(options::OPT_maix32)) {
664  AT = Target.get32BitArchVariant().getArch();
665  if (Target.getEnvironment() == llvm::Triple::GNUX32)
666  Target.setEnvironment(llvm::Triple::GNU);
667  else if (Target.getEnvironment() == llvm::Triple::MuslX32)
668  Target.setEnvironment(llvm::Triple::Musl);
669  } else if (A->getOption().matches(options::OPT_m16) &&
670  Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
671  AT = llvm::Triple::x86;
672  Target.setEnvironment(llvm::Triple::CODE16);
673  }
674 
675  if (AT != llvm::Triple::UnknownArch && AT != Target.getArch()) {
676  Target.setArch(AT);
677  if (Target.isWindowsGNUEnvironment())
679  }
680  }
681 
682  // Handle -miamcu flag.
683  if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) {
684  if (Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
685  D.Diag(diag::err_drv_unsupported_opt_for_target) << "-miamcu"
686  << Target.str();
687 
688  if (A && !A->getOption().matches(options::OPT_m32))
689  D.Diag(diag::err_drv_argument_not_allowed_with)
690  << "-miamcu" << A->getBaseArg().getAsString(Args);
691 
692  Target.setArch(llvm::Triple::x86);
693  Target.setArchName("i586");
694  Target.setEnvironment(llvm::Triple::UnknownEnvironment);
695  Target.setEnvironmentName("");
696  Target.setOS(llvm::Triple::ELFIAMCU);
697  Target.setVendor(llvm::Triple::UnknownVendor);
698  Target.setVendorName("intel");
699  }
700 
701  // If target is MIPS adjust the target triple
702  // accordingly to provided ABI name.
703  if (Target.isMIPS()) {
704  if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
705  StringRef ABIName = A->getValue();
706  if (ABIName == "32") {
707  Target = Target.get32BitArchVariant();
708  if (Target.getEnvironment() == llvm::Triple::GNUABI64 ||
709  Target.getEnvironment() == llvm::Triple::GNUABIN32)
710  Target.setEnvironment(llvm::Triple::GNU);
711  } else if (ABIName == "n32") {
712  Target = Target.get64BitArchVariant();
713  if (Target.getEnvironment() == llvm::Triple::GNU ||
714  Target.getEnvironment() == llvm::Triple::GNUABI64)
715  Target.setEnvironment(llvm::Triple::GNUABIN32);
716  } else if (ABIName == "64") {
717  Target = Target.get64BitArchVariant();
718  if (Target.getEnvironment() == llvm::Triple::GNU ||
719  Target.getEnvironment() == llvm::Triple::GNUABIN32)
720  Target.setEnvironment(llvm::Triple::GNUABI64);
721  }
722  }
723  }
724 
725  // If target is RISC-V adjust the target triple according to
726  // provided architecture name
727  if (Target.isRISCV()) {
728  if (Args.hasArg(options::OPT_march_EQ) ||
729  Args.hasArg(options::OPT_mcpu_EQ)) {
730  StringRef ArchName = tools::riscv::getRISCVArch(Args, Target);
731  auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
732  ArchName, /*EnableExperimentalExtensions=*/true);
733  if (!llvm::errorToBool(ISAInfo.takeError())) {
734  unsigned XLen = (*ISAInfo)->getXLen();
735  if (XLen == 32)
736  Target.setArch(llvm::Triple::riscv32);
737  else if (XLen == 64)
738  Target.setArch(llvm::Triple::riscv64);
739  }
740  }
741  }
742 
743  return Target;
744 }
745 
746 // Parse the LTO options and record the type of LTO compilation
747 // based on which -f(no-)?lto(=.*)? or -f(no-)?offload-lto(=.*)?
748 // option occurs last.
749 static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args,
750  OptSpecifier OptEq, OptSpecifier OptNeg) {
751  if (!Args.hasFlag(OptEq, OptNeg, false))
752  return LTOK_None;
753 
754  const Arg *A = Args.getLastArg(OptEq);
755  StringRef LTOName = A->getValue();
756 
757  driver::LTOKind LTOMode = llvm::StringSwitch<LTOKind>(LTOName)
758  .Case("full", LTOK_Full)
759  .Case("thin", LTOK_Thin)
760  .Default(LTOK_Unknown);
761 
762  if (LTOMode == LTOK_Unknown) {
763  D.Diag(diag::err_drv_unsupported_option_argument)
764  << A->getSpelling() << A->getValue();
765  return LTOK_None;
766  }
767  return LTOMode;
768 }
769 
770 // Parse the LTO options.
771 void Driver::setLTOMode(const llvm::opt::ArgList &Args) {
772  LTOMode =
773  parseLTOMode(*this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
774 
775  OffloadLTOMode = parseLTOMode(*this, Args, options::OPT_foffload_lto_EQ,
776  options::OPT_fno_offload_lto);
777 
778  // Try to enable `-foffload-lto=full` if `-fopenmp-target-jit` is on.
779  if (Args.hasFlag(options::OPT_fopenmp_target_jit,
780  options::OPT_fno_openmp_target_jit, false)) {
781  if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
782  options::OPT_fno_offload_lto))
783  if (OffloadLTOMode != LTOK_Full)
784  Diag(diag::err_drv_incompatible_options)
785  << A->getSpelling() << "-fopenmp-target-jit";
786  OffloadLTOMode = LTOK_Full;
787  }
788 }
789 
790 /// Compute the desired OpenMP runtime from the flags provided.
792  StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
793 
794  const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
795  if (A)
796  RuntimeName = A->getValue();
797 
798  auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
799  .Case("libomp", OMPRT_OMP)
800  .Case("libgomp", OMPRT_GOMP)
801  .Case("libiomp5", OMPRT_IOMP5)
802  .Default(OMPRT_Unknown);
803 
804  if (RT == OMPRT_Unknown) {
805  if (A)
806  Diag(diag::err_drv_unsupported_option_argument)
807  << A->getSpelling() << A->getValue();
808  else
809  // FIXME: We could use a nicer diagnostic here.
810  Diag(diag::err_drv_unsupported_opt) << "-fopenmp";
811  }
812 
813  return RT;
814 }
815 
816 static bool isValidSYCLTriple(llvm::Triple T) {
817  // NVPTX is valid for SYCL.
818  if (T.isNVPTX())
819  return true;
820 
821  // AMDGCN is valid for SYCL
822  if (T.isAMDGCN())
823  return true;
824 
825  // Check for invalid SYCL device triple values.
826  // Non-SPIR/SPIRV arch.
827  if (!T.isSPIROrSPIRV())
828  return false;
829  // SPIR/SPIRV arch, but has invalid SubArch for AOT.
830  StringRef A(T.getArchName());
831  if (T.getSubArch() == llvm::Triple::NoSubArch &&
832  ((T.getArch() == llvm::Triple::spir && A != "spir") ||
833  (T.getArch() == llvm::Triple::spir64 && A != "spir64")))
834  return false;
835  return true;
836 }
837 
838 static const char *getDefaultSYCLArch(Compilation &C) {
839  if (C.getDefaultToolChain().getTriple().getArch() == llvm::Triple::x86)
840  return "spir";
841  return "spir64";
842 }
843 
845  SmallVectorImpl<llvm::Triple> &SYCLTriples) {
846  /// Returns true if a triple is added to SYCLTriples, false otherwise
847  if (!C.getDriver().isSYCLDefaultTripleImplied())
848  return false;
849  if (C.getInputArgs().hasArg(options::OPT_fsycl_force_target_EQ))
850  return false;
851  for (const auto &SYCLTriple : SYCLTriples) {
852  if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
853  SYCLTriple.isSPIROrSPIRV())
854  return false;
855  // If we encounter a known non-spir* target, do not add the default triple.
856  if (SYCLTriple.isNVPTX() || SYCLTriple.isAMDGCN())
857  return false;
858  }
859  // Add the default triple as it was not found.
860  llvm::Triple DefaultTriple =
861  C.getDriver().MakeSYCLDeviceTriple(getDefaultSYCLArch(C));
862  SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple);
863  return true;
864 }
865 
867  InputList &Inputs) {
868 
869  //
870  // CUDA/HIP
871  //
872  // We need to generate a CUDA/HIP toolchain if any of the inputs has a CUDA
873  // or HIP type. However, mixed CUDA/HIP compilation is not supported.
874  using namespace tools::SYCL;
875  bool IsCuda =
876  llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
877  return types::isCuda(I.first);
878  });
879  bool IsHIP =
880  llvm::any_of(Inputs,
881  [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
882  return types::isHIP(I.first);
883  }) ||
884  C.getInputArgs().hasArg(options::OPT_hip_link) ||
885  C.getInputArgs().hasArg(options::OPT_hipstdpar);
886  if (IsCuda && IsHIP) {
887  Diag(clang::diag::err_drv_mix_cuda_hip);
888  return;
889  }
890  if (IsCuda) {
891  const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
892  const llvm::Triple &HostTriple = HostTC->getTriple();
893  auto OFK = Action::OFK_Cuda;
894  auto CudaTriple =
895  getNVIDIAOffloadTargetTriple(*this, C.getInputArgs(), HostTriple);
896  if (!CudaTriple)
897  return;
898  // Use the CUDA and host triples as the key into the ToolChains map,
899  // because the device toolchain we create depends on both.
900  auto &CudaTC = ToolChains[CudaTriple->str() + "/" + HostTriple.str()];
901  if (!CudaTC) {
902  CudaTC = std::make_unique<toolchains::CudaToolChain>(
903  *this, *CudaTriple, *HostTC, C.getInputArgs(), OFK);
904 
905  // Emit a warning if the detected CUDA version is too new.
906  CudaInstallationDetector &CudaInstallation =
907  static_cast<toolchains::CudaToolChain &>(*CudaTC).CudaInstallation;
908  if (CudaInstallation.isValid())
909  CudaInstallation.WarnIfUnsupportedVersion();
910  }
911  C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
912  } else if (IsHIP) {
913  if (auto *OMPTargetArg =
914  C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
915  Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
916  << OMPTargetArg->getSpelling() << "HIP";
917  return;
918  }
919  const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
920  auto OFK = Action::OFK_HIP;
921  auto HIPTriple = getHIPOffloadTargetTriple(*this, C.getInputArgs());
922  if (!HIPTriple)
923  return;
924  auto *HIPTC = &getOffloadingDeviceToolChain(C.getInputArgs(), *HIPTriple,
925  *HostTC, OFK);
926  assert(HIPTC && "Could not create offloading device tool chain.");
927  C.addOffloadDeviceToolChain(HIPTC, OFK);
928  }
929 
930  //
931  // OpenMP
932  //
933  // We need to generate an OpenMP toolchain if the user specified targets with
934  // the -fopenmp-targets option or used --offload-arch with OpenMP enabled.
935  bool IsOpenMPOffloading =
936  C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
937  options::OPT_fno_openmp, false) &&
938  (C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
939  C.getInputArgs().hasArg(options::OPT_offload_arch_EQ));
940  if (IsOpenMPOffloading) {
941  // We expect that -fopenmp-targets is always used in conjunction with the
942  // option -fopenmp specifying a valid runtime with offloading support, i.e.
943  // libomp or libiomp.
944  OpenMPRuntimeKind RuntimeKind = getOpenMPRuntime(C.getInputArgs());
945  if (RuntimeKind != OMPRT_OMP && RuntimeKind != OMPRT_IOMP5) {
946  Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
947  return;
948  }
949 
950  llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
951  llvm::StringMap<StringRef> FoundNormalizedTriples;
952  std::multiset<StringRef> OpenMPTriples;
953 
954  // If the user specified -fopenmp-targets= we create a toolchain for each
955  // valid triple. Otherwise, if only --offload-arch= was specified we instead
956  // attempt to derive the appropriate toolchains from the arguments.
957  if (Arg *OpenMPTargets =
958  C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
959  if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
960  Diag(clang::diag::warn_drv_empty_joined_argument)
961  << OpenMPTargets->getAsString(C.getInputArgs());
962  return;
963  }
964  for (StringRef T : OpenMPTargets->getValues())
965  OpenMPTriples.insert(T);
966  } else if (C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
967  !IsHIP && !IsCuda) {
968  const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
969  auto AMDTriple = getHIPOffloadTargetTriple(*this, C.getInputArgs());
970  auto NVPTXTriple = getNVIDIAOffloadTargetTriple(*this, C.getInputArgs(),
971  HostTC->getTriple());
972 
973  // Attempt to deduce the offloading triple from the set of architectures.
974  // We can only correctly deduce NVPTX / AMDGPU triples currently. We need
975  // to temporarily create these toolchains so that we can access tools for
976  // inferring architectures.
978  if (NVPTXTriple) {
979  auto TempTC = std::make_unique<toolchains::CudaToolChain>(
980  *this, *NVPTXTriple, *HostTC, C.getInputArgs(), Action::OFK_None);
981  for (StringRef Arch : getOffloadArchs(
982  C, C.getArgs(), Action::OFK_OpenMP, &*TempTC, true))
983  Archs.insert(Arch);
984  }
985  if (AMDTriple) {
986  auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
987  *this, *AMDTriple, *HostTC, C.getInputArgs());
988  for (StringRef Arch : getOffloadArchs(
989  C, C.getArgs(), Action::OFK_OpenMP, &*TempTC, true))
990  Archs.insert(Arch);
991  }
992  if (!AMDTriple && !NVPTXTriple) {
993  for (StringRef Arch :
994  getOffloadArchs(C, C.getArgs(), Action::OFK_OpenMP, nullptr, true))
995  Archs.insert(Arch);
996  }
997 
998  for (StringRef Arch : Archs) {
999  if (NVPTXTriple && IsNVIDIAGpuArch(StringToCudaArch(
1000  getProcessorFromTargetID(*NVPTXTriple, Arch)))) {
1001  DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
1002  } else if (AMDTriple &&
1004  getProcessorFromTargetID(*AMDTriple, Arch)))) {
1005  DerivedArchs[AMDTriple->getTriple()].insert(Arch);
1006  } else {
1007  Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
1008  return;
1009  }
1010  }
1011 
1012  // If the set is empty then we failed to find a native architecture.
1013  if (Archs.empty()) {
1014  Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1015  << "native";
1016  return;
1017  }
1018 
1019  for (const auto &TripleAndArchs : DerivedArchs)
1020  OpenMPTriples.insert(TripleAndArchs.first());
1021  }
1022 
1023  for (StringRef Val : OpenMPTriples) {
1024  llvm::Triple TT(ToolChain::getOpenMPTriple(Val));
1025  std::string NormalizedName = TT.normalize();
1026 
1027  // Make sure we don't have a duplicate triple.
1028  auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
1029  if (Duplicate != FoundNormalizedTriples.end()) {
1030  Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1031  << Val << Duplicate->second;
1032  continue;
1033  }
1034 
1035  // Store the current triple so that we can check for duplicates in the
1036  // following iterations.
1037  FoundNormalizedTriples[NormalizedName] = Val;
1038 
1039  // If the specified target is invalid, emit a diagnostic.
1040  if (TT.getArch() == llvm::Triple::UnknownArch)
1041  Diag(clang::diag::err_drv_invalid_omp_target) << Val;
1042  else {
1043  const ToolChain *TC;
1044  // Device toolchains have to be selected differently. They pair host
1045  // and device in their implementation.
1046  if (TT.isNVPTX() || TT.isAMDGCN()) {
1047  const ToolChain *HostTC =
1048  C.getSingleOffloadToolChain<Action::OFK_Host>();
1049  assert(HostTC && "Host toolchain should be always defined.");
1050  auto &DeviceTC =
1051  ToolChains[TT.str() + "/" + HostTC->getTriple().normalize()];
1052  if (!DeviceTC) {
1053  if (TT.isNVPTX())
1054  DeviceTC = std::make_unique<toolchains::CudaToolChain>(
1055  *this, TT, *HostTC, C.getInputArgs(), Action::OFK_OpenMP);
1056  else if (TT.isAMDGCN())
1057  DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
1058  *this, TT, *HostTC, C.getInputArgs());
1059  else
1060  assert(DeviceTC && "Device toolchain not defined.");
1061  }
1062 
1063  TC = DeviceTC.get();
1064  } else
1065  TC = &getToolChain(C.getInputArgs(), TT);
1066  C.addOffloadDeviceToolChain(TC, Action::OFK_OpenMP);
1067  if (DerivedArchs.contains(TT.getTriple()))
1068  KnownArchs[TC] = DerivedArchs[TT.getTriple()];
1069  }
1070  }
1071  } else if (C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
1072  Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1073  return;
1074  }
1075 
1076  //
1077  // SYCL
1078  //
1079  // We need to generate a SYCL toolchain if the user specified targets with
1080  // the -fsycl-targets. If -fsycl is supplied without any of these we will
1081  // assume SPIR-V.
1082  // Use of -fsycl-device-only overrides -fsycl.
1083  bool HasValidSYCLRuntime =
1084  C.getInputArgs().hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
1085  false) ||
1086  C.getInputArgs().hasArg(options::OPT_fsycl_device_only);
1087 
1088  Arg *SYCLfpga = C.getInputArgs().getLastArg(options::OPT_fintelfpga);
1089 
1090  // Make -fintelfpga flag imply -fsycl.
1091  if (SYCLfpga && !HasValidSYCLRuntime)
1092  HasValidSYCLRuntime = true;
1093 
1094  // A mechanism for retrieving SYCL-specific options, erroring out
1095  // if SYCL offloading wasn't enabled prior to that
1096  auto getArgRequiringSYCLRuntime = [&](OptSpecifier OptId) -> Arg * {
1097  Arg *SYCLArg = C.getInputArgs().getLastArg(OptId);
1098  if (SYCLArg && !HasValidSYCLRuntime) {
1099  Diag(clang::diag::err_drv_expecting_fsycl_with_sycl_opt)
1100  // Dropping the '=' symbol, which would otherwise pollute
1101  // the diagnostics for the most of options
1102  << SYCLArg->getSpelling().split('=').first;
1103  return nullptr;
1104  }
1105  return SYCLArg;
1106  };
1107 
1108  Arg *SYCLTargets = getArgRequiringSYCLRuntime(options::OPT_fsycl_targets_EQ);
1109  Arg *SYCLLink = getArgRequiringSYCLRuntime(options::OPT_fsycl_link_EQ);
1110 
1111  // Check if -fsycl-host-compiler is used in conjunction with -fsycl.
1112  Arg *SYCLHostCompiler =
1113  getArgRequiringSYCLRuntime(options::OPT_fsycl_host_compiler_EQ);
1114  Arg *SYCLHostCompilerOptions =
1115  getArgRequiringSYCLRuntime(options::OPT_fsycl_host_compiler_options_EQ);
1116 
1117  // -fsycl-targets cannot be used with -fintelfpga
1118  if (SYCLTargets && SYCLfpga)
1119  Diag(clang::diag::err_drv_option_conflict)
1120  << SYCLTargets->getSpelling() << SYCLfpga->getSpelling();
1121  // -fsycl-host-compiler-options cannot be used without -fsycl-host-compiler
1122  if (SYCLHostCompilerOptions && !SYCLHostCompiler)
1123  Diag(clang::diag::warn_drv_opt_requires_opt)
1124  << SYCLHostCompilerOptions->getSpelling().split('=').first
1125  << "-fsycl-host-compiler";
1126 
1127  auto argSYCLIncompatible = [&](OptSpecifier OptId) {
1128  if (!HasValidSYCLRuntime)
1129  return;
1130  if (Arg *IncompatArg = C.getInputArgs().getLastArg(OptId))
1131  Diag(clang::diag::err_drv_fsycl_unsupported_with_opt)
1132  << IncompatArg->getSpelling();
1133  };
1134  // -static-libstdc++ is not compatible with -fsycl.
1135  argSYCLIncompatible(options::OPT_static_libstdcxx);
1136  // -ffreestanding cannot be used with -fsycl
1137  argSYCLIncompatible(options::OPT_ffreestanding);
1138 
1139  // Diagnose incorrect inputs to SYCL options.
1140  // FIXME: Since the option definition includes the list of possible values,
1141  // the validation must be automatic, not requiring separate disjointed code
1142  // blocks accross the driver code. Long-term, the detection of incorrect
1143  // values must happen at the level of TableGen and Arg class design, with
1144  // Compilation/Driver class constructors handling the driver-specific
1145  // diagnostic output.
1146  auto checkSingleArgValidity = [&](Arg *A,
1147  SmallVector<StringRef, 4> AllowedValues) {
1148  if (!A)
1149  return;
1150  const char *ArgValue = A->getValue();
1151  for (const StringRef AllowedValue : AllowedValues)
1152  if (AllowedValue == ArgValue)
1153  return;
1154  Diag(clang::diag::err_drv_invalid_argument_to_option)
1155  << ArgValue << A->getOption().getName();
1156  };
1157  Arg *DeviceCodeSplit =
1158  C.getInputArgs().getLastArg(options::OPT_fsycl_device_code_split_EQ);
1159  checkSingleArgValidity(SYCLLink, {"early", "image"});
1160  checkSingleArgValidity(DeviceCodeSplit,
1161  {"per_kernel", "per_source", "auto", "off"});
1162 
1163  Arg *RangeRoundingPreference =
1164  C.getInputArgs().getLastArg(options::OPT_fsycl_range_rounding_EQ);
1165  checkSingleArgValidity(RangeRoundingPreference, {"disable", "force", "on"});
1166 
1167  Arg *SYCLForceTarget =
1168  getArgRequiringSYCLRuntime(options::OPT_fsycl_force_target_EQ);
1169  if (SYCLForceTarget) {
1170  StringRef Val(SYCLForceTarget->getValue());
1171  llvm::Triple TT(MakeSYCLDeviceTriple(Val));
1172  if (!isValidSYCLTriple(TT))
1173  Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1174  }
1175  bool HasSYCLTargetsOption = SYCLTargets;
1176 
1177  llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
1178  llvm::StringMap<StringRef> FoundNormalizedTriples;
1179  llvm::SmallVector<llvm::Triple, 4> UniqueSYCLTriplesVec;
1180  if (HasSYCLTargetsOption) {
1181  // At this point, we know we have a valid combination
1182  // of -fsycl*target options passed
1183  Arg *SYCLTargetsValues = SYCLTargets;
1184  if (SYCLTargetsValues) {
1185  llvm::StringSet<> SYCLTriples;
1186  if (SYCLTargetsValues->getNumValues()) {
1187 
1188  // Multiple targets are currently not supported when using
1189  // -fsycl-force-target as the bundler does not allow for multiple
1190  // outputs of the same target.
1191  if (SYCLForceTarget && SYCLTargetsValues->getNumValues() > 1)
1192  Diag(clang::diag::err_drv_multiple_target_with_forced_target)
1193  << SYCLTargetsValues->getAsString(C.getInputArgs())
1194  << SYCLForceTarget->getAsString(C.getInputArgs());
1195 
1196  for (StringRef Val : SYCLTargetsValues->getValues()) {
1197  StringRef Arch;
1198  StringRef UserTargetName(Val);
1199  if (auto Device = gen::isGPUTarget<gen::IntelGPU>(Val)) {
1200  if (Device->empty()) {
1201  Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1202  continue;
1203  }
1204  Arch = Device->data();
1205  UserTargetName = "spir64_gen";
1206  } else if (auto Device = gen::isGPUTarget<gen::NvidiaGPU>(Val)) {
1207  if (Device->empty()) {
1208  Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1209  continue;
1210  }
1211  Arch = Device->data();
1212  UserTargetName = "nvptx64-nvidia-cuda";
1213  } else if (auto Device = gen::isGPUTarget<gen::AmdGPU>(Val)) {
1214  if (Device->empty()) {
1215  Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1216  continue;
1217  }
1218  Arch = Device->data();
1219  UserTargetName = "amdgcn-amd-amdhsa";
1220  } else if (Val == "native_cpu") {
1221  const ToolChain *HostTC =
1222  C.getSingleOffloadToolChain<Action::OFK_Host>();
1223  llvm::Triple HostTriple = HostTC->getTriple();
1224  SYCLTriples.insert(HostTriple.normalize());
1225  continue;
1226  }
1227 
1228  llvm::Triple DeviceTriple(MakeSYCLDeviceTriple(UserTargetName));
1229  if (!isValidSYCLTriple(DeviceTriple)) {
1230  Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1231  continue;
1232  }
1233 
1234  // For any -fsycl-targets=spir64_gen additions, we will scan the
1235  // additional -X* options for potential -device settings. These
1236  // need to be added as a known Arch to the packager.
1237  if (DeviceTriple.isSPIRAOT() && Arch.empty() &&
1238  DeviceTriple.getSubArch() == llvm::Triple::SPIRSubArch_gen) {
1239  const ToolChain *HostTC =
1240  C.getSingleOffloadToolChain<Action::OFK_Host>();
1241  auto DeviceTC = std::make_unique<toolchains::SYCLToolChain>(
1242  *this, DeviceTriple, *HostTC, C.getInputArgs());
1243  assert(DeviceTC && "Device toolchain not defined.");
1244  ArgStringList TargetArgs;
1245  DeviceTC->TranslateBackendTargetArgs(DeviceTC->getTriple(),
1246  C.getInputArgs(), TargetArgs);
1247  // Look for -device <string> and use that as the known arch to
1248  // be associated with the current spir64_gen entry. Grab the
1249  // right most entry.
1250  for (int i = TargetArgs.size() - 2; i >= 0; --i) {
1251  if (StringRef(TargetArgs[i]) == "-device") {
1252  Arch = TargetArgs[i + 1];
1253  break;
1254  }
1255  }
1256  }
1257 
1258  // Make sure we don't have a duplicate triple.
1259  std::string NormalizedName = MakeSYCLDeviceTriple(Val).normalize();
1260  auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
1261  if (Duplicate != FoundNormalizedTriples.end()) {
1262  Diag(clang::diag::warn_drv_sycl_offload_target_duplicate)
1263  << Val << Duplicate->second;
1264  continue;
1265  }
1266 
1267  // Store the current triple so that we can check for duplicates in
1268  // the following iterations.
1269  FoundNormalizedTriples[NormalizedName] = Val;
1270  SYCLTriples.insert(DeviceTriple.normalize());
1271  if (!Arch.empty())
1272  DerivedArchs[DeviceTriple.getTriple()].insert(Arch);
1273  }
1274  if (!SYCLTriples.empty()) {
1275  for (const auto &SYCLTriple : SYCLTriples) {
1276  llvm::Triple Triple(SYCLTriple.getKey());
1277  UniqueSYCLTriplesVec.push_back(Triple);
1278  }
1279  }
1280  addSYCLDefaultTriple(C, UniqueSYCLTriplesVec);
1281  } else
1282  Diag(clang::diag::warn_drv_empty_joined_argument)
1283  << SYCLTargetsValues->getAsString(C.getInputArgs());
1284  }
1285  } else {
1286  // If -fsycl is supplied without -fsycl-*targets we will assume SPIR-V
1287  // unless -fintelfpga is supplied, which uses SPIR-V with fpga AOT.
1288  // For -fsycl-device-only, we also setup the implied triple as needed.
1289  if (HasValidSYCLRuntime) {
1290  StringRef SYCLTargetArch = getDefaultSYCLArch(C);
1291  if (SYCLfpga)
1292  // Triple for -fintelfpga is spir64_fpga.
1293  SYCLTargetArch = "spir64_fpga";
1294  UniqueSYCLTriplesVec.push_back(MakeSYCLDeviceTriple(SYCLTargetArch));
1295  addSYCLDefaultTriple(C, UniqueSYCLTriplesVec);
1296  }
1297  }
1298  // -fno-sycl-libspirv flag is reserved for very unusual cases where the
1299  // libspirv library is not linked when using CUDA/HIP: so output appropriate
1300  // warnings.
1301  if (C.getInputArgs().hasArg(options::OPT_fno_sycl_libspirv)) {
1302  for (auto &TT : UniqueSYCLTriplesVec) {
1303  if (TT.isNVPTX() || TT.isAMDGCN()) {
1304  Diag(diag::warn_flag_no_sycl_libspirv) << TT.getTriple();
1305  } else {
1306  Diag(diag::warn_drv_unsupported_option_for_target)
1307  << "-fno-sycl-libspirv" << TT.getTriple();
1308  }
1309  }
1310  }
1311  // -fsycl-fp64-conv-emu is valid only for AOT compilation with an Intel GPU
1312  // target. For other scenarios, we emit a warning message.
1313  if (C.getInputArgs().hasArg(options::OPT_fsycl_fp64_conv_emu)) {
1314  bool HasIntelGPUAOTTarget = false;
1315  for (auto &TT : UniqueSYCLTriplesVec) {
1316  if (TT.isSPIRAOT() && TT.getSubArch() == llvm::Triple::SPIRSubArch_gen) {
1317  HasIntelGPUAOTTarget = true;
1318  break;
1319  }
1320  }
1321  if (!HasIntelGPUAOTTarget)
1322  Diag(diag::warn_unsupported_fsycl_fp64_conv_emu_use);
1323  }
1324 
1325  // We'll need to use the SYCL and host triples as the key into
1326  // getOffloadingDeviceToolChain, because the device toolchains we're
1327  // going to create will depend on both.
1328  const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
1329  for (auto &TT : UniqueSYCLTriplesVec) {
1330  auto SYCLTC = &getOffloadingDeviceToolChain(C.getInputArgs(), TT, *HostTC,
1332  C.addOffloadDeviceToolChain(SYCLTC, Action::OFK_SYCL);
1333  if (DerivedArchs.contains(TT.getTriple()))
1334  KnownArchs[SYCLTC] = DerivedArchs[TT.getTriple()];
1335  }
1336 
1337  //
1338  // TODO: Add support for other offloading programming models here.
1339  //
1340 }
1341 
1342 static void appendOneArg(InputArgList &Args, const Arg *Opt,
1343  const Arg *BaseArg) {
1344  // The args for config files or /clang: flags belong to different InputArgList
1345  // objects than Args. This copies an Arg from one of those other InputArgLists
1346  // to the ownership of Args.
1347  unsigned Index = Args.MakeIndex(Opt->getSpelling());
1348  Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index),
1349  Index, BaseArg);
1350  Copy->getValues() = Opt->getValues();
1351  if (Opt->isClaimed())
1352  Copy->claim();
1353  Copy->setOwnsValues(Opt->getOwnsValues());
1354  Opt->setOwnsValues(false);
1355  Args.append(Copy);
1356 }
1357 
1358 bool Driver::readConfigFile(StringRef FileName,
1359  llvm::cl::ExpansionContext &ExpCtx) {
1360  // Try opening the given file.
1361  auto Status = getVFS().status(FileName);
1362  if (!Status) {
1363  Diag(diag::err_drv_cannot_open_config_file)
1364  << FileName << Status.getError().message();
1365  return true;
1366  }
1367  if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1368  Diag(diag::err_drv_cannot_open_config_file)
1369  << FileName << "not a regular file";
1370  return true;
1371  }
1372 
1373  // Try reading the given file.
1374  SmallVector<const char *, 32> NewCfgArgs;
1375  if (llvm::Error Err = ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
1376  Diag(diag::err_drv_cannot_read_config_file)
1377  << FileName << toString(std::move(Err));
1378  return true;
1379  }
1380 
1381  // Read options from config file.
1382  llvm::SmallString<128> CfgFileName(FileName);
1383  llvm::sys::path::native(CfgFileName);
1384  bool ContainErrors;
1385  std::unique_ptr<InputArgList> NewOptions = std::make_unique<InputArgList>(
1386  ParseArgStrings(NewCfgArgs, /*UseDriverMode=*/true, ContainErrors));
1387  if (ContainErrors)
1388  return true;
1389 
1390  // Claim all arguments that come from a configuration file so that the driver
1391  // does not warn on any that is unused.
1392  for (Arg *A : *NewOptions)
1393  A->claim();
1394 
1395  if (!CfgOptions)
1396  CfgOptions = std::move(NewOptions);
1397  else {
1398  // If this is a subsequent config file, append options to the previous one.
1399  for (auto *Opt : *NewOptions) {
1400  const Arg *BaseArg = &Opt->getBaseArg();
1401  if (BaseArg == Opt)
1402  BaseArg = nullptr;
1403  appendOneArg(*CfgOptions, Opt, BaseArg);
1404  }
1405  }
1406  ConfigFiles.push_back(std::string(CfgFileName));
1407  return false;
1408 }
1409 
1410 bool Driver::loadConfigFiles() {
1411  llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1412  llvm::cl::tokenizeConfigFile);
1413  ExpCtx.setVFS(&getVFS());
1414 
1415  // Process options that change search path for config files.
1416  if (CLOptions) {
1417  if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1418  SmallString<128> CfgDir;
1419  CfgDir.append(
1420  CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1421  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
1422  SystemConfigDir.clear();
1423  else
1424  SystemConfigDir = static_cast<std::string>(CfgDir);
1425  }
1426  if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1427  SmallString<128> CfgDir;
1428  llvm::sys::fs::expand_tilde(
1429  CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1430  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
1431  UserConfigDir.clear();
1432  else
1433  UserConfigDir = static_cast<std::string>(CfgDir);
1434  }
1435  }
1436 
1437  // Prepare list of directories where config file is searched for.
1438  StringRef CfgFileSearchDirs[] = {UserConfigDir, SystemConfigDir, Dir};
1439  ExpCtx.setSearchDirs(CfgFileSearchDirs);
1440 
1441  // First try to load configuration from the default files, return on error.
1442  if (loadDefaultConfigFiles(ExpCtx))
1443  return true;
1444 
1445  // Then load configuration files specified explicitly.
1446  SmallString<128> CfgFilePath;
1447  if (CLOptions) {
1448  for (auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1449  // If argument contains directory separator, treat it as a path to
1450  // configuration file.
1451  if (llvm::sys::path::has_parent_path(CfgFileName)) {
1452  CfgFilePath.assign(CfgFileName);
1453  if (llvm::sys::path::is_relative(CfgFilePath)) {
1454  if (getVFS().makeAbsolute(CfgFilePath)) {
1455  Diag(diag::err_drv_cannot_open_config_file)
1456  << CfgFilePath << "cannot get absolute path";
1457  return true;
1458  }
1459  }
1460  } else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1461  // Report an error that the config file could not be found.
1462  Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1463  for (const StringRef &SearchDir : CfgFileSearchDirs)
1464  if (!SearchDir.empty())
1465  Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1466  return true;
1467  }
1468 
1469  // Try to read the config file, return on error.
1470  if (readConfigFile(CfgFilePath, ExpCtx))
1471  return true;
1472  }
1473  }
1474 
1475  // No error occurred.
1476  return false;
1477 }
1478 
1479 bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1480  // Disable default config if CLANG_NO_DEFAULT_CONFIG is set to a non-empty
1481  // value.
1482  if (const char *NoConfigEnv = ::getenv("CLANG_NO_DEFAULT_CONFIG")) {
1483  if (*NoConfigEnv)
1484  return false;
1485  }
1486  if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1487  return false;
1488 
1489  std::string RealMode = getExecutableForDriverMode(Mode);
1490  std::string Triple;
1491 
1492  // If name prefix is present, no --target= override was passed via CLOptions
1493  // and the name prefix is not a valid triple, force it for backwards
1494  // compatibility.
1495  if (!ClangNameParts.TargetPrefix.empty() &&
1496  computeTargetTriple(*this, "/invalid/", *CLOptions).str() ==
1497  "/invalid/") {
1498  llvm::Triple PrefixTriple{ClangNameParts.TargetPrefix};
1499  if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1500  PrefixTriple.isOSUnknown())
1501  Triple = PrefixTriple.str();
1502  }
1503 
1504  // Otherwise, use the real triple as used by the driver.
1505  if (Triple.empty()) {
1506  llvm::Triple RealTriple =
1507  computeTargetTriple(*this, TargetTriple, *CLOptions);
1508  Triple = RealTriple.str();
1509  assert(!Triple.empty());
1510  }
1511 
1512  // Search for config files in the following order:
1513  // 1. <triple>-<mode>.cfg using real driver mode
1514  // (e.g. i386-pc-linux-gnu-clang++.cfg).
1515  // 2. <triple>-<mode>.cfg using executable suffix
1516  // (e.g. i386-pc-linux-gnu-clang-g++.cfg for *clang-g++).
1517  // 3. <triple>.cfg + <mode>.cfg using real driver mode
1518  // (e.g. i386-pc-linux-gnu.cfg + clang++.cfg).
1519  // 4. <triple>.cfg + <mode>.cfg using executable suffix
1520  // (e.g. i386-pc-linux-gnu.cfg + clang-g++.cfg for *clang-g++).
1521 
1522  // Try loading <triple>-<mode>.cfg, and return if we find a match.
1523  SmallString<128> CfgFilePath;
1524  std::string CfgFileName = Triple + '-' + RealMode + ".cfg";
1525  if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1526  return readConfigFile(CfgFilePath, ExpCtx);
1527 
1528  bool TryModeSuffix = !ClangNameParts.ModeSuffix.empty() &&
1529  ClangNameParts.ModeSuffix != RealMode;
1530  if (TryModeSuffix) {
1531  CfgFileName = Triple + '-' + ClangNameParts.ModeSuffix + ".cfg";
1532  if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1533  return readConfigFile(CfgFilePath, ExpCtx);
1534  }
1535 
1536  // Try loading <mode>.cfg, and return if loading failed. If a matching file
1537  // was not found, still proceed on to try <triple>.cfg.
1538  CfgFileName = RealMode + ".cfg";
1539  if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1540  if (readConfigFile(CfgFilePath, ExpCtx))
1541  return true;
1542  } else if (TryModeSuffix) {
1543  CfgFileName = ClangNameParts.ModeSuffix + ".cfg";
1544  if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1545  readConfigFile(CfgFilePath, ExpCtx))
1546  return true;
1547  }
1548 
1549  // Try loading <triple>.cfg and return if we find a match.
1550  CfgFileName = Triple + ".cfg";
1551  if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1552  return readConfigFile(CfgFilePath, ExpCtx);
1553 
1554  // If we were unable to find a config file deduced from executable name,
1555  // that is not an error.
1556  return false;
1557 }
1558 
1560  llvm::PrettyStackTraceString CrashInfo("Compilation construction");
1561 
1562  // FIXME: Handle environment options which affect driver behavior, somewhere
1563  // (client?). GCC_EXEC_PREFIX, LPATH, CC_PRINT_OPTIONS.
1564 
1565  // We look for the driver mode option early, because the mode can affect
1566  // how other options are parsed.
1567 
1568  auto DriverMode = getDriverMode(ClangExecutable, ArgList.slice(1));
1569  if (!DriverMode.empty())
1570  setDriverMode(DriverMode);
1571 
1572  setResourceDirectory();
1573  // FIXME: What are we going to do with -V and -b?
1574 
1575  // Arguments specified in command line.
1576  bool ContainsError;
1577  CLOptions = std::make_unique<InputArgList>(
1578  ParseArgStrings(ArgList.slice(1), /*UseDriverMode=*/true, ContainsError));
1579 
1580  // Try parsing configuration file.
1581  if (!ContainsError)
1582  ContainsError = loadConfigFiles();
1583  bool HasConfigFile = !ContainsError && (CfgOptions.get() != nullptr);
1584 
1585  // All arguments, from both config file and command line.
1586  InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
1587  : std::move(*CLOptions));
1588 
1589  if (HasConfigFile)
1590  for (auto *Opt : *CLOptions) {
1591  if (Opt->getOption().matches(options::OPT_config))
1592  continue;
1593  const Arg *BaseArg = &Opt->getBaseArg();
1594  if (BaseArg == Opt)
1595  BaseArg = nullptr;
1596  appendOneArg(Args, Opt, BaseArg);
1597  }
1598 
1599  // In CL mode, look for any pass-through arguments
1600  if (IsCLMode() && !ContainsError) {
1601  SmallVector<const char *, 16> CLModePassThroughArgList;
1602  for (const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1603  A->claim();
1604  CLModePassThroughArgList.push_back(A->getValue());
1605  }
1606 
1607  if (!CLModePassThroughArgList.empty()) {
1608  // Parse any pass through args using default clang processing rather
1609  // than clang-cl processing.
1610  auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1611  ParseArgStrings(CLModePassThroughArgList, /*UseDriverMode=*/false,
1612  ContainsError));
1613 
1614  if (!ContainsError)
1615  for (auto *Opt : *CLModePassThroughOptions) {
1616  appendOneArg(Args, Opt, nullptr);
1617  }
1618  }
1619  }
1620 
1621  if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
1622  CCCIsCC())
1623  setDriverMode("g++");
1624 
1625  // Check for working directory option before accessing any files
1626  if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1627  if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1628  Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1629 
1630  // FIXME: This stuff needs to go into the Compilation, not the driver.
1631  bool CCCPrintPhases;
1632 
1633  // -canonical-prefixes, -no-canonical-prefixes are used very early in main.
1634  Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1635  Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1636 
1637  // f(no-)integated-cc1 is also used very early in main.
1638  Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1639  Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1640 
1641  // Ignore -pipe.
1642  Args.ClaimAllArgs(options::OPT_pipe);
1643 
1644  // Extract -ccc args.
1645  //
1646  // FIXME: We need to figure out where this behavior should live. Most of it
1647  // should be outside in the client; the parts that aren't should have proper
1648  // options, either by introducing new ones or by overloading gcc ones like -V
1649  // or -b.
1650  CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1651  CCCPrintBindings = Args.hasArg(options::OPT_ccc_print_bindings);
1652  if (const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1653  CCCGenericGCCName = A->getValue();
1654 
1655  // Process -fproc-stat-report options.
1656  if (const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1657  CCPrintProcessStats = true;
1658  CCPrintStatReportFilename = A->getValue();
1659  }
1660  if (Args.hasArg(options::OPT_fproc_stat_report))
1661  CCPrintProcessStats = true;
1662 
1663  // FIXME: TargetTriple is used by the target-prefixed calls to as/ld
1664  // and getToolChain is const.
1665  if (IsCLMode()) {
1666  // clang-cl targets MSVC-style Win32.
1667  llvm::Triple T(TargetTriple);
1668  T.setOS(llvm::Triple::Win32);
1669  T.setVendor(llvm::Triple::PC);
1670  T.setEnvironment(llvm::Triple::MSVC);
1671  T.setObjectFormat(llvm::Triple::COFF);
1672  if (Args.hasArg(options::OPT__SLASH_arm64EC))
1673  T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1674  TargetTriple = T.str();
1675  } else if (IsDXCMode()) {
1676  // Build TargetTriple from target_profile option for clang-dxc.
1677  if (const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1678  StringRef TargetProfile = A->getValue();
1679  if (auto Triple =
1681  TargetTriple = *Triple;
1682  else
1683  Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1684 
1685  A->claim();
1686 
1687  if (Args.hasArg(options::OPT_spirv)) {
1688  llvm::Triple T(TargetTriple);
1689  T.setArch(llvm::Triple::spirv);
1690  T.setOS(llvm::Triple::Vulkan);
1691 
1692  // Set specific Vulkan version if applicable.
1693  if (const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1694  const llvm::StringSet<> ValidValues = {"vulkan1.2", "vulkan1.3"};
1695  if (ValidValues.contains(A->getValue())) {
1696  T.setOSName(A->getValue());
1697  } else {
1698  Diag(diag::err_drv_invalid_value)
1699  << A->getAsString(Args) << A->getValue();
1700  }
1701  A->claim();
1702  }
1703 
1704  TargetTriple = T.str();
1705  }
1706  } else {
1707  Diag(diag::err_drv_dxc_missing_target_profile);
1708  }
1709  }
1710 
1711  if (const Arg *A = Args.getLastArg(options::OPT_target))
1712  TargetTriple = A->getValue();
1713  if (const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1714  Dir = Dir = A->getValue();
1715  for (const Arg *A : Args.filtered(options::OPT_B)) {
1716  A->claim();
1717  PrefixDirs.push_back(A->getValue(0));
1718  }
1719  if (std::optional<std::string> CompilerPathValue =
1720  llvm::sys::Process::GetEnv("COMPILER_PATH")) {
1721  StringRef CompilerPath = *CompilerPathValue;
1722  while (!CompilerPath.empty()) {
1723  std::pair<StringRef, StringRef> Split =
1724  CompilerPath.split(llvm::sys::EnvPathSeparator);
1725  PrefixDirs.push_back(std::string(Split.first));
1726  CompilerPath = Split.second;
1727  }
1728  }
1729  if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1730  SysRoot = A->getValue();
1731  if (const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1732  DyldPrefix = A->getValue();
1733 
1734  if (const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1735  ResourceDir = A->getValue();
1736 
1737  if (const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1738  SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1739  .Case("cwd", SaveTempsCwd)
1740  .Case("obj", SaveTempsObj)
1741  .Default(SaveTempsCwd);
1742  }
1743 
1744  if (Args.getLastArg(options::OPT_fsycl_dump_device_code_EQ))
1745  DumpDeviceCode = true;
1746 
1747  if (const Arg *A = Args.getLastArg(
1748  options::OPT_offload_host_only, options::OPT_offload_device_only,
1749  options::OPT_offload_host_device, options::OPT_fsycl_device_only)) {
1750  if (A->getOption().matches(options::OPT_offload_host_only))
1751  Offload = OffloadHost;
1752  else if (A->getOption().matches(options::OPT_offload_device_only) ||
1753  A->getOption().matches(options::OPT_fsycl_device_only))
1754  Offload = OffloadDevice;
1755  else
1756  Offload = OffloadHostDevice;
1757  }
1758 
1759  setLTOMode(Args);
1760 
1761  // Process -fembed-bitcode= flags.
1762  if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1763  StringRef Name = A->getValue();
1764  unsigned Model = llvm::StringSwitch<unsigned>(Name)
1765  .Case("off", EmbedNone)
1766  .Case("all", EmbedBitcode)
1767  .Case("bitcode", EmbedBitcode)
1768  .Case("marker", EmbedMarker)
1769  .Default(~0U);
1770  if (Model == ~0U) {
1771  Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1772  << Name;
1773  } else
1774  BitcodeEmbed = static_cast<BitcodeEmbedMode>(Model);
1775  }
1776 
1777  // Remove existing compilation database so that each job can append to it.
1778  if (Arg *A = Args.getLastArg(options::OPT_MJ))
1779  llvm::sys::fs::remove(A->getValue());
1780 
1781  // Setting up the jobs for some precompile cases depends on whether we are
1782  // treating them as PCH, implicit modules or C++20 ones.
1783  // TODO: inferring the mode like this seems fragile (it meets the objective
1784  // of not requiring anything new for operation, however).
1785  const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1786  ModulesModeCXX20 =
1787  !Args.hasArg(options::OPT_fmodules) && Std &&
1788  (Std->containsValue("c++20") || Std->containsValue("c++2a") ||
1789  Std->containsValue("c++23") || Std->containsValue("c++2b") ||
1790  Std->containsValue("c++26") || Std->containsValue("c++2c") ||
1791  Std->containsValue("c++latest"));
1792 
1793  // Process -fmodule-header{=} flags.
1794  if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1795  options::OPT_fmodule_header)) {
1796  // These flags force C++20 handling of headers.
1797  ModulesModeCXX20 = true;
1798  if (A->getOption().matches(options::OPT_fmodule_header))
1799  CXX20HeaderType = HeaderMode_Default;
1800  else {
1801  StringRef ArgName = A->getValue();
1802  unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1803  .Case("user", HeaderMode_User)
1804  .Case("system", HeaderMode_System)
1805  .Default(~0U);
1806  if (Kind == ~0U) {
1807  Diags.Report(diag::err_drv_invalid_value)
1808  << A->getAsString(Args) << ArgName;
1809  } else
1810  CXX20HeaderType = static_cast<ModuleHeaderMode>(Kind);
1811  }
1812  }
1813 
1814  std::unique_ptr<llvm::opt::InputArgList> UArgs =
1815  std::make_unique<InputArgList>(std::move(Args));
1816 
1817  // Perform the default argument translations.
1818  DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1819 
1820  // Owned by the host.
1821  const ToolChain &TC = getToolChain(
1822  *UArgs, computeTargetTriple(*this, TargetTriple, *UArgs));
1823 
1824  // Check if the environment version is valid except wasm case.
1825  llvm::Triple Triple = TC.getTriple();
1826  if (!Triple.isWasm()) {
1827  StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1828  StringRef TripleObjectFormat =
1829  Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1830  if (Triple.getEnvironmentVersion().empty() && TripleVersionName != "" &&
1831  TripleVersionName != TripleObjectFormat) {
1832  Diags.Report(diag::err_drv_triple_version_invalid)
1833  << TripleVersionName << TC.getTripleString();
1834  ContainsError = true;
1835  }
1836  }
1837 
1838  // Report warning when arm64EC option is overridden by specified target
1839  if ((TC.getTriple().getArch() != llvm::Triple::aarch64 ||
1840  TC.getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1841  UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1842  getDiags().Report(clang::diag::warn_target_override_arm64ec)
1843  << TC.getTriple().str();
1844  }
1845 
1846  // A common user mistake is specifying a target of aarch64-none-eabi or
1847  // arm-none-elf whereas the correct names are aarch64-none-elf &
1848  // arm-none-eabi. Detect these cases and issue a warning.
1849  if (TC.getTriple().getOS() == llvm::Triple::UnknownOS &&
1850  TC.getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1851  switch (TC.getTriple().getArch()) {
1852  case llvm::Triple::arm:
1853  case llvm::Triple::armeb:
1854  case llvm::Triple::thumb:
1855  case llvm::Triple::thumbeb:
1856  if (TC.getTriple().getEnvironmentName() == "elf") {
1857  Diag(diag::warn_target_unrecognized_env)
1858  << TargetTriple
1859  << (TC.getTriple().getArchName().str() + "-none-eabi");
1860  }
1861  break;
1862  case llvm::Triple::aarch64:
1863  case llvm::Triple::aarch64_be:
1864  case llvm::Triple::aarch64_32:
1865  if (TC.getTriple().getEnvironmentName().starts_with("eabi")) {
1866  Diag(diag::warn_target_unrecognized_env)
1867  << TargetTriple
1868  << (TC.getTriple().getArchName().str() + "-none-elf");
1869  }
1870  break;
1871  default:
1872  break;
1873  }
1874  }
1875 
1876  // The compilation takes ownership of Args.
1877  Compilation *C = new Compilation(*this, TC, UArgs.release(), TranslatedArgs,
1878  ContainsError);
1879 
1880  if (!HandleImmediateArgs(*C))
1881  return C;
1882 
1883  // Construct the list of inputs.
1884  InputList Inputs;
1885  BuildInputs(C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1886 
1887  // Determine if there are any offload static libraries.
1888  if (checkForOffloadStaticLib(*C, *TranslatedArgs))
1889  setOffloadStaticLibSeen();
1890 
1891  // Check for any objects/archives that need to be compiled with the default
1892  // triple.
1893  if (checkForSYCLDefaultDevice(*C, *TranslatedArgs))
1894  setSYCLDefaultTriple(true);
1895 
1896  // Populate the tool chains for the offloading devices, if any.
1898 
1899  // Use new offloading path for OpenMP. This is disabled as the SYCL
1900  // offloading path is not properly setup to use the updated device linking
1901  // scheme.
1902  if ((C->isOffloadingHostKind(Action::OFK_OpenMP) &&
1903  TranslatedArgs->hasFlag(options::OPT_fopenmp_new_driver,
1904  options::OPT_no_offload_new_driver, true)) ||
1905  TranslatedArgs->hasFlag(options::OPT_offload_new_driver,
1906  options::OPT_no_offload_new_driver, false))
1907  setUseNewOffloadingDriver();
1908 
1909  // Determine FPGA emulation status.
1910  if (C->hasOffloadToolChain<Action::OFK_SYCL>()) {
1911  auto SYCLTCRange = C->getOffloadToolChains<Action::OFK_SYCL>();
1912  for (auto TI = SYCLTCRange.first, TE = SYCLTCRange.second; TI != TE; ++TI) {
1913  if (TI->second->getTriple().getSubArch() !=
1914  llvm::Triple::SPIRSubArch_fpga)
1915  continue;
1916  ArgStringList TargetArgs;
1917  const toolchains::SYCLToolChain *FPGATC =
1918  static_cast<const toolchains::SYCLToolChain *>(TI->second);
1919  FPGATC->TranslateBackendTargetArgs(FPGATC->getTriple(), *TranslatedArgs,
1920  TargetArgs);
1921  // By default, FPGAEmulationMode is true due to the fact that
1922  // an external option setting is required to target hardware.
1924  for (StringRef ArgString : TargetArgs) {
1925  if (ArgString == "-hardware" || ArgString == "-simulation") {
1927  break;
1928  }
1929  }
1930  break;
1931  }
1932  }
1933 
1934  // Construct the list of abstract actions to perform for this compilation. On
1935  // MachO targets this uses the driver-driver and universal actions.
1936  if (TC.getTriple().isOSBinFormatMachO())
1937  BuildUniversalActions(*C, C->getDefaultToolChain(), Inputs);
1938  else
1939  BuildActions(*C, C->getArgs(), Inputs, C->getActions());
1940 
1941  if (CCCPrintPhases) {
1942  PrintActions(*C);
1943  return C;
1944  }
1945 
1946  BuildJobs(*C);
1947 
1948  return C;
1949 }
1950 
1951 static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args) {
1952  llvm::opt::ArgStringList ASL;
1953  for (const auto *A : Args) {
1954  // Use user's original spelling of flags. For example, use
1955  // `/source-charset:utf-8` instead of `-finput-charset=utf-8` if the user
1956  // wrote the former.
1957  while (A->getAlias())
1958  A = A->getAlias();
1959  A->render(Args, ASL);
1960  }
1961 
1962  for (auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1963  if (I != ASL.begin())
1964  OS << ' ';
1965  llvm::sys::printArg(OS, *I, true);
1966  }
1967  OS << '\n';
1968 }
1969 
1970 bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1971  SmallString<128> &CrashDiagDir) {
1972  using namespace llvm::sys;
1973  assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1974  "Only knows about .crash files on Darwin");
1975 
1976  // The .crash file can be found on at ~/Library/Logs/DiagnosticReports/
1977  // (or /Library/Logs/DiagnosticReports for root) and has the filename pattern
1978  // clang-<VERSION>_<YYYY-MM-DD-HHMMSS>_<hostname>.crash.
1979  path::home_directory(CrashDiagDir);
1980  if (CrashDiagDir.starts_with("/var/root"))
1981  CrashDiagDir = "/";
1982  path::append(CrashDiagDir, "Library/Logs/DiagnosticReports");
1983  int PID =
1984 #if LLVM_ON_UNIX
1985  getpid();
1986 #else
1987  0;
1988 #endif
1989  std::error_code EC;
1990  fs::file_status FileStatus;
1991  TimePoint<> LastAccessTime;
1992  SmallString<128> CrashFilePath;
1993  // Lookup the .crash files and get the one generated by a subprocess spawned
1994  // by this driver invocation.
1995  for (fs::directory_iterator File(CrashDiagDir, EC), FileEnd;
1996  File != FileEnd && !EC; File.increment(EC)) {
1997  StringRef FileName = path::filename(File->path());
1998  if (!FileName.starts_with(Name))
1999  continue;
2000  if (fs::status(File->path(), FileStatus))
2001  continue;
2002  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
2003  llvm::MemoryBuffer::getFile(File->path());
2004  if (!CrashFile)
2005  continue;
2006  // The first line should start with "Process:", otherwise this isn't a real
2007  // .crash file.
2008  StringRef Data = CrashFile.get()->getBuffer();
2009  if (!Data.starts_with("Process:"))
2010  continue;
2011  // Parse parent process pid line, e.g: "Parent Process: clang-4.0 [79141]"
2012  size_t ParentProcPos = Data.find("Parent Process:");
2013  if (ParentProcPos == StringRef::npos)
2014  continue;
2015  size_t LineEnd = Data.find_first_of("\n", ParentProcPos);
2016  if (LineEnd == StringRef::npos)
2017  continue;
2018  StringRef ParentProcess = Data.slice(ParentProcPos+15, LineEnd).trim();
2019  int OpenBracket = -1, CloseBracket = -1;
2020  for (size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
2021  if (ParentProcess[i] == '[')
2022  OpenBracket = i;
2023  if (ParentProcess[i] == ']')
2024  CloseBracket = i;
2025  }
2026  // Extract the parent process PID from the .crash file and check whether
2027  // it matches this driver invocation pid.
2028  int CrashPID;
2029  if (OpenBracket < 0 || CloseBracket < 0 ||
2030  ParentProcess.slice(OpenBracket + 1, CloseBracket)
2031  .getAsInteger(10, CrashPID) || CrashPID != PID) {
2032  continue;
2033  }
2034 
2035  // Found a .crash file matching the driver pid. To avoid getting an older
2036  // and misleading crash file, continue looking for the most recent.
2037  // FIXME: the driver can dispatch multiple cc1 invocations, leading to
2038  // multiple crashes poiting to the same parent process. Since the driver
2039  // does not collect pid information for the dispatched invocation there's
2040  // currently no way to distinguish among them.
2041  const auto FileAccessTime = FileStatus.getLastModificationTime();
2042  if (FileAccessTime > LastAccessTime) {
2043  CrashFilePath.assign(File->path());
2044  LastAccessTime = FileAccessTime;
2045  }
2046  }
2047 
2048  // If found, copy it over to the location of other reproducer files.
2049  if (!CrashFilePath.empty()) {
2050  EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2051  if (EC)
2052  return false;
2053  return true;
2054  }
2055 
2056  return false;
2057 }
2058 
2059 static const char BugReporMsg[] =
2060  "\n********************\n\n"
2061  "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
2062  "Preprocessed source(s) and associated run script(s) are located at:";
2063 
2064 // When clang crashes, produce diagnostic information including the fully
2065 // preprocessed source file(s). Request that the developer attach the
2066 // diagnostic information to a bug report.
2068  Compilation &C, const Command &FailingCommand,
2069  StringRef AdditionalInformation, CompilationDiagnosticReport *Report) {
2070  if (C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2071  return;
2072 
2073  unsigned Level = 1;
2074  if (Arg *A = C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2075  Level = llvm::StringSwitch<unsigned>(A->getValue())
2076  .Case("off", 0)
2077  .Case("compiler", 1)
2078  .Case("all", 2)
2079  .Default(1);
2080  }
2081  if (!Level)
2082  return;
2083 
2084  // Don't try to generate diagnostics for dsymutil jobs.
2085  if (FailingCommand.getCreator().isDsymutilJob())
2086  return;
2087 
2088  bool IsLLD = false;
2089  TempFileList SavedTemps;
2090  if (FailingCommand.getCreator().isLinkJob()) {
2091  C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2092  if (!IsLLD || Level < 2)
2093  return;
2094 
2095  // If lld crashed, we will re-run the same command with the input it used
2096  // to have. In that case we should not remove temp files in
2097  // initCompilationForDiagnostics yet. They will be added back and removed
2098  // later.
2099  SavedTemps = std::move(C.getTempFiles());
2100  assert(!C.getTempFiles().size());
2101  }
2102 
2103  // Print the version of the compiler.
2104  PrintVersion(C, llvm::errs());
2105 
2106  // Suppress driver output and emit preprocessor output to temp file.
2107  CCGenDiagnostics = true;
2108 
2109  // Save the original job command(s).
2110  Command Cmd = FailingCommand;
2111 
2112  // Keep track of whether we produce any errors while trying to produce
2113  // preprocessed sources.
2114  DiagnosticErrorTrap Trap(Diags);
2115 
2116  // Suppress tool output.
2117  C.initCompilationForDiagnostics();
2118 
2119  // If lld failed, rerun it again with --reproduce.
2120  if (IsLLD) {
2121  const char *TmpName = CreateTempFile(C, "linker-crash", "tar");
2122  Command NewLLDInvocation = Cmd;
2123  llvm::opt::ArgStringList ArgList = NewLLDInvocation.getArguments();
2124  StringRef ReproduceOption =
2125  C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2126  ? "/reproduce:"
2127  : "--reproduce=";
2128  ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2129  NewLLDInvocation.replaceArguments(std::move(ArgList));
2130 
2131  // Redirect stdout/stderr to /dev/null.
2132  NewLLDInvocation.Execute({std::nullopt, {""}, {""}}, nullptr, nullptr);
2133  Diag(clang::diag::note_drv_command_failed_diag_msg) << BugReporMsg;
2134  Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2135  Diag(clang::diag::note_drv_command_failed_diag_msg)
2136  << "\n\n********************";
2137  if (Report)
2138  Report->TemporaryFiles.push_back(TmpName);
2139  return;
2140  }
2141 
2142  // Construct the list of inputs.
2143  InputList Inputs;
2144  BuildInputs(C.getDefaultToolChain(), C.getArgs(), Inputs);
2145 
2146  for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2147  bool IgnoreInput = false;
2148 
2149  // Ignore input from stdin or any inputs that cannot be preprocessed.
2150  // Check type first as not all linker inputs have a value.
2151  if (types::getPreprocessedType(it->first) == types::TY_INVALID) {
2152  IgnoreInput = true;
2153  } else if (!strcmp(it->second->getValue(), "-")) {
2154  Diag(clang::diag::note_drv_command_failed_diag_msg)
2155  << "Error generating preprocessed source(s) - "
2156  "ignoring input from stdin.";
2157  IgnoreInput = true;
2158  }
2159 
2160  if (IgnoreInput) {
2161  it = Inputs.erase(it);
2162  ie = Inputs.end();
2163  } else {
2164  ++it;
2165  }
2166  }
2167 
2168  if (Inputs.empty()) {
2169  Diag(clang::diag::note_drv_command_failed_diag_msg)
2170  << "Error generating preprocessed source(s) - "
2171  "no preprocessable inputs.";
2172  return;
2173  }
2174 
2175  // Don't attempt to generate preprocessed files if multiple -arch options are
2176  // used, unless they're all duplicates.
2177  llvm::StringSet<> ArchNames;
2178  for (const Arg *A : C.getArgs()) {
2179  if (A->getOption().matches(options::OPT_arch)) {
2180  StringRef ArchName = A->getValue();
2181  ArchNames.insert(ArchName);
2182  }
2183  }
2184  if (ArchNames.size() > 1) {
2185  Diag(clang::diag::note_drv_command_failed_diag_msg)
2186  << "Error generating preprocessed source(s) - cannot generate "
2187  "preprocessed source with multiple -arch options.";
2188  return;
2189  }
2190 
2191  // Construct the list of abstract actions to perform for this compilation. On
2192  // Darwin OSes this uses the driver-driver and builds universal actions.
2193  const ToolChain &TC = C.getDefaultToolChain();
2194  if (TC.getTriple().isOSBinFormatMachO())
2195  BuildUniversalActions(C, TC, Inputs);
2196  else
2197  BuildActions(C, C.getArgs(), Inputs, C.getActions());
2198 
2199  BuildJobs(C);
2200 
2201  // If there were errors building the compilation, quit now.
2202  if (Trap.hasErrorOccurred()) {
2203  Diag(clang::diag::note_drv_command_failed_diag_msg)
2204  << "Error generating preprocessed source(s).";
2205  return;
2206  }
2207 
2208  // Generate preprocessed output.
2209  SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
2210  C.ExecuteJobs(C.getJobs(), FailingCommands);
2211 
2212  // If any of the preprocessing commands failed, clean up and exit.
2213  if (!FailingCommands.empty()) {
2214  Diag(clang::diag::note_drv_command_failed_diag_msg)
2215  << "Error generating preprocessed source(s).";
2216  return;
2217  }
2218 
2219  const TempFileList &TempFiles = C.getTempFiles();
2220  if (TempFiles.empty()) {
2221  Diag(clang::diag::note_drv_command_failed_diag_msg)
2222  << "Error generating preprocessed source(s).";
2223  return;
2224  }
2225 
2226  Diag(clang::diag::note_drv_command_failed_diag_msg) << BugReporMsg;
2227 
2228  SmallString<128> VFS;
2229  SmallString<128> ReproCrashFilename;
2230  for (auto &TempFile : TempFiles) {
2231  Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile.first;
2232  if (Report)
2233  Report->TemporaryFiles.push_back(TempFile.first);
2234  if (ReproCrashFilename.empty()) {
2235  ReproCrashFilename = TempFile.first;
2236  llvm::sys::path::replace_extension(ReproCrashFilename, ".crash");
2237  }
2238  if (StringRef(TempFile.first).ends_with(".cache")) {
2239  // In some cases (modules) we'll dump extra data to help with reproducing
2240  // the crash into a directory next to the output.
2241  VFS = llvm::sys::path::filename(TempFile.first);
2242  llvm::sys::path::append(VFS, "vfs", "vfs.yaml");
2243  }
2244  }
2245 
2246  for (auto &TempFile : SavedTemps)
2247  C.addTempFile(TempFile.first);
2248 
2249  // Assume associated files are based off of the first temporary file.
2250  CrashReportInfo CrashInfo(TempFiles[0].first, VFS);
2251 
2252  llvm::SmallString<128> Script(CrashInfo.Filename);
2253  llvm::sys::path::replace_extension(Script, "sh");
2254  std::error_code EC;
2255  llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2256  llvm::sys::fs::FA_Write,
2257  llvm::sys::fs::OF_Text);
2258  if (EC) {
2259  Diag(clang::diag::note_drv_command_failed_diag_msg)
2260  << "Error generating run script: " << Script << " " << EC.message();
2261  } else {
2262  ScriptOS << "# Crash reproducer for " << getClangFullVersion() << "\n"
2263  << "# Driver args: ";
2264  printArgList(ScriptOS, C.getInputArgs());
2265  ScriptOS << "# Original command: ";
2266  Cmd.Print(ScriptOS, "\n", /*Quote=*/true);
2267  Cmd.Print(ScriptOS, "\n", /*Quote=*/true, &CrashInfo);
2268  if (!AdditionalInformation.empty())
2269  ScriptOS << "\n# Additional information: " << AdditionalInformation
2270  << "\n";
2271  if (Report)
2272  Report->TemporaryFiles.push_back(std::string(Script));
2273  Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2274  }
2275 
2276  // On darwin, provide information about the .crash diagnostic report.
2277  if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2278  SmallString<128> CrashDiagDir;
2279  if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2280  Diag(clang::diag::note_drv_command_failed_diag_msg)
2281  << ReproCrashFilename.str();
2282  } else { // Suggest a directory for the user to look for .crash files.
2283  llvm::sys::path::append(CrashDiagDir, Name);
2284  CrashDiagDir += "_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2285  Diag(clang::diag::note_drv_command_failed_diag_msg)
2286  << "Crash backtrace is located in";
2287  Diag(clang::diag::note_drv_command_failed_diag_msg)
2288  << CrashDiagDir.str();
2289  Diag(clang::diag::note_drv_command_failed_diag_msg)
2290  << "(choose the .crash file that corresponds to your crash)";
2291  }
2292  }
2293 
2294  Diag(clang::diag::note_drv_command_failed_diag_msg)
2295  << "\n\n********************";
2296 }
2297 
2298 void Driver::setUpResponseFiles(Compilation &C, Command &Cmd) {
2299  // Since commandLineFitsWithinSystemLimits() may underestimate system's
2300  // capacity if the tool does not support response files, there is a chance/
2301  // that things will just work without a response file, so we silently just
2302  // skip it.
2303  if (Cmd.getResponseFileSupport().ResponseKind ==
2305  llvm::sys::commandLineFitsWithinSystemLimits(Cmd.getExecutable(),
2306  Cmd.getArguments()))
2307  return;
2308 
2309  std::string TmpName = GetTemporaryPath("response", "txt");
2310  Cmd.setResponseFile(C.addTempFile(C.getArgs().MakeArgString(TmpName)));
2311 }
2312 
2314  Compilation &C,
2315  SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) {
2316  if (C.getArgs().hasArg(options::OPT_fdriver_only)) {
2317  if (C.getArgs().hasArg(options::OPT_v))
2318  C.getJobs().Print(llvm::errs(), "\n", true);
2319 
2320  C.ExecuteJobs(C.getJobs(), FailingCommands, /*LogOnly=*/true);
2321 
2322  // If there were errors building the compilation, quit now.
2323  if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2324  return 1;
2325 
2326  return 0;
2327  }
2328 
2329  // Just print if -### was present.
2330  if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2331  C.getJobs().Print(llvm::errs(), "\n", true);
2332  return Diags.hasErrorOccurred() ? 1 : 0;
2333  }
2334 
2335  // If there were errors building the compilation, quit now.
2336  if (Diags.hasErrorOccurred())
2337  return 1;
2338 
2339  // Set up response file names for each command, if necessary.
2340  for (auto &Job : C.getJobs())
2341  setUpResponseFiles(C, Job);
2342 
2343  C.ExecuteJobs(C.getJobs(), FailingCommands);
2344 
2345  // If the command succeeded, we are done.
2346  if (FailingCommands.empty())
2347  return 0;
2348 
2349  // Otherwise, remove result files and print extra information about abnormal
2350  // failures.
2351  int Res = 0;
2352  for (const auto &CmdPair : FailingCommands) {
2353  int CommandRes = CmdPair.first;
2354  const Command *FailingCommand = CmdPair.second;
2355 
2356  // Remove result files if we're not saving temps.
2357  if (!isSaveTempsEnabled()) {
2358  const JobAction *JA = cast<JobAction>(&FailingCommand->getSource());
2359  C.CleanupFileMap(C.getResultFiles(), JA, true);
2360 
2361  // Failure result files are valid unless we crashed.
2362  if (CommandRes < 0)
2363  C.CleanupFileMap(C.getFailureResultFiles(), JA, true);
2364  }
2365 
2366  // llvm/lib/Support/*/Signals.inc will exit with a special return code
2367  // for SIGPIPE. Do not print diagnostics for this case.
2368  if (CommandRes == EX_IOERR) {
2369  Res = CommandRes;
2370  continue;
2371  }
2372 
2373  // Print extra information about abnormal failures, if possible.
2374  //
2375  // This is ad-hoc, but we don't want to be excessively noisy. If the result
2376  // status was 1, assume the command failed normally. In particular, if it
2377  // was the compiler then assume it gave a reasonable error code. Failures
2378  // in other tools are less common, and they generally have worse
2379  // diagnostics, so always print the diagnostic there.
2380  const Tool &FailingTool = FailingCommand->getCreator();
2381 
2382  if (!FailingTool.hasGoodDiagnostics() || CommandRes != 1) {
2383  // FIXME: See FIXME above regarding result code interpretation.
2384  if (CommandRes < 0)
2385  Diag(clang::diag::err_drv_command_signalled)
2386  << FailingTool.getShortName();
2387  else
2388  Diag(clang::diag::err_drv_command_failed)
2389  << FailingTool.getShortName() << CommandRes;
2390  }
2391 
2392  auto CustomDiag = FailingCommand->getDiagForErrorCode(CommandRes);
2393  if (!CustomDiag.empty())
2394  Diag(clang::diag::note_drv_command_failed_diag_msg) << CustomDiag;
2395  }
2396  return Res;
2397 }
2398 
2399 void Driver::PrintHelp(bool ShowHidden) const {
2400  llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2401 
2402  std::string Usage = llvm::formatv("{0} [options] file...", Name).str();
2403  getOpts().printHelp(llvm::outs(), Usage.c_str(), DriverTitle.c_str(),
2404  ShowHidden, /*ShowAllAliases=*/false,
2405  VisibilityMask);
2406 }
2407 
2408 llvm::Triple Driver::MakeSYCLDeviceTriple(StringRef TargetArch) const {
2409  SmallVector<StringRef, 5> SYCLAlias = {
2410  "spir", "spir64", "spir64_fpga", "spir64_x86_64",
2411  "spir64_gen", "spirv32", "spirv64"};
2412  if (std::find(SYCLAlias.begin(), SYCLAlias.end(), TargetArch) !=
2413  SYCLAlias.end()) {
2414  llvm::Triple TT;
2415  TT.setArchName(TargetArch);
2416  TT.setVendor(llvm::Triple::UnknownVendor);
2417  TT.setOS(llvm::Triple::UnknownOS);
2418  return TT;
2419  }
2420  return llvm::Triple(TargetArch);
2421 }
2422 
2423 // Print the help from any of the given tools which are used for AOT
2424 // compilation for SYCL
2427  HelpArgs;
2428  // Populate the vector with the tools and help options
2429  if (Arg *A = C.getArgs().getLastArg(options::OPT_fsycl_help_EQ)) {
2430  StringRef AV(A->getValue());
2431  llvm::Triple T;
2432  if (AV == "gen" || AV == "all")
2433  HelpArgs.push_back(std::make_tuple(MakeSYCLDeviceTriple("spir64_gen"),
2434  "ocloc", "--help", ""));
2435  if (AV == "fpga" || AV == "all")
2436  HelpArgs.push_back(std::make_tuple(MakeSYCLDeviceTriple("spir64_fpga"),
2437  "aoc", "-help", "-sycl"));
2438  if (AV == "x86_64" || AV == "all")
2439  HelpArgs.push_back(std::make_tuple(MakeSYCLDeviceTriple("spir64_x86_64"),
2440  "opencl-aot", "--help", ""));
2441  if (HelpArgs.empty()) {
2442  C.getDriver().Diag(diag::err_drv_unsupported_option_argument)
2443  << A->getSpelling() << AV;
2444  return;
2445  }
2446  }
2447 
2448  // Go through the args and emit the help information for each.
2449  for (auto &HA : HelpArgs) {
2450  llvm::outs() << "Emitting help information for " << std::get<1>(HA) << '\n'
2451  << "Use triple of '" << std::get<0>(HA).normalize() <<
2452  "' to enable ahead of time compilation\n";
2453  // Flush out the buffer before calling the external tool.
2454  llvm::outs().flush();
2455  std::vector<StringRef> ToolArgs = {std::get<1>(HA), std::get<2>(HA),
2456  std::get<3>(HA)};
2457  SmallString<128> ExecPath(
2458  C.getDefaultToolChain().GetProgramPath(std::get<1>(HA).data()));
2459  // do not run the tools with -###.
2460  if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2461  llvm::errs() << "\"" << ExecPath << "\" \"" << ToolArgs[1] << "\"";
2462  if (!ToolArgs[2].empty())
2463  llvm::errs() << " \"" << ToolArgs[2] << "\"";
2464  llvm::errs() << "\n";
2465  continue;
2466  }
2467  auto ToolBinary = llvm::sys::findProgramByName(ExecPath);
2468  if (ToolBinary.getError()) {
2469  C.getDriver().Diag(diag::err_drv_command_failure) << ExecPath;
2470  continue;
2471  }
2472  // Run the Tool.
2473  llvm::sys::ExecuteAndWait(ToolBinary.get(), ToolArgs);
2474  }
2475 }
2476 
2477 void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
2478  if (IsFlangMode()) {
2479  OS << getClangToolFullVersion("flang-new") << '\n';
2480  } else {
2481  // FIXME: The following handlers should use a callback mechanism, we don't
2482  // know what the client would like to do.
2483  OS << getClangFullVersion() << '\n';
2484  }
2485  const ToolChain &TC = C.getDefaultToolChain();
2486  OS << "Target: " << TC.getTripleString() << '\n';
2487 
2488  // Print the threading model.
2489  if (Arg *A = C.getArgs().getLastArg(options::OPT_mthread_model)) {
2490  // Don't print if the ToolChain would have barfed on it already
2491  if (TC.isThreadModelSupported(A->getValue()))
2492  OS << "Thread model: " << A->getValue();
2493  } else
2494  OS << "Thread model: " << TC.getThreadModel();
2495  OS << '\n';
2496 
2497  // Print out the install directory.
2498  OS << "InstalledDir: " << Dir << '\n';
2499 
2500  // Print the build config if it's non-default.
2501  // Intended to help LLVM developers understand the configs of compilers
2502  // they're investigating.
2503  if (!llvm::cl::getCompilerBuildConfig().empty())
2504  llvm::cl::printBuildConfig(OS);
2505 
2506  // If configuration files were used, print their paths.
2507  for (auto ConfigFile : ConfigFiles)
2508  OS << "Configuration file: " << ConfigFile << '\n';
2509 }
2510 
2511 /// PrintDiagnosticCategories - Implement the --print-diagnostic-categories
2512 /// option.
2513 static void PrintDiagnosticCategories(raw_ostream &OS) {
2514  // Skip the empty category.
2515  for (unsigned i = 1, max = DiagnosticIDs::getNumberOfCategories(); i != max;
2516  ++i)
2517  OS << i << ',' << DiagnosticIDs::getCategoryNameFromID(i) << '\n';
2518 }
2519 
2520 void Driver::HandleAutocompletions(StringRef PassedFlags) const {
2521  if (PassedFlags == "")
2522  return;
2523  // Print out all options that start with a given argument. This is used for
2524  // shell autocompletion.
2525  std::vector<std::string> SuggestedCompletions;
2526  std::vector<std::string> Flags;
2527 
2529 
2530  // Make sure that Flang-only options don't pollute the Clang output
2531  // TODO: Make sure that Clang-only options don't pollute Flang output
2532  if (IsFlangMode())
2533  VisibilityMask = llvm::opt::Visibility(options::FlangOption);
2534 
2535  // Distinguish "--autocomplete=-someflag" and "--autocomplete=-someflag,"
2536  // because the latter indicates that the user put space before pushing tab
2537  // which should end up in a file completion.
2538  const bool HasSpace = PassedFlags.ends_with(",");
2539 
2540  // Parse PassedFlags by "," as all the command-line flags are passed to this
2541  // function separated by ","
2542  StringRef TargetFlags = PassedFlags;
2543  while (TargetFlags != "") {
2544  StringRef CurFlag;
2545  std::tie(CurFlag, TargetFlags) = TargetFlags.split(",");
2546  Flags.push_back(std::string(CurFlag));
2547  }
2548 
2549  // We want to show cc1-only options only when clang is invoked with -cc1 or
2550  // -Xclang.
2551  if (llvm::is_contained(Flags, "-Xclang") || llvm::is_contained(Flags, "-cc1"))
2552  VisibilityMask = llvm::opt::Visibility(options::CC1Option);
2553 
2554  const llvm::opt::OptTable &Opts = getOpts();
2555  StringRef Cur;
2556  Cur = Flags.at(Flags.size() - 1);
2557  StringRef Prev;
2558  if (Flags.size() >= 2) {
2559  Prev = Flags.at(Flags.size() - 2);
2560  SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2561  }
2562 
2563  if (SuggestedCompletions.empty())
2564  SuggestedCompletions = Opts.suggestValueCompletions(Cur, "");
2565 
2566  // If Flags were empty, it means the user typed `clang [tab]` where we should
2567  // list all possible flags. If there was no value completion and the user
2568  // pressed tab after a space, we should fall back to a file completion.
2569  // We're printing a newline to be consistent with what we print at the end of
2570  // this function.
2571  if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2572  llvm::outs() << '\n';
2573  return;
2574  }
2575 
2576  // When flag ends with '=' and there was no value completion, return empty
2577  // string and fall back to the file autocompletion.
2578  if (SuggestedCompletions.empty() && !Cur.ends_with("=")) {
2579  // If the flag is in the form of "--autocomplete=-foo",
2580  // we were requested to print out all option names that start with "-foo".
2581  // For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only".
2582  SuggestedCompletions = Opts.findByPrefix(
2583  Cur, VisibilityMask,
2584  /*DisableFlags=*/options::Unsupported | options::Ignored);
2585 
2586  // We have to query the -W flags manually as they're not in the OptTable.
2587  // TODO: Find a good way to add them to OptTable instead and them remove
2588  // this code.
2589  for (StringRef S : DiagnosticIDs::getDiagnosticFlags())
2590  if (S.starts_with(Cur))
2591  SuggestedCompletions.push_back(std::string(S));
2592  }
2593 
2594  // Sort the autocomplete candidates so that shells print them out in a
2595  // deterministic order. We could sort in any way, but we chose
2596  // case-insensitive sorting for consistency with the -help option
2597  // which prints out options in the case-insensitive alphabetical order.
2598  llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2599  if (int X = A.compare_insensitive(B))
2600  return X < 0;
2601  return A.compare(B) > 0;
2602  });
2603 
2604  llvm::outs() << llvm::join(SuggestedCompletions, "\n") << '\n';
2605 }
2606 
2608  // The order these options are handled in gcc is all over the place, but we
2609  // don't expect inconsistencies w.r.t. that to matter in practice.
2610 
2611  if (C.getArgs().hasArg(options::OPT_dumpmachine)) {
2612  llvm::outs() << C.getDefaultToolChain().getTripleString() << '\n';
2613  return false;
2614  }
2615 
2616  if (C.getArgs().hasArg(options::OPT_dumpversion)) {
2617  // Since -dumpversion is only implemented for pedantic GCC compatibility, we
2618  // return an answer which matches our definition of __VERSION__.
2619  llvm::outs() << CLANG_VERSION_STRING << "\n";
2620  return false;
2621  }
2622 
2623  if (C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2624  PrintDiagnosticCategories(llvm::outs());
2625  return false;
2626  }
2627 
2628  if (C.getArgs().hasArg(options::OPT_help) ||
2629  C.getArgs().hasArg(options::OPT__help_hidden)) {
2630  PrintHelp(C.getArgs().hasArg(options::OPT__help_hidden));
2631  return false;
2632  }
2633 
2634  if (C.getArgs().hasArg(options::OPT_fsycl_help_EQ)) {
2635  PrintSYCLToolHelp(C);
2636  return false;
2637  }
2638 
2639  if (C.getArgs().hasArg(options::OPT__version)) {
2640  // Follow gcc behavior and use stdout for --version and stderr for -v.
2641  PrintVersion(C, llvm::outs());
2642  return false;
2643  }
2644 
2645  if (C.getArgs().hasArg(options::OPT_v) ||
2646  C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2647  C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2648  C.getArgs().hasArg(options::OPT_print_supported_extensions)) {
2649  PrintVersion(C, llvm::errs());
2650  SuppressMissingInputWarning = true;
2651  }
2652 
2653  if (C.getArgs().hasArg(options::OPT_v)) {
2654  if (!SystemConfigDir.empty())
2655  llvm::errs() << "System configuration file directory: "
2656  << SystemConfigDir << "\n";
2657  if (!UserConfigDir.empty())
2658  llvm::errs() << "User configuration file directory: "
2659  << UserConfigDir << "\n";
2660  }
2661 
2662  const ToolChain &TC = C.getDefaultToolChain();
2663 
2664  if (C.getArgs().hasArg(options::OPT_v))
2665  TC.printVerboseInfo(llvm::errs());
2666 
2667  if (C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2668  llvm::outs() << ResourceDir << '\n';
2669  return false;
2670  }
2671 
2672  if (C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2673  llvm::outs() << "programs: =";
2674  bool separator = false;
2675  // Print -B and COMPILER_PATH.
2676  for (const std::string &Path : PrefixDirs) {
2677  if (separator)
2678  llvm::outs() << llvm::sys::EnvPathSeparator;
2679  llvm::outs() << Path;
2680  separator = true;
2681  }
2682  for (const std::string &Path : TC.getProgramPaths()) {
2683  if (separator)
2684  llvm::outs() << llvm::sys::EnvPathSeparator;
2685  llvm::outs() << Path;
2686  separator = true;
2687  }
2688  llvm::outs() << "\n";
2689  llvm::outs() << "libraries: =" << ResourceDir;
2690 
2691  StringRef sysroot = C.getSysRoot();
2692 
2693  for (const std::string &Path : TC.getFilePaths()) {
2694  // Always print a separator. ResourceDir was the first item shown.
2695  llvm::outs() << llvm::sys::EnvPathSeparator;
2696  // Interpretation of leading '=' is needed only for NetBSD.
2697  if (Path[0] == '=')
2698  llvm::outs() << sysroot << Path.substr(1);
2699  else
2700  llvm::outs() << Path;
2701  }
2702  llvm::outs() << "\n";
2703  return false;
2704  }
2705 
2706  if (C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2707  llvm::outs() << GetStdModuleManifestPath(C, C.getDefaultToolChain())
2708  << '\n';
2709  return false;
2710  }
2711 
2712  if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2713  if (std::optional<std::string> RuntimePath = TC.getRuntimePath())
2714  llvm::outs() << *RuntimePath << '\n';
2715  else
2716  llvm::outs() << TC.getCompilerRTPath() << '\n';
2717  return false;
2718  }
2719 
2720  if (C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2721  std::vector<std::string> Flags = DiagnosticIDs::getDiagnosticFlags();
2722  for (std::size_t I = 0; I != Flags.size(); I += 2)
2723  llvm::outs() << " " << Flags[I] << "\n " << Flags[I + 1] << "\n\n";
2724  return false;
2725  }
2726 
2727  // FIXME: The following handlers should use a callback mechanism, we don't
2728  // know what the client would like to do.
2729  if (Arg *A = C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2730  llvm::outs() << GetFilePath(A->getValue(), TC) << "\n";
2731  return false;
2732  }
2733 
2734  if (Arg *A = C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2735  StringRef ProgName = A->getValue();
2736 
2737  // Null program name cannot have a path.
2738  if (! ProgName.empty())
2739  llvm::outs() << GetProgramPath(ProgName, TC);
2740 
2741  llvm::outs() << "\n";
2742  return false;
2743  }
2744 
2745  if (Arg *A = C.getArgs().getLastArg(options::OPT_autocomplete)) {
2746  StringRef PassedFlags = A->getValue();
2747  HandleAutocompletions(PassedFlags);
2748  return false;
2749  }
2750 
2751  if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2752  ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(C.getArgs());
2753  const llvm::Triple Triple(TC.ComputeEffectiveClangTriple(C.getArgs()));
2754  RegisterEffectiveTriple TripleRAII(TC, Triple);
2755  switch (RLT) {
2757  llvm::outs() << TC.getCompilerRT(C.getArgs(), "builtins") << "\n";
2758  break;
2759  case ToolChain::RLT_Libgcc:
2760  llvm::outs() << GetFilePath("libgcc.a", TC) << "\n";
2761  break;
2762  }
2763  return false;
2764  }
2765 
2766  if (C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2767  for (const Multilib &Multilib : TC.getMultilibs())
2768  llvm::outs() << Multilib << "\n";
2769  return false;
2770  }
2771 
2772  if (C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2773  Multilib::flags_list ArgFlags = TC.getMultilibFlags(C.getArgs());
2774  llvm::StringSet<> ExpandedFlags = TC.getMultilibs().expandFlags(ArgFlags);
2775  std::set<llvm::StringRef> SortedFlags;
2776  for (const auto &FlagEntry : ExpandedFlags)
2777  SortedFlags.insert(FlagEntry.getKey());
2778  for (auto Flag : SortedFlags)
2779  llvm::outs() << Flag << '\n';
2780  return false;
2781  }
2782 
2783  if (C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2784  for (const Multilib &Multilib : TC.getSelectedMultilibs()) {
2785  if (Multilib.gccSuffix().empty())
2786  llvm::outs() << ".\n";
2787  else {
2788  StringRef Suffix(Multilib.gccSuffix());
2789  assert(Suffix.front() == '/');
2790  llvm::outs() << Suffix.substr(1) << "\n";
2791  }
2792  }
2793  return false;
2794  }
2795 
2796  if (C.getArgs().hasArg(options::OPT_print_target_triple)) {
2797  llvm::outs() << TC.getTripleString() << "\n";
2798  return false;
2799  }
2800 
2801  if (C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2802  const llvm::Triple Triple(TC.ComputeEffectiveClangTriple(C.getArgs()));
2803  llvm::outs() << Triple.getTriple() << "\n";
2804  return false;
2805  }
2806 
2807  if (C.getArgs().hasArg(options::OPT_print_targets)) {
2808  llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2809  return false;
2810  }
2811 
2812  return true;
2813 }
2814 
2815 enum {
2819 };
2820 
2821 // Display an action graph human-readably. Action A is the "sink" node
2822 // and latest-occuring action. Traversal is in pre-order, visiting the
2823 // inputs to each action before printing the action itself.
2824 static unsigned PrintActions1(const Compilation &C, Action *A,
2825  std::map<Action *, unsigned> &Ids,
2826  Twine Indent = {}, int Kind = TopLevelAction) {
2827  if (Ids.count(A)) // A was already visited.
2828  return Ids[A];
2829 
2830  std::string str;
2831  llvm::raw_string_ostream os(str);
2832 
2833  auto getSibIndent = [](int K) -> Twine {
2834  return (K == HeadSibAction) ? " " : (K == OtherSibAction) ? "| " : "";
2835  };
2836 
2837  Twine SibIndent = Indent + getSibIndent(Kind);
2838  int SibKind = HeadSibAction;
2839  os << Action::getClassName(A->getKind()) << ", ";
2840  if (InputAction *IA = dyn_cast<InputAction>(A)) {
2841  os << "\"" << IA->getInputArg().getValue() << "\"";
2842  } else if (BindArchAction *BIA = dyn_cast<BindArchAction>(A)) {
2843  os << '"' << BIA->getArchName() << '"' << ", {"
2844  << PrintActions1(C, *BIA->input_begin(), Ids, SibIndent, SibKind) << "}";
2845  } else if (OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2846  bool IsFirst = true;
2847  OA->doOnEachDependence(
2848  [&](Action *A, const ToolChain *TC, const char *BoundArch) {
2849  assert(TC && "Unknown host toolchain");
2850  // E.g. for two CUDA device dependences whose bound arch is sm_20 and
2851  // sm_35 this will generate:
2852  // "cuda-device" (nvptx64-nvidia-cuda:sm_20) {#ID}, "cuda-device"
2853  // (nvptx64-nvidia-cuda:sm_35) {#ID}
2854  if (!IsFirst)
2855  os << ", ";
2856  os << '"';
2857  os << A->getOffloadingKindPrefix();
2858  os << " (";
2859  os << TC->getTriple().normalize();
2860  if (BoundArch)
2861  os << ":" << BoundArch;
2862  os << ")";
2863  os << '"';
2864  os << " {" << PrintActions1(C, A, Ids, SibIndent, SibKind) << "}";
2865  IsFirst = false;
2866  SibKind = OtherSibAction;
2867  });
2868  } else {
2869  const ActionList *AL = &A->getInputs();
2870 
2871  if (AL->size()) {
2872  const char *Prefix = "{";
2873  for (Action *PreRequisite : *AL) {
2874  os << Prefix << PrintActions1(C, PreRequisite, Ids, SibIndent, SibKind);
2875  Prefix = ", ";
2876  SibKind = OtherSibAction;
2877  }
2878  os << "}";
2879  } else
2880  os << "{}";
2881  }
2882 
2883  // Append offload info for all options other than the offloading action
2884  // itself (e.g. (cuda-device, sm_20) or (cuda-host)).
2885  std::string offload_str;
2886  llvm::raw_string_ostream offload_os(offload_str);
2887  if (!isa<OffloadAction>(A)) {
2888  auto S = A->getOffloadingKindPrefix();
2889  if (!S.empty()) {
2890  offload_os << ", (" << S;
2891  if (A->getOffloadingArch())
2892  offload_os << ", " << A->getOffloadingArch();
2893  offload_os << ")";
2894  }
2895  }
2896 
2897  auto getSelfIndent = [](int K) -> Twine {
2898  return (K == HeadSibAction) ? "+- " : (K == OtherSibAction) ? "|- " : "";
2899  };
2900 
2901  unsigned Id = Ids.size();
2902  Ids[A] = Id;
2903  llvm::errs() << Indent + getSelfIndent(Kind) << Id << ": " << os.str() << ", "
2904  << types::getTypeName(A->getType()) << offload_os.str() << "\n";
2905 
2906  return Id;
2907 }
2908 
2909 // Print the action graphs in a compilation C.
2910 // For example "clang -c file1.c file2.c" is composed of two subgraphs.
2911 void Driver::PrintActions(const Compilation &C) const {
2912  std::map<Action *, unsigned> Ids;
2913  for (Action *A : C.getActions())
2914  PrintActions1(C, A, Ids);
2915 }
2916 
2917 /// Check whether the given input tree contains any compilation or
2918 /// assembly actions.
2920  if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2921  isa<AssembleJobAction>(A))
2922  return true;
2923 
2924  return llvm::any_of(A->inputs(), ContainsCompileOrAssembleAction);
2925 }
2926 
2928  const InputList &BAInputs) const {
2929  DerivedArgList &Args = C.getArgs();
2930  ActionList &Actions = C.getActions();
2931  llvm::PrettyStackTraceString CrashInfo("Building universal build actions");
2932  // Collect the list of architectures. Duplicates are allowed, but should only
2933  // be handled once (in the order seen).
2934  llvm::StringSet<> ArchNames;
2936  for (Arg *A : Args) {
2937  if (A->getOption().matches(options::OPT_arch)) {
2938  // Validate the option here; we don't save the type here because its
2939  // particular spelling may participate in other driver choices.
2940  llvm::Triple::ArchType Arch =
2942  if (Arch == llvm::Triple::UnknownArch) {
2943  Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2944  continue;
2945  }
2946 
2947  A->claim();
2948  if (ArchNames.insert(A->getValue()).second)
2949  Archs.push_back(A->getValue());
2950  }
2951  }
2952 
2953  // When there is no explicit arch for this platform, make sure we still bind
2954  // the architecture (to the default) so that -Xarch_ is handled correctly.
2955  if (!Archs.size())
2956  Archs.push_back(Args.MakeArgString(TC.getDefaultUniversalArchName()));
2957 
2958  ActionList SingleActions;
2959  BuildActions(C, Args, BAInputs, SingleActions);
2960 
2961  // Add in arch bindings for every top level action, as well as lipo and
2962  // dsymutil steps if needed.
2963  for (Action* Act : SingleActions) {
2964  // Make sure we can lipo this kind of output. If not (and it is an actual
2965  // output) then we disallow, since we can't create an output file with the
2966  // right name without overwriting it. We could remove this oddity by just
2967  // changing the output names to include the arch, which would also fix
2968  // -save-temps. Compatibility wins for now.
2969 
2970  if (Archs.size() > 1 && !types::canLipoType(Act->getType()))
2971  Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2972  << types::getTypeName(Act->getType());
2973 
2974  ActionList Inputs;
2975  for (unsigned i = 0, e = Archs.size(); i != e; ++i)
2976  Inputs.push_back(C.MakeAction<BindArchAction>(Act, Archs[i]));
2977 
2978  // Lipo if necessary, we do it this way because we need to set the arch flag
2979  // so that -Xarch_ gets overwritten.
2980  if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2981  Actions.append(Inputs.begin(), Inputs.end());
2982  else
2983  Actions.push_back(C.MakeAction<LipoJobAction>(Inputs, Act->getType()));
2984 
2985  // Handle debug info queries.
2986  Arg *A = Args.getLastArg(options::OPT_g_Group);
2987  bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2988  !A->getOption().matches(options::OPT_gstabs);
2989  if ((enablesDebugInfo || willEmitRemarks(Args)) &&
2990  ContainsCompileOrAssembleAction(Actions.back())) {
2991 
2992  // Add a 'dsymutil' step if necessary, when debug info is enabled and we
2993  // have a compile input. We need to run 'dsymutil' ourselves in such cases
2994  // because the debug info will refer to a temporary object file which
2995  // will be removed at the end of the compilation process.
2996  if (Act->getType() == types::TY_Image) {
2997  ActionList Inputs;
2998  Inputs.push_back(Actions.back());
2999  Actions.pop_back();
3000  Actions.push_back(
3001  C.MakeAction<DsymutilJobAction>(Inputs, types::TY_dSYM));
3002  }
3003 
3004  // Verify the debug info output.
3005  if (Args.hasArg(options::OPT_verify_debug_info)) {
3006  Action* LastAction = Actions.back();
3007  Actions.pop_back();
3008  Actions.push_back(C.MakeAction<VerifyDebugInfoJobAction>(
3009  LastAction, types::TY_Nothing));
3010  }
3011  }
3012  }
3013 }
3014 
3015 bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value,
3016  types::ID Ty, bool TypoCorrect) const {
3017  if (!getCheckInputsExist())
3018  return true;
3019 
3020  // stdin always exists.
3021  if (Value == "-")
3022  return true;
3023 
3024  // If it's a header to be found in the system or user search path, then defer
3025  // complaints about its absence until those searches can be done. When we
3026  // are definitely processing headers for C++20 header units, extend this to
3027  // allow the user to put "-fmodule-header -xc++-header vector" for example.
3028  if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
3029  (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3030  return true;
3031 
3032  if (getVFS().exists(Value))
3033  return true;
3034 
3035  if (TypoCorrect) {
3036  // Check if the filename is a typo for an option flag. OptTable thinks
3037  // that all args that are not known options and that start with / are
3038  // filenames, but e.g. `/diagnostic:caret` is more likely a typo for
3039  // the option `/diagnostics:caret` than a reference to a file in the root
3040  // directory.
3041  std::string Nearest;
3042  if (getOpts().findNearest(Value, Nearest, getOptionVisibilityMask()) <= 1) {
3043  Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3044  << Value << Nearest;
3045  return false;
3046  }
3047  }
3048 
3049  // In CL mode, don't error on apparently non-existent linker inputs, because
3050  // they can be influenced by linker flags the clang driver might not
3051  // understand.
3052  // Examples:
3053  // - `clang-cl main.cc ole32.lib` in a non-MSVC shell will make the driver
3054  // module look for an MSVC installation in the registry. (We could ask
3055  // the MSVCToolChain object if it can find `ole32.lib`, but the logic to
3056  // look in the registry might move into lld-link in the future so that
3057  // lld-link invocations in non-MSVC shells just work too.)
3058  // - `clang-cl ... /link ...` can pass arbitrary flags to the linker,
3059  // including /libpath:, which is used to find .lib and .obj files.
3060  // So do not diagnose this on the driver level. Rely on the linker diagnosing
3061  // it. (If we don't end up invoking the linker, this means we'll emit a
3062  // "'linker' input unused [-Wunused-command-line-argument]" warning instead
3063  // of an error.)
3064  //
3065  // Only do this skip after the typo correction step above. `/Brepo` is treated
3066  // as TY_Object, but it's clearly a typo for `/Brepro`. It seems fine to emit
3067  // an error if we have a flag that's within an edit distance of 1 from a
3068  // flag. (Users can use `-Wl,` or `/linker` to launder the flag past the
3069  // driver in the unlikely case they run into this.)
3070  //
3071  // Don't do this for inputs that start with a '/', else we'd pass options
3072  // like /libpath: through to the linker silently.
3073  //
3074  // Emitting an error for linker inputs can also cause incorrect diagnostics
3075  // with the gcc driver. The command
3076  // clang -fuse-ld=lld -Wl,--chroot,some/dir /file.o
3077  // will make lld look for some/dir/file.o, while we will diagnose here that
3078  // `/file.o` does not exist. However, configure scripts check if
3079  // `clang /GR-` compiles without error to see if the compiler is cl.exe,
3080  // so we can't downgrade diagnostics for `/GR-` from an error to a warning
3081  // in cc mode. (We can in cl mode because cl.exe itself only warns on
3082  // unknown flags.)
3083  if (IsCLMode() && Ty == types::TY_Object && !Value.starts_with("/"))
3084  return true;
3085 
3086  Diag(clang::diag::err_drv_no_such_file) << Value;
3087  return false;
3088 }
3089 
3090 // Get the C++20 Header Unit type corresponding to the input type.
3092  switch (HM) {
3093  case HeaderMode_User:
3094  return types::TY_CXXUHeader;
3095  case HeaderMode_System:
3096  return types::TY_CXXSHeader;
3097  case HeaderMode_Default:
3098  break;
3099  case HeaderMode_None:
3100  llvm_unreachable("should not be called in this case");
3101  }
3102  return types::TY_CXXHUHeader;
3103 }
3104 
3105 // Construct a the list of inputs and their types.
3106 void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
3107  InputList &Inputs) const {
3108  const llvm::opt::OptTable &Opts = getOpts();
3109  // Track the current user specified (-x) input. We also explicitly track the
3110  // argument used to set the type; we only want to claim the type when we
3111  // actually use it, so we warn about unused -x arguments.
3112  types::ID InputType = types::TY_Nothing;
3113  Arg *InputTypeArg = nullptr;
3114  bool IsSYCL =
3115  Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) ||
3116  Args.hasArg(options::OPT_fsycl_device_only);
3117 
3118  // The last /TC or /TP option sets the input type to C or C++ globally.
3119  if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3120  options::OPT__SLASH_TP)) {
3121  InputTypeArg = TCTP;
3122  InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) && !IsSYCL
3123  ? types::TY_C
3124  : types::TY_CXX;
3125 
3126  Arg *Previous = nullptr;
3127  bool ShowNote = false;
3128  for (Arg *A :
3129  Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3130  if (Previous) {
3131  Diag(clang::diag::warn_drv_overriding_option)
3132  << Previous->getSpelling() << A->getSpelling();
3133  ShowNote = true;
3134  }
3135  Previous = A;
3136  }
3137  if (ShowNote)
3138  Diag(clang::diag::note_drv_t_option_is_global);
3139  }
3140 
3141  // Warn -x after last input file has no effect
3142  {
3143  Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3144  Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3145  if (LastXArg && LastInputArg &&
3146  LastInputArg->getIndex() < LastXArg->getIndex())
3147  Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3148  }
3149 
3150  for (Arg *A : Args) {
3151  if (A->getOption().getKind() == Option::InputClass) {
3152  const char *Value = A->getValue();
3154 
3155  // Infer the input type if necessary.
3156  if (InputType == types::TY_Nothing) {
3157  // If there was an explicit arg for this, claim it.
3158  if (InputTypeArg)
3159  InputTypeArg->claim();
3160 
3161  types::ID CType = types::TY_C;
3162  // For SYCL, all source file inputs are considered C++.
3163  if (IsSYCL)
3164  CType = types::TY_CXX;
3165 
3166  // stdin must be handled specially.
3167  if (memcmp(Value, "-", 2) == 0) {
3168  if (IsFlangMode()) {
3169  Ty = types::TY_Fortran;
3170  } else if (IsDXCMode()) {
3171  Ty = types::TY_HLSL;
3172  } else {
3173  // If running with -E, treat as a C input (this changes the
3174  // builtin macros, for example). This may be overridden by -ObjC
3175  // below.
3176  //
3177  // Otherwise emit an error but still use a valid type to avoid
3178  // spurious errors (e.g., no inputs).
3179  assert(!CCGenDiagnostics && "stdin produces no crash reproducer");
3180  if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP())
3181  Diag(IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3182  : clang::diag::err_drv_unknown_stdin_type);
3183  Ty = types::TY_C;
3184  }
3185  } else {
3186  // Otherwise lookup by extension.
3187  // Fallback is C if invoked as C preprocessor, C++ if invoked with
3188  // clang-cl /E, or Object otherwise.
3189  // We use a host hook here because Darwin at least has its own
3190  // idea of what .s is.
3191  if (const char *Ext = strrchr(Value, '.'))
3192  Ty = TC.LookupTypeForExtension(Ext + 1);
3193 
3194  // For SYCL, convert C-type sources to C++-type sources.
3195  if (IsSYCL) {
3196  types::ID OldTy = Ty;
3197  switch (Ty) {
3198  case types::TY_C:
3199  Ty = types::TY_CXX;
3200  break;
3201  case types::TY_CHeader:
3202  Ty = types::TY_CXXHeader;
3203  break;
3204  case types::TY_PP_C:
3205  Ty = types::TY_PP_CXX;
3206  break;
3207  case types::TY_PP_CHeader:
3208  Ty = types::TY_PP_CXXHeader;
3209  break;
3210  default:
3211  break;
3212  }
3213  if (OldTy != Ty) {
3214  Diag(clang::diag::warn_drv_fsycl_with_c_type)
3215  << getTypeName(OldTy) << getTypeName(Ty);
3216  }
3217  }
3218 
3219  if (Ty == types::TY_INVALID) {
3220  if (IsCLMode() && (Args.hasArgNoClaim(options::OPT_E) || CCGenDiagnostics))
3221  Ty = types::TY_CXX;
3222  else if (CCCIsCPP() || CCGenDiagnostics)
3223  Ty = CType;
3224  else
3225  Ty = types::TY_Object;
3226  }
3227 
3228  // If the driver is invoked as C++ compiler (like clang++ or c++) it
3229  // should autodetect some input files as C++ for g++ compatibility.
3230  if (CCCIsCXX()) {
3231  types::ID OldTy = Ty;
3233 
3234  // Do not complain about foo.h, when we are known to be processing
3235  // it as a C++20 header unit.
3236  if (Ty != OldTy && !(OldTy == types::TY_CHeader && hasHeaderMode()))
3237  Diag(clang::diag::warn_drv_treating_input_as_cxx)
3238  << getTypeName(OldTy) << getTypeName(Ty);
3239  }
3240 
3241  // If running with -fthinlto-index=, extensions that normally identify
3242  // native object files actually identify LLVM bitcode files.
3243  if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3244  Ty == types::TY_Object)
3245  Ty = types::TY_LLVM_BC;
3246  }
3247 
3248  // -ObjC and -ObjC++ override the default language, but only for "source
3249  // files". We just treat everything that isn't a linker input as a
3250  // source file.
3251  //
3252  // FIXME: Clean this up if we move the phase sequence into the type.
3253  if (Ty != types::TY_Object) {
3254  if (Args.hasArg(options::OPT_ObjC))
3255  Ty = types::TY_ObjC;
3256  else if (Args.hasArg(options::OPT_ObjCXX))
3257  Ty = types::TY_ObjCXX;
3258  }
3259 
3260  // Disambiguate headers that are meant to be header units from those
3261  // intended to be PCH. Avoid missing '.h' cases that are counted as
3262  // C headers by default - we know we are in C++ mode and we do not
3263  // want to issue a complaint about compiling things in the wrong mode.
3264  if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3265  hasHeaderMode())
3266  Ty = CXXHeaderUnitType(CXX20HeaderType);
3267  } else {
3268  assert(InputTypeArg && "InputType set w/o InputTypeArg");
3269  if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3270  // If emulating cl.exe, make sure that /TC and /TP don't affect input
3271  // object files.
3272  const char *Ext = strrchr(Value, '.');
3273  if (Ext && TC.LookupTypeForExtension(Ext + 1) == types::TY_Object)
3274  Ty = types::TY_Object;
3275  }
3276  if (Ty == types::TY_INVALID) {
3277  Ty = InputType;
3278  InputTypeArg->claim();
3279  }
3280  }
3281 
3282  if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3283  Args.hasArgNoClaim(options::OPT_hipstdpar))
3284  Ty = types::TY_HIP;
3285 
3286  if (DiagnoseInputExistence(Args, Value, Ty, /*TypoCorrect=*/true))
3287  Inputs.push_back(std::make_pair(Ty, A));
3288 
3289  } else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3290  StringRef Value = A->getValue();
3291  if (DiagnoseInputExistence(Args, Value, types::TY_C,
3292  /*TypoCorrect=*/false)) {
3293  Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
3294  Inputs.push_back(
3295  std::make_pair(IsSYCL ? types::TY_CXX : types::TY_C, InputArg));
3296  }
3297  A->claim();
3298  } else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3299  StringRef Value = A->getValue();
3300  if (DiagnoseInputExistence(Args, Value, types::TY_CXX,
3301  /*TypoCorrect=*/false)) {
3302  Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
3303  Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3304  }
3305  A->claim();
3306  } else if (A->getOption().hasFlag(options::LinkerInput)) {
3307  // Just treat as object type, we could make a special type for this if
3308  // necessary.
3309  Inputs.push_back(std::make_pair(types::TY_Object, A));
3310 
3311  } else if (A->getOption().matches(options::OPT_x)) {
3312  InputTypeArg = A;
3313  InputType = types::lookupTypeForTypeSpecifier(A->getValue());
3314  A->claim();
3315 
3316  // Follow gcc behavior and treat as linker input for invalid -x
3317  // options. Its not clear why we shouldn't just revert to unknown; but
3318  // this isn't very important, we might as well be bug compatible.
3319  if (!InputType) {
3320  Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3321  InputType = types::TY_Object;
3322  }
3323  // Emit an error if c-compilation is forced in -fsycl mode
3324  if (IsSYCL && (InputType == types::TY_C || InputType == types::TY_PP_C ||
3325  InputType == types::TY_CHeader))
3326  Diag(clang::diag::err_drv_fsycl_with_c_type) << A->getAsString(Args);
3327 
3328  // If the user has put -fmodule-header{,=} then we treat C++ headers as
3329  // header unit inputs. So we 'promote' -xc++-header appropriately.
3330  if (InputType == types::TY_CXXHeader && hasHeaderMode())
3331  InputType = CXXHeaderUnitType(CXX20HeaderType);
3332  } else if (A->getOption().getID() == options::OPT_U) {
3333  assert(A->getNumValues() == 1 && "The /U option has one value.");
3334  StringRef Val = A->getValue(0);
3335  if (Val.find_first_of("/\\") != StringRef::npos) {
3336  // Warn about e.g. "/Users/me/myfile.c".
3337  Diag(diag::warn_slash_u_filename) << Val;
3338  Diag(diag::note_use_dashdash);
3339  }
3340  }
3341  }
3342  if (CCCIsCPP() && Inputs.empty()) {
3343  // If called as standalone preprocessor, stdin is processed
3344  // if no other input is present.
3345  Arg *A = MakeInputArg(Args, Opts, "-");
3346  Inputs.push_back(std::make_pair(types::TY_C, A));
3347  }
3348 }
3349 
3350 static bool runBundler(const SmallVectorImpl<StringRef> &InputArgs,
3351  Compilation &C) {
3352  // Find bundler.
3353  StringRef ExecPath(C.getArgs().MakeArgString(C.getDriver().Dir));
3354  llvm::ErrorOr<std::string> BundlerBinary =
3355  llvm::sys::findProgramByName("clang-offload-bundler", ExecPath);
3356  SmallVector<StringRef, 6> BundlerArgs;
3357  BundlerArgs.push_back(BundlerBinary.getError() ? "clang-offload-bundler"
3358  : BundlerBinary.get().c_str());
3359  BundlerArgs.append(InputArgs);
3360  // Since this is run in real time and not in the toolchain, output the
3361  // command line if requested.
3362  bool OutputOnly = C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
3363  if (C.getArgs().hasArg(options::OPT_v) || OutputOnly) {
3364  for (StringRef A : BundlerArgs)
3365  if (OutputOnly)
3366  llvm::errs() << "\"" << A << "\" ";
3367  else
3368  llvm::errs() << A << " ";
3369  llvm::errs() << '\n';
3370  }
3371  if (BundlerBinary.getError())
3372  return false;
3373 
3374  return !llvm::sys::ExecuteAndWait(BundlerBinary.get(), BundlerArgs);
3375 }
3376 
3377 static bool hasFPGABinary(Compilation &C, std::string Object, types::ID Type) {
3378  assert(types::isFPGA(Type) && "unexpected Type for FPGA binary check");
3379  // Do not do the check if the file doesn't exist
3380  if (!llvm::sys::fs::exists(Object))
3381  return false;
3382 
3383  // Only static archives are valid FPGA Binaries for unbundling.
3384  if (!isStaticArchiveFile(Object))
3385  return false;
3386 
3387  // Temporary names for the output.
3388  llvm::Triple TT;
3389  TT.setArchName(types::getTypeName(Type));
3390  TT.setVendorName("intel");
3391  TT.setOS(llvm::Triple::UnknownOS);
3392 
3393  // Checking uses -check-section option with the input file, no output
3394  // file and the target triple being looked for.
3395  const char *Targets =
3396  C.getArgs().MakeArgString(Twine("-targets=sycl-") + TT.str());
3397  const char *Inputs = C.getArgs().MakeArgString(Twine("-input=") + Object);
3398  // Always use -type=ao for aocx/aocr bundle checking. The 'bundles' are
3399  // actually archives.
3400  SmallVector<StringRef, 6> BundlerArgs = {"-type=ao", Targets, Inputs,
3401  "-check-section"};
3402  return runBundler(BundlerArgs, C);
3403 }
3404 
3406  const StringRef &File) {
3407  // Do not do the check if the file doesn't exist
3408  if (!llvm::sys::fs::exists(File))
3409  return {};
3410 
3411  bool IsArchive = isStaticArchiveFile(File);
3412  if (!(IsArchive || isObjectFile(File.str())))
3413  return {};
3414 
3415  // Use the bundler to grab the list of sections from the given archive
3416  // or object.
3417  StringRef ExecPath(C.getArgs().MakeArgString(C.getDriver().Dir));
3418  llvm::ErrorOr<std::string> BundlerBinary =
3419  llvm::sys::findProgramByName("clang-offload-bundler", ExecPath);
3420  const char *Input = C.getArgs().MakeArgString(Twine("-input=") + File.str());
3421  // Always use -type=ao for bundle checking. The 'bundles' are
3422  // actually archives.
3423  SmallVector<StringRef, 6> BundlerArgs = {
3424  BundlerBinary.get(), IsArchive ? "-type=ao" : "-type=o", Input, "-list"};
3425  // Since this is run in real time and not in the toolchain, output the
3426  // command line if requested.
3427  bool OutputOnly = C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
3428  if (C.getArgs().hasArg(options::OPT_v) || OutputOnly) {
3429  for (StringRef A : BundlerArgs)
3430  if (OutputOnly)
3431  llvm::errs() << "\"" << A << "\" ";
3432  else
3433  llvm::errs() << A << " ";
3434  llvm::errs() << '\n';
3435  }
3436  if (BundlerBinary.getError())
3437  return {};
3438  llvm::SmallString<64> OutputFile(
3439  C.getDriver().GetTemporaryPath("bundle-list", "txt"));
3440  llvm::FileRemover OutputRemover(OutputFile.c_str());
3441  std::optional<llvm::StringRef> Redirects[] = {
3442  {""},
3443  OutputFile.str(),
3444  OutputFile.str(),
3445  };
3446 
3447  std::string ErrorMessage;
3448  if (llvm::sys::ExecuteAndWait(BundlerBinary.get(), BundlerArgs, {}, Redirects,
3449  /*SecondsToWait*/ 0, /*MemoryLimit*/ 0,
3450  &ErrorMessage)) {
3451  // Could not get the information, return false
3452  return {};
3453  }
3454 
3455  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
3456  llvm::MemoryBuffer::getFile(OutputFile.c_str());
3457  if (!OutputBuf) {
3458  // Could not capture output, return false
3459  return {};
3460  }
3461 
3462  SmallVector<std::string, 4> Sections;
3463  for (llvm::line_iterator LineIt(**OutputBuf); !LineIt.is_at_end(); ++LineIt)
3464  Sections.push_back(LineIt->str());
3465  if (Sections.empty())
3466  return {};
3467 
3468  return Sections;
3469 }
3470 
3471 static bool hasSYCLDefaultSection(Compilation &C, const StringRef &File) {
3472  // Do not do the check if the file doesn't exist
3473  if (!llvm::sys::fs::exists(File))
3474  return false;
3475 
3476  bool IsArchive = isStaticArchiveFile(File);
3477  if (!(IsArchive || isObjectFile(File.str())))
3478  return false;
3479 
3480  llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple(getDefaultSYCLArch(C)));
3481  // Checking uses -check-section option with the input file, no output
3482  // file and the target triple being looked for.
3483  const char *Targets =
3484  C.getArgs().MakeArgString(Twine("-targets=sycl-") + TT.str());
3485  const char *Inputs = C.getArgs().MakeArgString(Twine("-input=") + File.str());
3486  SmallVector<StringRef, 6> BundlerArgs = {IsArchive ? "-type=ao" : "-type=o",
3487  Targets, Inputs, "-check-section"};
3488  return runBundler(BundlerArgs, C);
3489 }
3490 
3491 static bool hasOffloadSections(Compilation &C, const StringRef &File,
3492  DerivedArgList &Args) {
3494  return !Sections.empty();
3495 }
3496 
3497 // Simple helper function for Linker options, where the option is valid if
3498 // it has '-' or '--' as the designator.
3499 static bool optionMatches(const std::string &Option,
3500  const std::string &OptCheck) {
3501  return (Option == OptCheck || ("-" + Option) == OptCheck);
3502 }
3503 
3504 // Process linker inputs for use with offload static libraries. We are only
3505 // handling options and explicitly named static archives as these need to be
3506 // partially linked.
3508 getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) {
3510  SmallVector<std::string, 8> LibPaths;
3511  bool IsMSVC = C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
3512  // Add search directories from LIBRARY_PATH/LIB env variable
3513  std::optional<std::string> LibPath =
3514  llvm::sys::Process::GetEnv(IsMSVC ? "LIB" : "LIBRARY_PATH");
3515  if (LibPath) {
3516  SmallVector<StringRef, 8> SplitPaths;
3517  const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
3518  llvm::SplitString(*LibPath, SplitPaths, EnvPathSeparatorStr);
3519  for (StringRef Path : SplitPaths)
3520  LibPaths.emplace_back(Path.trim());
3521  }
3522  // Add directories from user-specified -L options
3523  for (std::string LibDirs : Args.getAllArgValues(options::OPT_L))
3524  LibPaths.emplace_back(LibDirs);
3525 
3526  // Do processing for any -l<arg> options passed and see if any static
3527  // libraries representing the name exists. If so, convert the name and
3528  // use that inline with the rest of the libraries.
3529  // TODO: The static archive processing for SYCL is done in a different
3530  // manner than the OpenMP processing. We should try and refactor this
3531  // to use the OpenMP flow (adding -l<name> to the llvm-link step)
3532  auto resolveStaticLib = [&](StringRef LibName, bool IsStatic) -> bool {
3533  if (!LibName.starts_with("-l"))
3534  return false;
3535  for (auto &LPath : LibPaths) {
3536  if (!IsStatic) {
3537  // Current linking state is dynamic. We will first check for the
3538  // shared object and not pull in the static library if it is found.
3539  SmallString<128> SoLibName(LPath);
3540  llvm::sys::path::append(SoLibName,
3541  Twine("lib" + LibName.substr(2) + ".so").str());
3542  if (llvm::sys::fs::exists(SoLibName))
3543  return false;
3544  }
3545  SmallString<128> FullName(LPath);
3546  llvm::sys::path::append(FullName,
3547  Twine("lib" + LibName.substr(2) + ".a").str());
3548  if (llvm::sys::fs::exists(FullName)) {
3549  LibArgs.push_back(Args.MakeArgString(FullName));
3550  return true;
3551  }
3552  }
3553  return false;
3554  };
3555  for (const auto *A : Args) {
3556  std::string FileName = A->getAsString(Args);
3557  static bool IsLinkStateStatic(Args.hasArg(options::OPT_static));
3558  auto addLibArg = [&](StringRef LibName) -> bool {
3559  if (isStaticArchiveFile(LibName) ||
3560  (IncludeObj && isObjectFile(LibName.str()))) {
3561  LibArgs.push_back(Args.MakeArgString(LibName));
3562  return true;
3563  }
3564  return false;
3565  };
3566  if (A->getOption().getKind() == Option::InputClass) {
3567  if (addLibArg(FileName))
3568  continue;
3569  }
3570  // Evaluate any libraries passed along after /link. These are typically
3571  // ignored by the driver and sent directly to the linker. When performing
3572  // offload, we should evaluate them at the driver level.
3573  if (A->getOption().matches(options::OPT__SLASH_link)) {
3574  for (StringRef Value : A->getValues()) {
3575  // Add any libpath values.
3576  if (Value.starts_with_insensitive("-libpath:") ||
3577  Value.starts_with_insensitive("/libpath:"))
3578  LibPaths.emplace_back(Value.substr(std::string("-libpath:").size()));
3579  if (addLibArg(Value))
3580  continue;
3581  for (auto LPath : LibPaths) {
3582  SmallString<128> FullLib(LPath);
3583  llvm::sys::path::append(FullLib, Value);
3584  if (addLibArg(FullLib))
3585  continue;
3586  }
3587  }
3588  }
3589  if (A->getOption().matches(options::OPT_Wl_COMMA) ||
3590  A->getOption().matches(options::OPT_Xlinker)) {
3591  // Parse through additional linker arguments that are meant to go
3592  // directly to the linker.
3593  // Keep the previous arg even if it is a new argument, for example:
3594  // -Xlinker -rpath -Xlinker <dir>.
3595  // Without this history, we do not know that <dir> was assocated with
3596  // -rpath and is processed incorrectly.
3597  static std::string PrevArg;
3598  for (StringRef Value : A->getValues()) {
3599  auto addKnownValues = [&](const StringRef &V) {
3600  // Only add named static libs objects and --whole-archive options.
3601  if (optionMatches("-whole-archive", V.str()) ||
3602  optionMatches("-no-whole-archive", V.str()) ||
3603  isStaticArchiveFile(V) || (IncludeObj && isObjectFile(V.str()))) {
3604  LibArgs.push_back(Args.MakeArgString(V));
3605  return;
3606  }
3607  // Probably not the best way to handle this, but there are options
3608  // that take arguments which we should not add to the known values.
3609  // Handle -z and -rpath for now - can be expanded if/when usage shows
3610  // the need.
3611  if (PrevArg != "-z" && PrevArg != "-rpath" && V[0] != '-' &&
3612  isObjectFile(V.str())) {
3613  LibArgs.push_back(Args.MakeArgString(V));
3614  return;
3615  }
3616  if (optionMatches("-Bstatic", V.str()) ||
3617  optionMatches("-dn", V.str()) ||
3618  optionMatches("-non_shared", V.str()) ||
3619  optionMatches("-static", V.str())) {
3620  IsLinkStateStatic = true;
3621  return;
3622  }
3623  if (optionMatches("-Bdynamic", V.str()) ||
3624  optionMatches("-dy", V.str()) ||
3625  optionMatches("-call_shared", V.str())) {
3626  IsLinkStateStatic = false;
3627  return;
3628  }
3629  resolveStaticLib(V, IsLinkStateStatic);
3630  };
3631  if (Value[0] == '@') {
3632  // Found a response file, we want to expand contents to try and
3633  // discover more libraries and options.
3634  SmallVector<const char *, 20> ExpandArgs;
3635  ExpandArgs.push_back(Value.data());
3636 
3637  llvm::BumpPtrAllocator A;
3638  llvm::StringSaver S(A);
3639  llvm::cl::ExpandResponseFiles(
3640  S,
3641  IsMSVC ? llvm::cl::TokenizeWindowsCommandLine
3642  : llvm::cl::TokenizeGNUCommandLine,
3643  ExpandArgs);
3644  for (StringRef EA : ExpandArgs)
3645  addKnownValues(EA);
3646  } else
3647  addKnownValues(Value);
3648  PrevArg = Value;
3649  }
3650  continue;
3651  }
3652  if (A->getOption().matches(options::OPT_l))
3653  resolveStaticLib(A->getAsString(Args), IsLinkStateStatic);
3654  }
3655  return LibArgs;
3656 }
3657 
3658 static bool IsSYCLDeviceLibObj(std::string ObjFilePath, bool isMSVCEnv) {
3659  StringRef ObjFileName = llvm::sys::path::filename(ObjFilePath);
3660  StringRef ObjSuffix = isMSVCEnv ? ".obj" : ".o";
3661  StringRef NewObjSuffix = isMSVCEnv ? ".new.obj" : ".new.o";
3662  bool Ret =
3663  (ObjFileName.starts_with("libsycl-") &&
3664  ObjFileName.ends_with(ObjSuffix) &&
3665  !ObjFileName.ends_with(NewObjSuffix)) // Avoid new-offload-driver objs
3666  ? true
3667  : false;
3668  return Ret;
3669 }
3670 
3671 // Goes through all of the arguments, including inputs expected for the
3672 // linker directly, to determine if we need to potentially add the SYCL
3673 // default triple.
3674 bool Driver::checkForSYCLDefaultDevice(Compilation &C,
3675  DerivedArgList &Args) const {
3676  // Check only if enabled with -fsycl
3677  if (!Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false))
3678  return false;
3679 
3680  if (Args.hasArg(options::OPT_fno_sycl_link_spirv))
3681  return false;
3682 
3683  // Do not do the check if the default device is passed in -fsycl-targets
3684  // or if -fsycl-targets isn't passed (that implies default device)
3685  if (const Arg *A = Args.getLastArg(options::OPT_fsycl_targets_EQ)) {
3686  for (const char *Val : A->getValues()) {
3687  llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple(Val));
3688  if ((TT.isSPIROrSPIRV()) && TT.getSubArch() == llvm::Triple::NoSubArch)
3689  // Default triple found
3690  return false;
3691  }
3692  } else if (!Args.hasArg(options::OPT_fintelfpga))
3693  return false;
3694 
3695  SmallVector<const char *, 16> AllArgs(getLinkerArgs(C, Args, true));
3696  for (StringRef Arg : AllArgs) {
3697  if (hasSYCLDefaultSection(C, Arg))
3698  return true;
3699  }
3700  return false;
3701 }
3702 
3703 // Goes through all of the arguments, including inputs expected for the
3704 // linker directly, to determine if we need to perform additional work for
3705 // static offload libraries.
3706 bool Driver::checkForOffloadStaticLib(Compilation &C,
3707  DerivedArgList &Args) const {
3708  // Check only if enabled with -fsycl or -fopenmp-targets
3709  if (!Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
3710  !Args.hasArg(options::OPT_fopenmp_targets_EQ))
3711  return false;
3712 
3713  SmallVector<const char *, 16> OffloadLibArgs(getLinkerArgs(C, Args));
3714  for (StringRef OLArg : OffloadLibArgs)
3715  if (isStaticArchiveFile(OLArg) && hasOffloadSections(C, OLArg, Args)) {
3716  // FPGA binaries with AOCX or AOCR sections are not considered fat
3717  // static archives.
3718  return !(hasFPGABinary(C, OLArg.str(), types::TY_FPGA_AOCR) ||
3719  hasFPGABinary(C, OLArg.str(), types::TY_FPGA_AOCR_EMU) ||
3720  hasFPGABinary(C, OLArg.str(), types::TY_FPGA_AOCX));
3721  }
3722  return false;
3723 }
3724 
3725 /// Check whether the given input tree contains any clang-offload-dependency
3726 /// actions.
3727 static bool ContainsOffloadDepsAction(const Action *A) {
3728  if (isa<OffloadDepsJobAction>(A))
3729  return true;
3730  return llvm::any_of(A->inputs(), ContainsOffloadDepsAction);
3731 }
3732 
3733 namespace {
3734 /// Provides a convenient interface for different programming models to generate
3735 /// the required device actions.
3736 class OffloadingActionBuilder final {
3737  /// Flag used to trace errors in the builder.
3738  bool IsValid = false;
3739 
3740  /// The compilation that is using this builder.
3741  Compilation &C;
3742 
3743  /// Map between an input argument and the offload kinds used to process it.
3744  std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3745 
3746  /// Map between a host action and its originating input argument.
3747  std::map<Action *, const Arg *> HostActionToInputArgMap;
3748 
3749  /// Builder interface. It doesn't build anything or keep any state.
3750  class DeviceActionBuilder {
3751  public:
3752  typedef const llvm::SmallVectorImpl<phases::ID> PhasesTy;
3753 
3754  enum ActionBuilderReturnCode {
3755  // The builder acted successfully on the current action.
3756  ABRT_Success,
3757  // The builder didn't have to act on the current action.
3758  ABRT_Inactive,
3759  // The builder was successful and requested the host action to not be
3760  // generated.
3761  ABRT_Ignore_Host,
3762  };
3763 
3764  protected:
3765  /// Compilation associated with this builder.
3766  Compilation &C;
3767 
3768  /// Tool chains associated with this builder. The same programming
3769  /// model may have associated one or more tool chains.
3771 
3772  /// The derived arguments associated with this builder.
3773  DerivedArgList &Args;
3774 
3775  /// The inputs associated with this builder.
3776  const Driver::InputList &Inputs;
3777 
3778  /// The associated offload kind.
3779  Action::OffloadKind AssociatedOffloadKind = Action::OFK_None;
3780 
3781  /// The OffloadingActionBuilder reference.
3782  OffloadingActionBuilder &OffloadingActionBuilderRef;
3783 
3784  public:
3785  DeviceActionBuilder(Compilation &C, DerivedArgList &Args,
3786  const Driver::InputList &Inputs,
3787  Action::OffloadKind AssociatedOffloadKind,
3788  OffloadingActionBuilder &OAB)
3789  : C(C), Args(Args), Inputs(Inputs),
3790  AssociatedOffloadKind(AssociatedOffloadKind),
3791  OffloadingActionBuilderRef(OAB) {}
3792  virtual ~DeviceActionBuilder() {}
3793 
3794  /// Fill up the array \a DA with all the device dependences that should be
3795  /// added to the provided host action \a HostAction. By default it is
3796  /// inactive.
3797  virtual ActionBuilderReturnCode
3798  getDeviceDependences(OffloadAction::DeviceDependences &DA,
3799  phases::ID CurPhase, phases::ID FinalPhase,
3800  PhasesTy &Phases) {
3801  return ABRT_Inactive;
3802  }
3803 
3804  /// Update the state to include the provided host action \a HostAction as a
3805  /// dependency of the current device action. By default it is inactive.
3806  virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3807  return ABRT_Inactive;
3808  }
3809 
3810  /// Append top level actions generated by the builder.
3811  virtual void appendTopLevelActions(ActionList &AL) {}
3812 
3813  /// Append top level actions specific for certain link situations.
3814  virtual void appendTopLevelLinkAction(ActionList &AL) {}
3815 
3816  /// Append linker device actions generated by the builder.
3817  virtual void appendLinkDeviceActions(ActionList &AL) {}
3818 
3819  /// Append linker host action generated by the builder.
3820  virtual Action* appendLinkHostActions(ActionList &AL) { return nullptr; }
3821 
3822  /// Append linker actions generated by the builder.
3823  virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3824 
3825  /// Append linker actions generated by the builder.
3826  virtual void addDeviceLinkDependencies(OffloadDepsJobAction *DA) {}
3827 
3828  /// Initialize the builder. Return true if any initialization errors are
3829  /// found.
3830  virtual bool initialize() { return false; }
3831 
3832  /// Return true if the builder can use bundling/unbundling.
3833  virtual bool canUseBundlerUnbundler() const { return false; }
3834 
3835  /// Return true if this builder is valid. We have a valid builder if we have
3836  /// associated device tool chains.
3837  bool isValid() { return !ToolChains.empty(); }
3838 
3839  /// Return the associated offload kind.
3840  Action::OffloadKind getAssociatedOffloadKind() {
3841  return AssociatedOffloadKind;
3842  }
3843 
3844  /// Push an action from a different DeviceActionBuilder (i.e., foreign
3845  /// action) in the current one
3846  virtual void pushForeignAction(Action *A) {}
3847  };
3848 
3849  /// Base class for CUDA/HIP action builder. It injects device code in
3850  /// the host backend action.
3851  class CudaActionBuilderBase : public DeviceActionBuilder {
3852  protected:
3853  /// Flags to signal if the user requested host-only or device-only
3854  /// compilation.
3855  bool CompileHostOnly = false;
3856  bool CompileDeviceOnly = false;
3857  bool EmitLLVM = false;
3858  bool EmitAsm = false;
3859 
3860  /// ID to identify each device compilation. For CUDA it is simply the
3861  /// GPU arch string. For HIP it is either the GPU arch string or GPU
3862  /// arch string plus feature strings delimited by a plus sign, e.g.
3863  /// gfx906+xnack.
3864  struct TargetID {
3865  /// Target ID string which is persistent throughout the compilation.
3866  const char *ID;
3867  TargetID(CudaArch Arch) { ID = CudaArchToString(Arch); }
3868  TargetID(const char *ID) : ID(ID) {}
3869  operator const char *() { return ID; }
3870  operator StringRef() { return StringRef(ID); }
3871  };
3872  /// List of GPU architectures to use in this compilation.
3873  SmallVector<TargetID, 4> GpuArchList;
3874 
3875  /// The CUDA actions for the current input.
3876  ActionList CudaDeviceActions;
3877 
3878  /// The CUDA fat binary if it was generated for the current input.
3879  Action *CudaFatBinary = nullptr;
3880 
3881  /// Flag that is set to true if this builder acted on the current input.
3882  bool IsActive = false;
3883 
3884  /// Flag for -fgpu-rdc.
3885  bool Relocatable = false;
3886 
3887  /// Default GPU architecture if there's no one specified.
3888  CudaArch DefaultCudaArch = CudaArch::UNKNOWN;
3889 
3890  /// Method to generate compilation unit ID specified by option
3891  /// '-fuse-cuid='.
3892  enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
3893  UseCUIDKind UseCUID = CUID_Hash;
3894 
3895  /// Compilation unit ID specified by option '-cuid='.
3896  StringRef FixedCUID;
3897 
3898  public:
3899  CudaActionBuilderBase(Compilation &C, DerivedArgList &Args,
3900  const Driver::InputList &Inputs,
3901  Action::OffloadKind OFKind,
3902  OffloadingActionBuilder &OAB)
3903  : DeviceActionBuilder(C, Args, Inputs, OFKind, OAB) {
3904 
3905  CompileDeviceOnly = C.getDriver().offloadDeviceOnly();
3906  Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3907  options::OPT_fno_gpu_rdc, /*Default=*/false);
3908  }
3909 
3910  ActionBuilderReturnCode addDeviceDependences(Action *HostAction) override {
3911  // While generating code for CUDA, we only depend on the host input action
3912  // to trigger the creation of all the CUDA device actions.
3913 
3914  // If we are dealing with an input action, replicate it for each GPU
3915  // architecture. If we are in host-only mode we return 'success' so that
3916  // the host uses the CUDA offload kind.
3917  if (auto *IA = dyn_cast<InputAction>(HostAction)) {
3918  assert(!GpuArchList.empty() &&
3919  "We should have at least one GPU architecture.");
3920 
3921  // If the host input is not CUDA or HIP, we don't need to bother about
3922  // this input.
3923  if (!(IA->getType() == types::TY_CUDA ||
3924  IA->getType() == types::TY_HIP ||
3925  IA->getType() == types::TY_PP_HIP)) {
3926  // The builder will ignore this input.
3927  IsActive = false;
3928  return ABRT_Inactive;
3929  }
3930 
3931  // Set the flag to true, so that the builder acts on the current input.
3932  IsActive = true;
3933 
3934  if (CompileHostOnly)
3935  return ABRT_Success;
3936 
3937  // Replicate inputs for each GPU architecture.
3938  auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3939  : types::TY_CUDA_DEVICE;
3940  std::string CUID = FixedCUID.str();
3941  if (CUID.empty()) {
3942  if (UseCUID == CUID_Random)
3943  CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
3944  /*LowerCase=*/true);
3945  else if (UseCUID == CUID_Hash) {
3946  llvm::MD5 Hasher;
3947  llvm::MD5::MD5Result Hash;
3948  SmallString<256> RealPath;
3949  llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
3950  /*expand_tilde=*/true);
3951  Hasher.update(RealPath);
3952  for (auto *A : Args) {
3953  if (A->getOption().matches(options::OPT_INPUT))
3954  continue;
3955  Hasher.update(A->getAsString(Args));
3956  }
3957  Hasher.final(Hash);
3958  CUID = llvm::utohexstr(Hash.low(), /*LowerCase=*/true);
3959  }
3960  }
3961  IA->setId(CUID);
3962 
3963  for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3964  CudaDeviceActions.push_back(
3965  C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3966  }
3967 
3968  return ABRT_Success;
3969  }
3970 
3971  // If this is an unbundling action use it as is for each CUDA toolchain.
3972  if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3973 
3974  // If -fgpu-rdc is disabled, should not unbundle since there is no
3975  // device code to link.
3976  if (UA->getType() == types::TY_Object && !Relocatable)
3977  return ABRT_Inactive;
3978 
3979  CudaDeviceActions.clear();
3980  auto *IA = cast<InputAction>(UA->getInputs().back());
3981  std::string FileName = IA->getInputArg().getAsString(Args);
3982  // Check if the type of the file is the same as the action. Do not
3983  // unbundle it if it is not. Do not unbundle .so files, for example,
3984  // which are not object files. Files with extension ".lib" is classified
3985  // as TY_Object but they are actually archives, therefore should not be
3986  // unbundled here as objects. They will be handled at other places.
3987  const StringRef LibFileExt = ".lib";
3988  if (IA->getType() == types::TY_Object &&
3989  (!llvm::sys::path::has_extension(FileName) ||
3991  llvm::sys::path::extension(FileName).drop_front()) !=
3992  types::TY_Object ||
3993  llvm::sys::path::extension(FileName) == LibFileExt))
3994  return ABRT_Inactive;
3995 
3996  for (auto Arch : GpuArchList) {
3997  CudaDeviceActions.push_back(UA);
3998  UA->registerDependentActionInfo(ToolChains[0], Arch,
3999  AssociatedOffloadKind);
4000  }
4001  IsActive = true;
4002  return ABRT_Success;
4003  }
4004 
4005  return IsActive ? ABRT_Success : ABRT_Inactive;
4006  }
4007 
4008  void appendTopLevelActions(ActionList &AL) override {
4009  // Utility to append actions to the top level list.
4010  auto AddTopLevel = [&](Action *A, TargetID TargetID) {
4012  Dep.add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
4013  AL.push_back(C.MakeAction<OffloadAction>(Dep, A->getType()));
4014  };
4015 
4016  // If we have a fat binary, add it to the list.
4017  if (CudaFatBinary) {
4018  AddTopLevel(CudaFatBinary, CudaArch::UNUSED);
4019  CudaDeviceActions.clear();
4020  CudaFatBinary = nullptr;
4021  return;
4022  }
4023 
4024  if (CudaDeviceActions.empty())
4025  return;
4026 
4027  // If we have CUDA actions at this point, that's because we have a have
4028  // partial compilation, so we should have an action for each GPU
4029  // architecture.
4030  assert(CudaDeviceActions.size() == GpuArchList.size() &&
4031  "Expecting one action per GPU architecture.");
4032  assert(ToolChains.size() == 1 &&
4033  "Expecting to have a single CUDA toolchain.");
4034  for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
4035  AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
4036 
4037  CudaDeviceActions.clear();
4038  }
4039 
4040  /// Get canonicalized offload arch option. \returns empty StringRef if the
4041  /// option is invalid.
4042  virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
4043 
4044  virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4045  getConflictOffloadArchCombination(const std::set<StringRef> &GpuArchs) = 0;
4046 
4047  bool initialize() override {
4048  assert(AssociatedOffloadKind == Action::OFK_Cuda ||
4049  AssociatedOffloadKind == Action::OFK_HIP);
4050 
4051  // We don't need to support CUDA.
4052  if (AssociatedOffloadKind == Action::OFK_Cuda &&
4053  !C.hasOffloadToolChain<Action::OFK_Cuda>())
4054  return false;
4055 
4056  // We don't need to support HIP.
4057  if (AssociatedOffloadKind == Action::OFK_HIP &&
4058  !C.hasOffloadToolChain<Action::OFK_HIP>())
4059  return false;
4060 
4061  const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
4062  assert(HostTC && "No toolchain for host compilation.");
4063  if (HostTC->getTriple().isNVPTX() ||
4064  HostTC->getTriple().getArch() == llvm::Triple::amdgcn) {
4065  // We do not support targeting NVPTX/AMDGCN for host compilation. Throw
4066  // an error and abort pipeline construction early so we don't trip
4067  // asserts that assume device-side compilation.
4068  C.getDriver().Diag(diag::err_drv_cuda_host_arch)
4069  << HostTC->getTriple().getArchName();
4070  return true;
4071  }
4072 
4073  ToolChains.push_back(
4074  AssociatedOffloadKind == Action::OFK_Cuda
4075  ? C.getSingleOffloadToolChain<Action::OFK_Cuda>()
4076  : C.getSingleOffloadToolChain<Action::OFK_HIP>());
4077 
4078  CompileHostOnly = C.getDriver().offloadHostOnly();
4079  EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
4080  EmitAsm = Args.getLastArg(options::OPT_S);
4081  FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
4082  if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
4083  StringRef UseCUIDStr = A->getValue();
4084  UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
4085  .Case("hash", CUID_Hash)
4086  .Case("random", CUID_Random)
4087  .Case("none", CUID_None)
4088  .Default(CUID_Invalid);
4089  if (UseCUID == CUID_Invalid) {
4090  C.getDriver().Diag(diag::err_drv_invalid_value)
4091  << A->getAsString(Args) << UseCUIDStr;
4092  C.setContainsError();
4093  return true;
4094  }
4095  }
4096 
4097  // --offload and --offload-arch options are mutually exclusive.
4098  if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4099  Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4100  options::OPT_no_offload_arch_EQ)) {
4101  C.getDriver().Diag(diag::err_opt_not_valid_with_opt) << "--offload-arch"
4102  << "--offload";
4103  }
4104 
4105  // Collect all offload arch parameters, removing duplicates.
4106  std::set<StringRef> GpuArchs;
4107  bool Error = false;
4108  for (Arg *A : Args) {
4109  if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
4110  A->getOption().matches(options::OPT_no_offload_arch_EQ)))
4111  continue;
4112  A->claim();
4113 
4114  for (StringRef ArchStr : llvm::split(A->getValue(), ",")) {
4115  if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
4116  ArchStr == "all") {
4117  GpuArchs.clear();
4118  } else if (ArchStr == "native") {
4119  const ToolChain &TC = *ToolChains.front();
4120  auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
4121  if (!GPUsOrErr) {
4122  TC.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
4123  << llvm::Triple::getArchTypeName(TC.getArch())
4124  << llvm::toString(GPUsOrErr.takeError()) << "--offload-arch";
4125  continue;
4126  }
4127 
4128  for (auto GPU : *GPUsOrErr) {
4129  GpuArchs.insert(Args.MakeArgString(GPU));
4130  }
4131  } else {
4132  ArchStr = getCanonicalOffloadArch(ArchStr);
4133  if (ArchStr.empty()) {
4134  Error = true;
4135  } else if (A->getOption().matches(options::OPT_offload_arch_EQ))
4136  GpuArchs.insert(ArchStr);
4137  else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
4138  GpuArchs.erase(ArchStr);
4139  else
4140  llvm_unreachable("Unexpected option.");
4141  }
4142  }
4143  }
4144 
4145  auto &&ConflictingArchs = getConflictOffloadArchCombination(GpuArchs);
4146  if (ConflictingArchs) {
4147  C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4148  << ConflictingArchs->first << ConflictingArchs->second;
4149  C.setContainsError();
4150  return true;
4151  }
4152 
4153  // Collect list of GPUs remaining in the set.
4154  for (auto Arch : GpuArchs)
4155  GpuArchList.push_back(Arch.data());
4156 
4157  // Default to sm_20 which is the lowest common denominator for
4158  // supported GPUs. sm_20 code should work correctly, if
4159  // suboptimally, on all newer GPUs.
4160  if (GpuArchList.empty()) {
4161  if (ToolChains.front()->getTriple().isSPIROrSPIRV())
4162  GpuArchList.push_back(CudaArch::Generic);
4163  else
4164  GpuArchList.push_back(DefaultCudaArch);
4165  }
4166 
4167  return Error;
4168  }
4169  };
4170 
4171  /// \brief CUDA action builder. It injects device code in the host backend
4172  /// action.
4173  class CudaActionBuilder final : public CudaActionBuilderBase {
4174  public:
4175  CudaActionBuilder(Compilation &C, DerivedArgList &Args,
4176  const Driver::InputList &Inputs,
4177  OffloadingActionBuilder &OAB)
4178  : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_Cuda, OAB) {
4179  DefaultCudaArch = CudaArch::CudaDefault;
4180  }
4181 
4182  StringRef getCanonicalOffloadArch(StringRef ArchStr) override {
4183  CudaArch Arch = StringToCudaArch(ArchStr);
4184  if (Arch == CudaArch::UNKNOWN || !IsNVIDIAGpuArch(Arch)) {
4185  C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
4186  return StringRef();
4187  }
4188  return CudaArchToString(Arch);
4189  }
4190 
4191  std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4193  const std::set<StringRef> &GpuArchs) override {
4194  return std::nullopt;
4195  }
4196 
4197  bool canUseBundlerUnbundler() const override {
4198  return Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false);
4199  }
4200 
4201  ActionBuilderReturnCode
4202  getDeviceDependences(OffloadAction::DeviceDependences &DA,
4203  phases::ID CurPhase, phases::ID FinalPhase,
4204  PhasesTy &Phases) override {
4205  if (!IsActive)
4206  return ABRT_Inactive;
4207 
4208  // If we don't have more CUDA actions, we don't have any dependences to
4209  // create for the host.
4210  if (CudaDeviceActions.empty())
4211  return ABRT_Success;
4212 
4213  assert(CudaDeviceActions.size() == GpuArchList.size() &&
4214  "Expecting one action per GPU architecture.");
4215  assert(!CompileHostOnly &&
4216  "Not expecting CUDA actions in host-only compilation.");
4217 
4218  // If we are generating code for the device or we are in a backend phase,
4219  // we attempt to generate the fat binary. We compile each arch to ptx and
4220  // assemble to cubin, then feed the cubin *and* the ptx into a device
4221  // "link" action, which uses fatbinary to combine these cubins into one
4222  // fatbin. The fatbin is then an input to the host action if not in
4223  // device-only mode.
4224  if (CompileDeviceOnly || CurPhase == phases::Backend) {
4225  ActionList DeviceActions;
4226  for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
4227  // Produce the device action from the current phase up to the assemble
4228  // phase.
4229  for (auto Ph : Phases) {
4230  // Skip the phases that were already dealt with.
4231  if (Ph < CurPhase)
4232  continue;
4233  // We have to be consistent with the host final phase.
4234  if (Ph > FinalPhase)
4235  break;
4236 
4237  CudaDeviceActions[I] = C.getDriver().ConstructPhaseAction(
4238  C, Args, Ph, CudaDeviceActions[I], Action::OFK_Cuda);
4239 
4240  if (Ph == phases::Assemble)
4241  break;
4242  }
4243 
4244  // If we didn't reach the assemble phase, we can't generate the fat
4245  // binary. We don't need to generate the fat binary if we are not in
4246  // device-only mode.
4247  if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
4248  CompileDeviceOnly)
4249  continue;
4250 
4251  Action *AssembleAction = CudaDeviceActions[I];
4252  assert(AssembleAction->getType() == types::TY_Object);
4253  assert(AssembleAction->getInputs().size() == 1);
4254 
4255  Action *BackendAction = AssembleAction->getInputs()[0];
4256  assert(BackendAction->getType() == types::TY_PP_Asm);
4257 
4258  for (auto &A : {AssembleAction, BackendAction}) {
4260  DDep.add(*A, *ToolChains.front(), GpuArchList[I], Action::OFK_Cuda);
4261  DeviceActions.push_back(
4262  C.MakeAction<OffloadAction>(DDep, A->getType()));
4263  }
4264  }
4265 
4266  // We generate the fat binary if we have device input actions.
4267  if (!DeviceActions.empty()) {
4268  CudaFatBinary =
4269  C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
4270 
4271  if (!CompileDeviceOnly) {
4272  DA.add(*CudaFatBinary, *ToolChains.front(), /*BoundArch=*/nullptr,
4274  // Clear the fat binary, it is already a dependence to an host
4275  // action.
4276  CudaFatBinary = nullptr;
4277  }
4278 
4279  // Remove the CUDA actions as they are already connected to an host
4280  // action or fat binary.
4281  CudaDeviceActions.clear();
4282  }
4283 
4284  // We avoid creating host action in device-only mode.
4285  return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
4286  } else if (CurPhase > phases::Backend) {
4287  // If we are past the backend phase and still have a device action, we
4288  // don't have to do anything as this action is already a device
4289  // top-level action.
4290  return ABRT_Success;
4291  }
4292 
4293  assert(CurPhase < phases::Backend && "Generating single CUDA "
4294  "instructions should only occur "
4295  "before the backend phase!");
4296 
4297  // By default, we produce an action for each device arch.
4298  for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
4299 
4300  CudaDeviceActions[I] = C.getDriver().ConstructPhaseAction(
4301  C, Args, CurPhase, CudaDeviceActions[I]);
4302 
4303  if (CurPhase == phases::Compile) {
4305  DDep.add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
4307 
4308  OffloadingActionBuilderRef.pushForeignAction(
4309  C.MakeAction<OffloadAction>(
4310  DDep, DDep.getActions().front()->getType()));
4311  }
4312  }
4313 
4314  return ABRT_Success;
4315  }
4316  };
4317  /// \brief HIP action builder. It injects device code in the host backend
4318  /// action.
4319  class HIPActionBuilder final : public CudaActionBuilderBase {
4320  /// The linker inputs obtained for each device arch.
4321  SmallVector<ActionList, 8> DeviceLinkerInputs;
4322  // The default bundling behavior depends on the type of output, therefore
4323  // BundleOutput needs to be tri-value: None, true, or false.
4324  // Bundle code objects except --no-gpu-output is specified for device
4325  // only compilation. Bundle other type of output files only if
4326  // --gpu-bundle-output is specified for device only compilation.
4327  std::optional<bool> BundleOutput;
4328  std::optional<bool> EmitReloc;
4329 
4330  public:
4331  HIPActionBuilder(Compilation &C, DerivedArgList &Args,
4332  const Driver::InputList &Inputs,
4333  OffloadingActionBuilder &OAB)
4334  : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP, OAB) {
4335 
4336  DefaultCudaArch = CudaArch::HIPDefault;
4337 
4338  if (Args.hasArg(options::OPT_fhip_emit_relocatable,
4339  options::OPT_fno_hip_emit_relocatable)) {
4340  EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
4341  options::OPT_fno_hip_emit_relocatable, false);
4342 
4343  if (*EmitReloc) {
4344  if (Relocatable) {
4345  C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4346  << "-fhip-emit-relocatable"
4347  << "-fgpu-rdc";
4348  }
4349 
4350  if (!CompileDeviceOnly) {
4351  C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4352  << "-fhip-emit-relocatable"
4353  << "--cuda-device-only";
4354  }
4355  }
4356  }
4357 
4358  if (Args.hasArg(options::OPT_gpu_bundle_output,
4359  options::OPT_no_gpu_bundle_output))
4360  BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
4361  options::OPT_no_gpu_bundle_output, true) &&
4362  (!EmitReloc || !*EmitReloc);
4363  }
4364 
4365  bool canUseBundlerUnbundler() const override { return true; }
4366 
4367  StringRef getCanonicalOffloadArch(StringRef IdStr) override {
4368  llvm::StringMap<bool> Features;
4369  // getHIPOffloadTargetTriple() is known to return valid value as it has
4370  // been called successfully in the CreateOffloadingDeviceToolChains().
4371  auto ArchStr = parseTargetID(
4372  *getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs()), IdStr,
4373  &Features);
4374  if (!ArchStr) {
4375  C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
4376  C.setContainsError();
4377  return StringRef();
4378  }
4379  auto CanId = getCanonicalTargetID(*ArchStr, Features);
4380  return Args.MakeArgStringRef(CanId);
4381  };
4382 
4383  std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4385  const std::set<StringRef> &GpuArchs) override {
4386  return getConflictTargetIDCombination(GpuArchs);
4387  }
4388 
4389  ActionBuilderReturnCode
4390  getDeviceDependences(OffloadAction::DeviceDependences &DA,
4391  phases::ID CurPhase, phases::ID FinalPhase,
4392  PhasesTy &Phases) override {
4393  if (!IsActive)
4394  return ABRT_Inactive;
4395 
4396  // amdgcn does not support linking of object files, therefore we skip
4397  // backend and assemble phases to output LLVM IR. Except for generating
4398  // non-relocatable device code, where we generate fat binary for device
4399  // code and pass to host in Backend phase.
4400  if (CudaDeviceActions.empty())
4401  return ABRT_Success;
4402 
4403  assert(((CurPhase == phases::Link && Relocatable) ||
4404  CudaDeviceActions.size() == GpuArchList.size()) &&
4405  "Expecting one action per GPU architecture.");
4406  assert(!CompileHostOnly &&
4407  "Not expecting HIP actions in host-only compilation.");
4408 
4409  bool ShouldLink = !EmitReloc || !*EmitReloc;
4410 
4411  if (!Relocatable && CurPhase == phases::Backend && !EmitLLVM &&
4412  !EmitAsm && ShouldLink) {
4413  // If we are in backend phase, we attempt to generate the fat binary.
4414  // We compile each arch to IR and use a link action to generate code
4415  // object containing ISA. Then we use a special "link" action to create
4416  // a fat binary containing all the code objects for different GPU's.
4417  // The fat binary is then an input to the host action.
4418  for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
4419  if (C.getDriver().isUsingLTO(/*IsOffload=*/true)) {
4420  // When LTO is enabled, skip the backend and assemble phases and
4421  // use lld to link the bitcode.
4422  ActionList AL;
4423  AL.push_back(CudaDeviceActions[I]);
4424  // Create a link action to link device IR with device library
4425  // and generate ISA.
4426  CudaDeviceActions[I] =
4427  C.MakeAction<LinkJobAction>(AL, types::TY_Image);
4428  } else {
4429  // When LTO is not enabled, we follow the conventional
4430  // compiler phases, including backend and assemble phases.
4431  ActionList AL;
4432  Action *BackendAction = nullptr;
4433  if (ToolChains.front()->getTriple().isSPIROrSPIRV()) {
4434  // Emit LLVM bitcode for SPIR-V targets. SPIR-V device tool chain
4435  // (HIPSPVToolChain) runs post-link LLVM IR passes.
4436  types::ID Output = Args.hasArg(options::OPT_S)
4437  ? types::TY_LLVM_IR
4438  : types::TY_LLVM_BC;
4439  BackendAction =
4440  C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
4441  } else
4442  BackendAction = C.getDriver().ConstructPhaseAction(
4443  C, Args, phases::Backend, CudaDeviceActions[I],
4444  AssociatedOffloadKind);
4445  auto AssembleAction = C.getDriver().ConstructPhaseAction(
4446  C, Args, phases::Assemble, BackendAction,
4447  AssociatedOffloadKind);
4448  AL.push_back(AssembleAction);
4449  // Create a link action to link device IR with device library
4450  // and generate ISA.
4451  CudaDeviceActions[I] =
4452  C.MakeAction<LinkJobAction>(AL, types::TY_Image);
4453  }
4454 
4455  // OffloadingActionBuilder propagates device arch until an offload
4456  // action. Since the next action for creating fatbin does
4457  // not have device arch, whereas the above link action and its input
4458  // have device arch, an offload action is needed to stop the null
4459  // device arch of the next action being propagated to the above link
4460  // action.
4462  DDep.add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
4463  AssociatedOffloadKind);
4464  CudaDeviceActions[I] = C.MakeAction<OffloadAction>(
4465  DDep, CudaDeviceActions[I]->getType());
4466  }
4467 
4468  if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
4469  // Create HIP fat binary with a special "link" action.
4470  CudaFatBinary = C.MakeAction<LinkJobAction>(CudaDeviceActions,
4471  types::TY_HIP_FATBIN);
4472 
4473  if (!CompileDeviceOnly) {
4474  DA.add(*CudaFatBinary, *ToolChains.front(), /*BoundArch=*/nullptr,
4475  AssociatedOffloadKind);
4476  // Clear the fat binary, it is already a dependence to an host
4477  // action.
4478  CudaFatBinary = nullptr;
4479  }
4480 
4481  // Remove the CUDA actions as they are already connected to an host
4482  // action or fat binary.
4483  CudaDeviceActions.clear();
4484  }
4485 
4486  return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
4487  } else if (CurPhase == phases::Link) {
4488  if (!ShouldLink)
4489  return ABRT_Success;
4490  // Save CudaDeviceActions to DeviceLinkerInputs for each GPU subarch.
4491  // This happens to each device action originated from each input file.
4492  // Later on, device actions in DeviceLinkerInputs are used to create
4493  // device link actions in appendLinkDependences and the created device
4494  // link actions are passed to the offload action as device dependence.
4495  DeviceLinkerInputs.resize(CudaDeviceActions.size());
4496  auto LI = DeviceLinkerInputs.begin();
4497  for (auto *A : CudaDeviceActions) {
4498  LI->push_back(A);
4499  ++LI;
4500  }
4501 
4502  // We will pass the device action as a host dependence, so we don't
4503  // need to do anything else with them.
4504  CudaDeviceActions.clear();
4505  return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
4506  }
4507 
4508  // By default, we produce an action for each device arch.
4509  for (Action *&A : CudaDeviceActions)
4510  A = C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A,
4511  AssociatedOffloadKind);
4512 
4513  if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
4514  *BundleOutput) {
4515  for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
4517  DDep.add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
4518  AssociatedOffloadKind);
4519  CudaDeviceActions[I] = C.MakeAction<OffloadAction>(
4520  DDep, CudaDeviceActions[I]->getType());
4521  }
4522  CudaFatBinary =
4523  C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
4524  CudaDeviceActions.clear();
4525  }
4526 
4527  return (CompileDeviceOnly &&
4528  (CurPhase == FinalPhase ||
4529  (!ShouldLink && CurPhase == phases::Assemble)))
4530  ? ABRT_Ignore_Host
4531  : ABRT_Success;
4532  }
4533 
4534  void appendLinkDeviceActions(ActionList &AL) override {
4535  if (DeviceLinkerInputs.size() == 0)
4536  return;
4537 
4538  assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
4539  "Linker inputs and GPU arch list sizes do not match.");
4540 
4541  ActionList Actions;
4542  unsigned I = 0;
4543  // Append a new link action for each device.
4544  // Each entry in DeviceLinkerInputs corresponds to a GPU arch.
4545  for (auto &LI : DeviceLinkerInputs) {
4546 
4547  types::ID Output = Args.hasArg(options::OPT_emit_llvm)
4548  ? types::TY_LLVM_BC
4549  : types::TY_Image;
4550 
4551  auto *DeviceLinkAction = C.MakeAction<LinkJobAction>(LI, Output);
4552  // Linking all inputs for the current GPU arch.
4553  // LI contains all the inputs for the linker.
4554  OffloadAction::DeviceDependences DeviceLinkDeps;
4555  DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0],
4556  GpuArchList[I], AssociatedOffloadKind);
4557  Actions.push_back(C.MakeAction<OffloadAction>(
4558  DeviceLinkDeps, DeviceLinkAction->getType()));
4559  ++I;
4560  }
4561  DeviceLinkerInputs.clear();
4562 
4563  // If emitting LLVM, do not generate final host/device compilation action
4564  if (Args.hasArg(options::OPT_emit_llvm)) {
4565  AL.append(Actions);
4566  return;
4567  }
4568 
4569  // Create a host object from all the device images by embedding them
4570  // in a fat binary for mixed host-device compilation. For device-only
4571  // compilation, creates a fat binary.
4573  if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
4574  auto *TopDeviceLinkAction = C.MakeAction<LinkJobAction>(
4575  Actions,
4576  CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
4577  DDeps.add(*TopDeviceLinkAction, *ToolChains[0], nullptr,
4578  AssociatedOffloadKind);
4579  // Offload the host object to the host linker.
4580  AL.push_back(
4581  C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
4582  } else {
4583  AL.append(Actions);
4584  }
4585  }
4586 
4587  Action* appendLinkHostActions(ActionList &AL) override { return AL.back(); }
4588 
4589  void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {}
4590  };
4591 
4592  /// OpenMP action builder. The host bitcode is passed to the device frontend
4593  /// and all the device linked images are passed to the host link phase.
4594  class OpenMPActionBuilder final : public DeviceActionBuilder {
4595  /// The OpenMP actions for the current input.
4596  ActionList OpenMPDeviceActions;
4597 
4598  /// The linker inputs obtained for each toolchain.
4599  SmallVector<ActionList, 8> DeviceLinkerInputs;
4600 
4601  public:
4602  OpenMPActionBuilder(Compilation &C, DerivedArgList &Args,
4603  const Driver::InputList &Inputs,
4604  OffloadingActionBuilder &OAB)
4605  : DeviceActionBuilder(C, Args, Inputs, Action::OFK_OpenMP, OAB) {}
4606 
4607  ActionBuilderReturnCode
4608  getDeviceDependences(OffloadAction::DeviceDependences &DA,
4609  phases::ID CurPhase, phases::ID FinalPhase,
4610  PhasesTy &Phases) override {
4611  if (OpenMPDeviceActions.empty())
4612  return ABRT_Inactive;
4613 
4614  // We should always have an action for each input.
4615  assert(OpenMPDeviceActions.size() == ToolChains.size() &&
4616  "Number of OpenMP actions and toolchains do not match.");
4617 
4618  // The host only depends on device action in the linking phase, when all
4619  // the device images have to be embedded in the host image.
4620  if (CurPhase == phases::Link) {
4621  assert(ToolChains.size() == DeviceLinkerInputs.size() &&
4622  "Toolchains and linker inputs sizes do not match.");
4623  auto LI = DeviceLinkerInputs.begin();
4624  for (auto *A : OpenMPDeviceActions) {
4625  LI->push_back(A);
4626  ++LI;
4627  }
4628 
4629  // We passed the device action as a host dependence, so we don't need to
4630  // do anything else with them.
4631  OpenMPDeviceActions.clear();
4632  return ABRT_Success;
4633  }
4634 
4635  // By default, we produce an action for each device arch.
4636  for (Action *&A : OpenMPDeviceActions)
4637  A = C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A);
4638 
4639  return ABRT_Success;
4640  }
4641 
4642  ActionBuilderReturnCode addDeviceDependences(Action *HostAction) override {
4643 
4644  // If this is an input action replicate it for each OpenMP toolchain.
4645  if (auto *IA = dyn_cast<InputAction>(HostAction)) {
4646  OpenMPDeviceActions.clear();
4647  for (unsigned I = 0; I < ToolChains.size(); ++I)
4648  OpenMPDeviceActions.push_back(
4649  C.MakeAction<InputAction>(IA->getInputArg(), IA->getType()));
4650  return ABRT_Success;
4651  }
4652 
4653  // If this is an unbundling action use it as is for each OpenMP toolchain.
4654  if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
4655  OpenMPDeviceActions.clear();
4656  if (auto *IA = dyn_cast<InputAction>(UA->getInputs().back())) {
4657  std::string FileName = IA->getInputArg().getAsString(Args);
4658  // Check if the type of the file is the same as the action. Do not
4659  // unbundle it if it is not. Do not unbundle .so files, for example,
4660  // which are not object files.
4661  if (IA->getType() == types::TY_Object &&
4662  (!llvm::sys::path::has_extension(FileName) ||
4664  llvm::sys::path::extension(FileName).drop_front()) !=
4665  types::TY_Object))
4666  return ABRT_Inactive;
4667  }
4668  for (unsigned I = 0; I < ToolChains.size(); ++I) {
4669  OpenMPDeviceActions.push_back(UA);
4670  UA->registerDependentActionInfo(
4671  ToolChains[I], /*BoundArch=*/StringRef(), Action::OFK_OpenMP);
4672  }
4673  return ABRT_Success;
4674  }
4675 
4676  // When generating code for OpenMP we use the host compile phase result as
4677  // a dependence to the device compile phase so that it can learn what
4678  // declarations should be emitted. However, this is not the only use for
4679  // the host action, so we prevent it from being collapsed.
4680  if (isa<CompileJobAction>(HostAction)) {
4682  assert(ToolChains.size() == OpenMPDeviceActions.size() &&
4683  "Toolchains and device action sizes do not match.");
4685  *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
4686  /*BoundArch=*/nullptr, Action::OFK_OpenMP);
4687  auto TC = ToolChains.begin();
4688  for (Action *&A : OpenMPDeviceActions) {
4689  assert(isa<CompileJobAction>(A));
4691  DDep.add(*A, **TC, /*BoundArch=*/nullptr, Action::OFK_OpenMP);
4692  A = C.MakeAction<OffloadAction>(HDep, DDep);
4693  ++TC;
4694  }
4695  }
4696  return ABRT_Success;
4697  }
4698 
4699  void appendTopLevelActions(ActionList &AL) override {
4700  if (OpenMPDeviceActions.empty())
4701  return;
4702 
4703  // We should always have an action for each input.
4704  assert(OpenMPDeviceActions.size() == ToolChains.size() &&
4705  "Number of OpenMP actions and toolchains do not match.");
4706 
4707  // Append all device actions followed by the proper offload action.
4708  auto TI = ToolChains.begin();
4709  for (auto *A : OpenMPDeviceActions) {
4711  Dep.add(*A, **TI, /*BoundArch=*/nullptr, Action::OFK_OpenMP);
4712  AL.push_back(C.MakeAction<OffloadAction>(Dep, A->getType()));
4713  ++TI;
4714  }
4715  // We no longer need the action stored in this builder.
4716  OpenMPDeviceActions.clear();
4717  }
4718 
4719  void appendLinkDeviceActions(ActionList &AL) override {
4720  assert(ToolChains.size() == DeviceLinkerInputs.size() &&
4721  "Toolchains and linker inputs sizes do not match.");
4722 
4723  // Append a new link action for each device.
4724  auto TC = ToolChains.begin();
4725  for (auto &LI : DeviceLinkerInputs) {
4726  auto *DeviceLinkAction =
4727  C.MakeAction<LinkJobAction>(LI, types::TY_Image);
4728  OffloadAction::DeviceDependences DeviceLinkDeps;
4729  DeviceLinkDeps.add(*DeviceLinkAction, **TC, /*BoundArch=*/nullptr,
4731  AL.push_back(C.MakeAction<OffloadAction>(DeviceLinkDeps,
4732  DeviceLinkAction->getType()));
4733  ++TC;
4734  }
4735  DeviceLinkerInputs.clear();
4736  }
4737 
4738  Action* appendLinkHostActions(ActionList &AL) override {
4739  // Create wrapper bitcode from the result of device link actions and compile
4740  // it to an object which will be added to the host link command.
4741  auto *BC = C.MakeAction<OffloadWrapperJobAction>(AL, types::TY_LLVM_BC);
4742  auto *ASM = C.MakeAction<BackendJobAction>(BC, types::TY_PP_Asm);
4743  return C.MakeAction<AssembleJobAction>(ASM, types::TY_Object);
4744  }
4745 
4746  void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {}
4747 
4748  void addDeviceLinkDependencies(OffloadDepsJobAction *DA) override {
4749  for (unsigned I = 0; I < ToolChains.size(); ++I) {
4750  // Register dependent toolchain.
4752  ToolChains[I], /*BoundArch=*/StringRef(), Action::OFK_OpenMP);
4753 
4754  if (!ToolChains[I]->getTriple().isSPIROrSPIRV()) {
4755  // Create object from the deps bitcode.
4756  auto *BA = C.MakeAction<BackendJobAction>(DA, types::TY_PP_Asm);
4757  auto *AA = C.MakeAction<AssembleJobAction>(BA, types::TY_Object);
4758 
4759  // Add deps object to linker inputs.
4760  DeviceLinkerInputs[I].push_back(AA);
4761  } else
4762  DeviceLinkerInputs[I].push_back(DA);
4763  }
4764  }
4765 
4766  bool initialize() override {
4767  // Get the OpenMP toolchains. If we don't get any, the action builder will
4768  // know there is nothing to do related to OpenMP offloading.
4769  auto OpenMPTCRange = C.getOffloadToolChains<Action::OFK_OpenMP>();
4770  for (auto TI = OpenMPTCRange.first, TE = OpenMPTCRange.second; TI != TE;
4771  ++TI)
4772  ToolChains.push_back(TI->second);
4773 
4774  DeviceLinkerInputs.resize(ToolChains.size());
4775  return false;
4776  }
4777 
4778  bool canUseBundlerUnbundler() const override {
4779  // OpenMP should use bundled files whenever possible.
4780  return true;
4781  }
4782  };
4783 
4784  /// SYCL action builder. The host bitcode is passed to the device frontend
4785  /// and all the device linked images are passed to the host link phase.
4786  /// SPIR related are wrapped before added to the fat binary
4787  class SYCLActionBuilder final : public DeviceActionBuilder {
4788  /// Flag to signal if the user requested device-only compilation.
4789  bool CompileDeviceOnly = false;
4790 
4791  /// Flag to signal if the user requested the device object to be wrapped.
4792  bool WrapDeviceOnlyBinary = false;
4793 
4794  /// Flag to signal if the user requested device code split.
4795  bool DeviceCodeSplit = false;
4796 
4797  /// List of offload device toolchain, bound arch needed to track for
4798  /// different binary constructions.
4799  /// POD to hold information about a SYCL device action.
4800  /// Each Action is bound to a <TC, arch> pair,
4801  /// we keep them together under a struct for clarity.
4802  struct DeviceTargetInfo {
4803  DeviceTargetInfo(const ToolChain *TC, const char *BA)
4804  : TC(TC), BoundArch(BA) {}
4805 
4806  const ToolChain *TC;
4807  const char *BoundArch;
4808  };
4809  SmallVector<DeviceTargetInfo, 4> SYCLTargetInfoList;
4810 
4811  /// The SYCL actions for the current input.
4812  /// One action per triple/boundarch.
4813  ActionList SYCLDeviceActions;
4814 
4815  /// The linker inputs obtained for each input/toolchain/arch.
4816  SmallVector<ActionList, 4> DeviceLinkerInputs;
4817 
4818  /// The SYCL link binary if it was generated for the current input.
4819  Action *SYCLLinkBinary = nullptr;
4820 
4821  /// Running list of SYCL actions specific for device linking.
4822  ActionList SYCLLinkBinaryList;
4823 
4824  /// List of SYCL Final Device binaries that should be unbundled as a final
4825  /// device binary and not further processed.
4827  SYCLFinalDeviceList;
4828 
4829  /// SYCL ahead of time compilation inputs
4831 
4832  /// List of offload device triples as provided on the CLI.
4833  /// Does not track AOT binary inputs triples.
4834  SmallVector<llvm::Triple, 4> SYCLTripleList;
4835 
4836  /// Type of output file for FPGA device compilation.
4837  types::ID FPGAOutType = types::TY_FPGA_AOCX;
4838 
4839  /// List of objects to extract FPGA dependency info from
4840  ActionList FPGAObjectInputs;
4841 
4842  /// List of static archives to extract FPGA dependency info from
4843  ActionList FPGAArchiveInputs;
4844 
4845  /// List of AOCR based archives that contain BC members to use for
4846  /// providing symbols and properties.
4847  ActionList FPGAAOCArchives;
4848 
4849  // SYCLInstallation is needed in order to link SYCLDeviceLibs
4850  SYCLInstallationDetector SYCLInstallation;
4851 
4852  /// List of GPU architectures to use in this compilation with NVPTX/AMDGCN
4853  /// targets.
4855 
4856  /// Build the last steps for CUDA after all BC files have been linked.
4857  JobAction *finalizeNVPTXDependences(Action *Input, const llvm::Triple &TT) {
4858  auto *BA = C.getDriver().ConstructPhaseAction(
4859  C, Args, phases::Backend, Input, AssociatedOffloadKind);
4860  if (TT.getOS() != llvm::Triple::NVCL) {
4861  auto *AA = C.getDriver().ConstructPhaseAction(
4862  C, Args, phases::Assemble, BA, AssociatedOffloadKind);
4863  ActionList DeviceActions = {BA, AA};
4864  return C.MakeAction<LinkJobAction>(DeviceActions,
4865  types::TY_CUDA_FATBIN);
4866  }
4867  return cast<JobAction>(BA);
4868  }
4869 
4870  JobAction *finalizeAMDGCNDependences(Action *Input,
4871  const llvm::Triple &TT) {
4872  auto *BA = C.getDriver().ConstructPhaseAction(
4873  C, Args, phases::Backend, Input, AssociatedOffloadKind);
4874 
4875  auto *AA = C.getDriver().ConstructPhaseAction(C, Args, phases::Assemble,
4876  BA, AssociatedOffloadKind);
4877 
4878  ActionList AL = {AA};
4879  Action *LinkAction = C.MakeAction<LinkJobAction>(AL, types::TY_Image);
4880  ActionList HIPActions = {LinkAction};
4881  JobAction *HIPFatBinary =
4882  C.MakeAction<LinkJobAction>(HIPActions, types::TY_HIP_FATBIN);
4883  return HIPFatBinary;
4884  }
4885 
4886  Action *ExternalCudaAction = nullptr;
4887 
4888  public:
4889  SYCLActionBuilder(Compilation &C, DerivedArgList &Args,
4890  const Driver::InputList &Inputs,
4891  OffloadingActionBuilder &OAB)
4892  : DeviceActionBuilder(C, Args, Inputs, Action::OFK_SYCL, OAB),
4893  SYCLInstallation(C.getDriver()) {}
4894 
4895  void withBoundArchForToolChain(const ToolChain *TC,
4896  llvm::function_ref<void(const char *)> Op) {
4897  for (auto &A : GpuArchList) {
4898  if (TC->getTriple() == A.first) {
4899  Op(A.second ? Args.MakeArgString(A.second) : nullptr);
4900  return;
4901  }
4902  }
4903 
4904  // no bound arch for this toolchain
4905  Op(nullptr);
4906  }
4907 
4908  void pushForeignAction(Action *A) override {
4909  // Accept a foreign action from the CudaActionBuilder for compiling CUDA
4910  // sources
4912  ExternalCudaAction = A;
4913  }
4914 
4915  ActionBuilderReturnCode
4916  getDeviceDependences(OffloadAction::DeviceDependences &DA,
4917  phases::ID CurPhase, phases::ID FinalPhase,
4918  PhasesTy &Phases) override {
4919  bool SYCLDeviceOnly = C.getDriver().offloadDeviceOnly();
4920  if (CurPhase == phases::Preprocess) {
4921  // Do not perform the host compilation when doing preprocessing only
4922  // with -fsycl-device-only.
4923  bool IsPreprocessOnly =
4924  Args.getLastArg(options::OPT_E) ||
4925  Args.getLastArg(options::OPT__SLASH_EP, options::OPT__SLASH_P) ||
4926  Args.getLastArg(options::OPT_M, options::OPT_MM);
4927  if (IsPreprocessOnly) {
4928  for (auto TargetActionInfo :
4929  llvm::zip(SYCLDeviceActions, SYCLTargetInfoList)) {
4930  Action *&A = std::get<0>(TargetActionInfo);
4931  auto &TargetInfo = std::get<1>(TargetActionInfo);
4932  A = C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A,
4933  AssociatedOffloadKind);
4934  if (SYCLDeviceOnly)
4935  continue;
4936  // Add an additional compile action to generate the integration
4937  // header.
4938  Action *CompileAction =
4939  C.MakeAction<CompileJobAction>(A, types::TY_Nothing);
4940  DA.add(*CompileAction, *TargetInfo.TC, TargetInfo.BoundArch,
4942  }
4943  return SYCLDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
4944  }
4945  }
4946 
4947  // Device compilation generates LLVM BC.
4948  if (CurPhase == phases::Compile && !SYCLTargetInfoList.empty()) {
4949  // TODO: handle stubfile handling when mix and matching programming
4950  // model.
4951  if (SYCLDeviceActions.empty())
4952  return ABRT_Success;
4953 
4954  Action *DeviceCompilerInput = nullptr;
4955  const DeviceTargetInfo &DevTarget = SYCLTargetInfoList.back();
4956  for (auto TargetActionInfo :
4957  llvm::zip(SYCLDeviceActions, SYCLTargetInfoList)) {
4958  Action *&A = std::get<0>(TargetActionInfo);
4959  auto &TargetInfo = std::get<1>(TargetActionInfo);
4960  types::ID OutputType = types::TY_LLVM_BC;
4961  if ((SYCLDeviceOnly || Args.hasArg(options::OPT_emit_llvm)) &&
4962  Args.hasArg(options::OPT_S))
4963  OutputType = types::TY_LLVM_IR;
4964  // Use of -fsycl-device-obj=spirv converts the original LLVM-IR
4965  // file to SPIR-V for later consumption.
4966  if ((SYCLDeviceOnly || FinalPhase != phases::Link) &&
4967  Args.getLastArgValue(options::OPT_fsycl_device_obj_EQ)
4968  .equals_insensitive("spirv")) {
4969  auto *CompileAction =
4970  C.MakeAction<CompileJobAction>(A, types::TY_LLVM_BC);
4971  A = C.MakeAction<SPIRVTranslatorJobAction>(CompileAction,
4972  types::TY_SPIRV);
4973  if (SYCLDeviceOnly)
4974  continue;
4975  } else {
4976  if (Args.hasArg(options::OPT_fsyntax_only))
4977  OutputType = types::TY_Nothing;
4978  A = C.MakeAction<CompileJobAction>(A, OutputType);
4979  }
4980  // Add any of the device linking steps when -fno-sycl-rdc is
4981  // specified. Device linking is only available for AOT at this
4982  // time.
4983  llvm::Triple TargetTriple = TargetInfo.TC->getTriple();
4985  TargetTriple.isSPIRAOT() && FinalPhase != phases::Link) {
4986  ActionList CAList;
4987  CAList.push_back(A);
4988  ActionList DeviceLinkActions;
4989  appendSYCLDeviceLink(CAList, TargetInfo.TC, DeviceLinkActions,
4990  TargetInfo.BoundArch, /*SkipWrapper=*/false);
4991  // The list of actions generated from appendSYCLDeviceLink is kept
4992  // in DeviceLinkActions. Instead of adding the dependency on the
4993  // compiled device file, add the dependency against the compiled
4994  // device binary to be added to the resulting fat object.
4995  A = DeviceLinkActions.back();
4996  }
4997  DeviceCompilerInput = A;
4998  }
4999  DA.add(*DeviceCompilerInput, *DevTarget.TC, DevTarget.BoundArch,
5001  return SYCLDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
5002  }
5003 
5004  // Backend/Assemble actions are obsolete for the SYCL device side
5005  if (CurPhase == phases::Backend || CurPhase == phases::Assemble)
5006  return ABRT_Inactive;
5007 
5008  // The host only depends on device action in the linking phase, when all
5009  // the device images have to be embedded in the host image.
5010  if (CurPhase == phases::Link) {
5011  if (!SYCLDeviceActions.empty()) {
5012  assert(SYCLDeviceActions.size() == DeviceLinkerInputs.size() &&
5013  "Device action and device linker inputs sizes do not match.");
5014 
5015  for (auto TargetAction :
5016  llvm::zip(DeviceLinkerInputs, SYCLDeviceActions)) {
5017  ActionList &LinkerList = std::get<0>(TargetAction);
5018  Action *A = std::get<1>(TargetAction);
5019 
5020  LinkerList.push_back(A);
5021  }
5022  }
5023 
5024  if (ExternalCudaAction) {
5025  assert(DeviceLinkerInputs.size() == 1 &&
5026  "Number of SYCL actions and toolchains/boundarch pairs do not "
5027  "match.");
5028  DeviceLinkerInputs[0].push_back(ExternalCudaAction);
5029  ExternalCudaAction = nullptr;
5030  }
5031 
5032  if (CompileDeviceOnly && !SYCLDeviceActions.empty()) {
5033  for (auto SDA : SYCLDeviceActions)
5034  SYCLLinkBinaryList.push_back(SDA);
5035  // Remove the SYCL actions as they are already connected to an host
5036  // action or fat binary.
5037  SYCLDeviceActions.clear();
5038 
5039  if (WrapDeviceOnlyBinary)
5040  return ABRT_Ignore_Host;
5041  auto *Link =
5042  C.MakeAction<LinkJobAction>(SYCLLinkBinaryList, types::TY_Image);
5043  SYCLLinkBinary =
5044  C.MakeAction<SPIRVTranslatorJobAction>(Link, types::TY_Image);
5045  // We avoid creating host action in device-only mode.
5046  return ABRT_Ignore_Host;
5047  }
5048 
5049  // We passed the device action as a host dependence, so we don't need to
5050  // do anything else with them.
5051  SYCLDeviceActions.clear();
5052  return ABRT_Success;
5053  }
5054 
5055  // By default, we produce an action for each device arch.
5056  for (auto TargetActionInfo :
5057  llvm::zip(SYCLDeviceActions, SYCLTargetInfoList)) {
5058  auto &TargetInfo = std::get<1>(TargetActionInfo);
5059  if (TargetInfo.TC->getTriple().isNVPTX() && CurPhase >= phases::Backend)
5060  // For CUDA, stop to emit LLVM IR so it can be linked later on.
5061  continue;
5062 
5063  Action *&A = std::get<0>(TargetActionInfo);
5064  A = C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A,
5065  AssociatedOffloadKind);
5066  }
5067 
5068  return ABRT_Success;
5069  }
5070 
5071  ActionBuilderReturnCode addDeviceDependences(Action *HostAction) override {
5072 
5073  // If this is an input action replicate it for each SYCL toolchain.
5074  if (auto *IA = dyn_cast<InputAction>(HostAction)) {
5075  SYCLDeviceActions.clear();
5076 
5077  // Options that are considered LinkerInput are not valid input actions
5078  // to the device tool chain.
5079  if (IA->getInputArg().getOption().hasFlag(options::LinkerInput))
5080  return ABRT_Inactive;
5081 
5082  std::string InputName = IA->getInputArg().getAsString(Args);
5083  // Objects will be consumed as part of the partial link step when
5084  // dealing with offload static libraries
5085  if (C.getDriver().getOffloadStaticLibSeen() &&
5086  IA->getType() == types::TY_Object && isObjectFile(InputName))
5087  return ABRT_Inactive;
5088 
5089  // Libraries are not processed in the SYCL toolchain
5090  if (IA->getType() == types::TY_Object && !isObjectFile(InputName))
5091  return ABRT_Inactive;
5092 
5093  for (auto &TargetInfo : SYCLTargetInfoList) {
5094  (void)TargetInfo;
5095  SYCLDeviceActions.push_back(
5096  C.MakeAction<InputAction>(IA->getInputArg(), IA->getType()));
5097  }
5098  return ABRT_Success;
5099  }
5100 
5101  // If this is an unbundling action use it as is for each SYCL toolchain.
5102  if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
5103  SYCLDeviceActions.clear();
5104  if (auto *IA = dyn_cast<InputAction>(UA->getInputs().back())) {
5105  // Options that are considered LinkerInput are not valid input actions
5106  // to the device tool chain.
5107  if (IA->getInputArg().getOption().hasFlag(options::LinkerInput))
5108  return ABRT_Inactive;
5109 
5110  std::string FileName = IA->getInputArg().getAsString(Args);
5111  // Check if the type of the file is the same as the action. Do not
5112  // unbundle it if it is not. Do not unbundle .so files, for example,
5113  // which are not object files.
5114  if (IA->getType() == types::TY_Object) {
5115  if (!isObjectFile(FileName))
5116  return ABRT_Inactive;
5117  // For SYCL device libraries, don't need to add them to
5118  // FPGAObjectInputs as there is no FPGA dep files inside.
5119  const auto *TC = ToolChains.front();
5120  if (TC->getTriple().getSubArch() ==
5121  llvm::Triple::SPIRSubArch_fpga &&
5122  !IsSYCLDeviceLibObj(FileName, C.getDefaultToolChain()
5123  .getTriple()
5124  .isWindowsMSVCEnvironment()))
5125  FPGAObjectInputs.push_back(IA);
5126  }
5127  }
5128  // Create 1 device action per triple/bound arch
5129  for (auto &TargetInfo : SYCLTargetInfoList) {
5130  SYCLDeviceActions.push_back(UA);
5131  UA->registerDependentActionInfo(TargetInfo.TC, TargetInfo.BoundArch,
5133  }
5134  return ABRT_Success;
5135  }
5136  return ABRT_Success;
5137  }
5138 
5139  void appendLinkDeviceActions(ActionList &AL) override {
5140  if (DeviceLinkerInputs.size() == 0)
5141  return;
5142 
5143  for (const auto &LinkInputEnum : enumerate(DeviceLinkerInputs)) {
5144  auto &LI = LinkInputEnum.value();
5145  int Index = LinkInputEnum.index();
5146  const ToolChain *TC = SYCLTargetInfoList[Index].TC;
5147  const char *BoundArch = SYCLTargetInfoList[Index].BoundArch;
5148 
5149  auto TripleIt = llvm::find_if(SYCLTripleList, [&](auto &SYCLTriple) {
5150  return SYCLTriple == TC->getTriple();
5151  });
5152  if (TripleIt == SYCLTripleList.end()) {
5153  // If the toolchain's triple is absent in this "main" triple
5154  // collection, this means it was created specifically for one of
5155  // the SYCL AOT inputs. Those will be handled separately.
5156  continue;
5157  }
5158  if (LI.empty())
5159  // Current list is empty, nothing to process.
5160  continue;
5161  // Do not add the wrapper when performing -fsycl-link.
5162  // TODO: Update when wrappers are not added to be more general,
5163  // improving the number of wrapper calls occuring. For now, only
5164  // restrict the wrappers from being inlined with each device link
5165  // when performing -fsycl-link behaviors.
5166  appendSYCLDeviceLink(LI, TC, AL, BoundArch,
5167  /*SkipWrapper=*/WrapDeviceOnlyBinary,
5168  /*AddOffloadAction=*/true);
5169  }
5170  DeviceLinkerInputs.clear();
5171  }
5172 
5173  Action *appendLinkHostActions(ActionList &AL) override {
5174  // Only add wrapping actions when performing -fsycl-link
5175  if (!WrapDeviceOnlyBinary)
5176  return nullptr;
5177 
5178  // Create wrapper bitcode from the result of device link actions and
5179  // compile it to an object which will be added to the host link command.
5180  auto *BC = C.MakeAction<OffloadWrapperJobAction>(AL, types::TY_LLVM_BC);
5181  auto *ASM = C.MakeAction<BackendJobAction>(BC, types::TY_PP_Asm);
5182  return C.MakeAction<AssembleJobAction>(ASM, types::TY_Object);
5183  }
5184 
5185  // Actions that can only be appended after all Inputs have been processed
5186  // occur here. Not all offload actions are against single files.
5187  void appendTopLevelLinkAction(ActionList &AL) override {
5188  if (!SYCLLinkBinary)
5189  return;
5190 
5192  withBoundArchForToolChain(ToolChains.front(), [&](const char *BoundArch) {
5193  Dep.add(*SYCLLinkBinary, *ToolChains.front(), BoundArch,
5194  Action::OFK_SYCL);
5195  });
5196  AL.push_back(C.MakeAction<OffloadAction>(Dep, SYCLLinkBinary->getType()));
5197  SYCLLinkBinary = nullptr;
5198  }
5199 
5200  void appendTopLevelActions(ActionList &AL) override {
5201  // We should always have an action for each input.
5202  if (!SYCLDeviceActions.empty()) {
5203  assert(SYCLDeviceActions.size() == SYCLTargetInfoList.size() &&
5204  "Number of SYCL actions and toolchains/boundarch pairs do not "
5205  "match.");
5206 
5207  // Append all device actions followed by the proper offload action.
5208  for (auto TargetActionInfo :
5209  llvm::zip(SYCLDeviceActions, SYCLTargetInfoList)) {
5210  Action *A = std::get<0>(TargetActionInfo);
5211  DeviceTargetInfo &TargetInfo = std::get<1>(TargetActionInfo);
5212 
5214  Dep.add(*A, *TargetInfo.TC, TargetInfo.BoundArch, Action::OFK_SYCL);
5215  if (ExternalCudaAction) {
5216  assert(
5217  SYCLTargetInfoList.size() == 1 &&
5218  "Number of SYCL actions and toolchains/boundarch pairs do not "
5219  "match.");
5220 
5221  // Link with external CUDA action.
5222  ActionList LinkObjects;
5223  LinkObjects.push_back(
5224  C.MakeAction<OffloadAction>(Dep, A->getType()));
5225  LinkObjects.push_back(ExternalCudaAction);
5226  Action *DeviceLinkAction =
5227  C.MakeAction<LinkJobAction>(LinkObjects, types::TY_LLVM_BC);
5228 
5230  DDep.add(*DeviceLinkAction, *TargetInfo.TC, TargetInfo.BoundArch,
5232  AL.push_back(C.MakeAction<OffloadAction>(DDep, A->getType()));
5233 
5234  ExternalCudaAction = nullptr;
5235  } else {
5236  AL.push_back(C.MakeAction<OffloadAction>(Dep, A->getType()));
5237  }
5238  }
5239  // We no longer need the action stored in this builder.
5240  SYCLDeviceActions.clear();
5241  }
5242  }
5243 
5244  // Performs device specific linking steps for the SYCL based toolchain.
5245  // This function is used for both the early AOT flow and the typical
5246  // offload device link flow.
5247  // When creating the standard offload device link flow during the link
5248  // phase, the ListIndex input provides an index against the
5249  // SYCLTargetInfoList. This is used to determine associated toolchain
5250  // information for the values being worked against to add the device link
5251  // steps. The generated device link steps are added via dependency
5252  // additions. For early AOT, ListIndex is the base device file that the
5253  // created device linking actions are performed against. The
5254  // DeviceLinkActions is used to hold the actions generated to be added to
5255  // the toolchain.
5256  // TODO: This function takes a list of items to work against. Update this
5257  // to work one action at a time, enabling the ability to pull out the
5258  // wrapping step to be performed solely on the host side of the toolchain.
5259  // Any FPGA specific behaviors should also be specifically scrutinized
5260  // to better compartmentalize that aspect of the compilation.
5261  void appendSYCLDeviceLink(const ActionList &ListIndex, const ToolChain *TC,
5262  ActionList &DeviceLinkActions,
5263  const char *BoundArch, bool SkipWrapper,
5264  bool AddOffloadAction = false) {
5265  auto addDeps = [&](Action *A, const ToolChain *TC,
5266  const char *BoundArch) {
5267  if (AddOffloadAction) {
5269  Deps.add(*A, *TC, BoundArch, Action::OFK_SYCL);
5270  DeviceLinkActions.push_back(
5271  C.MakeAction<OffloadAction>(Deps, A->getType()));
5272  } else
5273  DeviceLinkActions.push_back(A);
5274  };
5275 
5276  // List of device specific libraries to be fed into llvm-link.
5277  ActionList SYCLDeviceLibs;
5278 
5279  // List of device specific library 'objects' (FPGA AOCO libraries) that
5280  // are fed directly to the FPGA offline compiler.
5281  ActionList FPGADeviceLibObjects;
5282 
5283  // List of device objects that go through the device link step.
5284  ActionList LinkObjects;
5285 
5286  // List of FPGA AOC specific device objects/archives.
5287  ActionList FPGAAOCDevices;
5288  auto TargetTriple = TC->getTriple();
5289  auto IsNVPTX = TargetTriple.isNVPTX();
5290  auto IsAMDGCN = TargetTriple.isAMDGCN();
5291  auto IsSPIR = TargetTriple.isSPIROrSPIRV();
5292  bool IsSpirvAOT = TargetTriple.isSPIRAOT();
5293  const bool IsSYCLNativeCPU =
5294  TC->getAuxTriple() &&
5295  driver::isSYCLNativeCPU(TargetTriple, *TC->getAuxTriple());
5296  for (const auto &Input : ListIndex) {
5297  if (TargetTriple.getSubArch() == llvm::Triple::SPIRSubArch_fpga &&
5298  types::isFPGA(Input->getType())) {
5299  assert(BoundArch == nullptr &&
5300  "fpga triple bounded arch not nullptr");
5301  // FPGA aoco does not go through the link, everything else does.
5302  if (Input->getType() == types::TY_FPGA_AOCO) {
5303  FPGADeviceLibObjects.push_back(Input);
5304  continue;
5305  }
5306  // FPGA aocr/aocx does not go through the link and is passed
5307  // directly to the backend compilation step (aocr) or wrapper (aocx)
5308  if (Args.hasArg(options::OPT_fintelfpga)) {
5309  if (Input->getType() == types::TY_FPGA_AOCR ||
5310  Input->getType() == types::TY_FPGA_AOCR_EMU ||
5311  Input->getType() == types::TY_FPGA_AOCX)
5312  // Save the AOCR device items. These will be processed along
5313  // with the FPGAAOCArchives.
5314  FPGAAOCDevices.push_back(Input);
5315  else
5316  llvm_unreachable("Unexpected FPGA input type.");
5317  }
5318  continue;
5319  } else if (!types::isFPGA(Input->getType())) {
5320  // No need for any conversion if we are coming in from the
5321  // clang-offload-deps or regular compilation path.
5322  if (IsNVPTX || IsAMDGCN || ContainsOffloadDepsAction(Input) ||
5324  LinkObjects.push_back(Input);
5325  continue;
5326  }
5327  // Any objects or lists of objects that come in from the unbundling
5328  // step can either be LLVM-IR or SPIR-V based. Send these through
5329  // the spirv-to-ir-wrapper to convert to LLVM-IR to be properly
5330  // processed during the device link.
5331  Action *ConvertSPIRVAction = C.MakeAction<SpirvToIrWrapperJobAction>(
5332  Input, Input->getType() == types::TY_Tempfilelist
5333  ? types::TY_Tempfilelist
5334  : types::TY_LLVM_BC);
5335  LinkObjects.push_back(ConvertSPIRVAction);
5336  }
5337  }
5338  // Process AOCR/AOCR_EMU
5339  if (FPGAAOCDevices.size()) {
5340  assert(FPGAAOCDevices.size() == FPGAAOCArchives.size() &&
5341  "Unexpected number of AOC binaries");
5342  // Generate AOCX/AOCR
5343  // Input is the unbundled device binary. Perform an additional
5344  // unbundle against the input file associated to grab the wrapped
5345  // device binary.
5346  for (auto AOCRItem : llvm::zip(FPGAAOCArchives, FPGAAOCDevices)) {
5347  Action *Archive = std::get<0>(AOCRItem);
5348  Action *Device = std::get<1>(AOCRItem);
5349 
5350  auto *UnbundleAction = C.MakeAction<OffloadUnbundlingJobAction>(
5351  Archive, types::TY_Tempfilelist);
5352  UnbundleAction->registerDependentActionInfo(TC, /*BoundArch=*/"",
5354  auto *RenameUnbundle = C.MakeAction<FileTableTformJobAction>(
5355  UnbundleAction, types::TY_Tempfilelist, types::TY_Tempfilelist);
5356  RenameUnbundle->addRenameColumnTform(
5359 
5360  // Wrap the unbundled device binary along with the additional
5361  // .bc file that contains the Symbols and Properties
5362  if (Device->getType() == types::TY_FPGA_AOCX) {
5363  auto *RenameAction = C.MakeAction<FileTableTformJobAction>(
5364  Device, types::TY_Tempfilelist, types::TY_Tempfilelist);
5365  RenameAction->addRenameColumnTform(
5368  ActionList WrapperItems({RenameAction, RenameUnbundle});
5369  auto *DeviceWrappingAction = C.MakeAction<OffloadWrapperJobAction>(
5370  WrapperItems, types::TY_Object);
5371  addDeps(DeviceWrappingAction, TC, BoundArch);
5372  } else {
5373  auto *FPGAAOTAction =
5374  C.MakeAction<BackendCompileJobAction>(Device, FPGAOutType);
5375  auto *RenameAction = C.MakeAction<FileTableTformJobAction>(
5376  FPGAAOTAction, types::TY_Tempfilelist, types::TY_Tempfilelist);
5377  RenameAction->addRenameColumnTform(
5380  ActionList WrapperItems({RenameAction, RenameUnbundle});
5381  auto *DeviceWrappingAction = C.MakeAction<OffloadWrapperJobAction>(
5382  WrapperItems, types::TY_Object);
5383 
5384  Action *DeviceAction = DeviceWrappingAction;
5385  if (Args.hasArg(options::OPT_fsycl_link_EQ)) {
5386  if (auto *OWA = dyn_cast<OffloadWrapperJobAction>(DeviceAction))
5387  OWA->setCompileStep(false);
5388  ActionList BundlingActions;
5389  BundlingActions.push_back(DeviceWrappingAction);
5390 
5391  // Wrap and compile the wrapped device device binary. This will
5392  // be used later when consumed as the input .bc file to retain
5393  // the symbols and properties associated.
5394  DeviceAction = C.MakeAction<OffloadWrapperJobAction>(
5395  BundlingActions, types::TY_Object);
5396  if (auto *OWA = dyn_cast<OffloadWrapperJobAction>(DeviceAction))
5398  Action *CompiledDeviceAction =
5399  C.MakeAction<OffloadWrapperJobAction>(WrapperItems,
5400  types::TY_Object);
5401  addDeps(CompiledDeviceAction, TC, BoundArch);
5402  }
5403  addDeps(DeviceAction, TC, BoundArch);
5404  }
5405  }
5406  }
5407  for (const auto &A : SYCLFinalDeviceList) {
5408  // Given the list of archives that have final device binaries, take
5409  // those archives and unbundle all of the devices seen. These will
5410  // be added to the final host link with no additional processing.
5411  // Gather the targets to unbundle.
5412  auto Input(A.first);
5413  for (StringRef TargetString : A.second) {
5414  // Unbundle
5415  types::ID InputType = Input->getType();
5416  if (InputType == types::TY_Archive)
5417  InputType = types::TY_Tempfilelist;
5418  auto *UA = C.MakeAction<OffloadUnbundlingJobAction>(Input, InputType);
5419  UA->registerDependentActionInfo(TC, /*BoundArch=*/"",
5421  UA->setTargetString(TargetString.str());
5422 
5423  // Add lists to the final link.
5424  addDeps(UA, TC, "");
5425  }
5426  }
5427  if (!LinkObjects.empty()) {
5428  // The linkage actions subgraph leading to the offload wrapper.
5429  // [cond] Means incoming/outgoing dependence is created only when cond
5430  // is true. A function of:
5431  // n - target is NVPTX/AMDGCN
5432  // a - SPIRV AOT compilation is requested
5433  // s - device code split requested
5434  // r - relocatable device code is requested
5435  // f - link object output type is TY_Tempfilelist (fat archive)
5436  // e - Embedded IR for fusion (-fsycl-embed-ir) was requested
5437  // and target is NVPTX.
5438  // * - "all other cases"
5439  // - no condition means output/input is "always" present
5440  // First symbol indicates output/input type
5441  // . - single file output (TY_SPIRV, TY_LLVM_BC,...)
5442  // - - TY_Tempfilelist
5443  // + - TY_Tempfiletable
5444  //
5445  // .-----------------.
5446  // |Link(LinkObjects)|
5447  // .-----------------.
5448  // ----[-!rf] [*]
5449  // [-!rf] |
5450  // .-------------. |
5451  // | llvm-foreach| |
5452  // .-------------. |
5453  // [.] |
5454  // | |
5455  // | |
5456  // .---------------------------------------.
5457  // | PostLink |[+e]----------------
5458  // .---------------------------------------. |
5459  // [+*] [+] |
5460  // | | |
5461  // | | |
5462  // |--------- | |
5463  // | | | |
5464  // | | | |
5465  // | [+!rf] | |
5466  // | .-------------. | |
5467  // | | llvm-foreach| | |
5468  // | .-------------. | |
5469  // | | | |
5470  // [+*] [+!rf] | |
5471  // .-----------------. | |
5472  // | FileTableTform | | |
5473  // | (extract "Code")| | |
5474  // .-----------------. | |
5475  // [-] |----------- |
5476  // --------------------| | |
5477  // | | | |
5478  // | |----------------- | |
5479  // | | | | |
5480  // | | [-!rf] | |
5481  // | | .--------------. | |
5482  // | | |FileTableTform| | |
5483  // | | | (merge) | | |
5484  // | | .--------------. | |
5485  // | | [-] |------- |
5486  // | | | | | |
5487  // | | | ------| | |
5488  // | | --------| | | |
5489  // [.] [-*] [-!rf] [+!rf] | |
5490  // .---------------. .-------------------. .--------------. | |
5491  // | finalizeNVPTX | | SPIRVTranslator | |FileTableTform| | |
5492  // | finalizeAMDGCN | | | | (merge) | | |
5493  // .---------------. .-------------------. . -------------. | |
5494  // [.] [-as] [-!a] | | |
5495  // | | | | | |
5496  // | [-s] | | | |
5497  // | .----------------. | | | |
5498  // | | BackendCompile | | | | |
5499  // | .----------------. | ------| | |
5500  // | [-s] | | | |
5501  // | | | | | |
5502  // | [-a] [-!a] [-!rf] | |
5503  // | .--------------------. | |
5504  // -----------[-n]| FileTableTform |[+*]--------------| |
5505  // | (replace "Code") | |
5506  // .--------------------. |
5507  // | -------------------------
5508  // [+*] | [+e]
5509  // .--------------------------------------.
5510  // | OffloadWrapper |
5511  // .--------------------------------------.
5512  //
5513  ActionList FullLinkObjects;
5515  if (IsRDC) {
5516  Action *DeviceLinkAction =
5517  C.MakeAction<LinkJobAction>(LinkObjects, types::TY_LLVM_BC);
5518  FullLinkObjects.push_back(DeviceLinkAction);
5519  } else
5520  FullLinkObjects = LinkObjects;
5521 
5522  // FIXME: Link all wrapper and fallback device libraries as default,
5523  // When spv online link is supported by all backends, the fallback
5524  // device libraries are only needed when current toolchain is using
5525  // AOT compilation.
5526  bool SYCLDeviceLibLinked = false;
5527  if (IsSPIR || IsNVPTX) {
5528  bool UseJitLink =
5529  IsSPIR &&
5530  Args.hasFlag(options::OPT_fsycl_device_lib_jit_link,
5531  options::OPT_fno_sycl_device_lib_jit_link, false);
5532  bool UseAOTLink = IsSPIR && (IsSpirvAOT || !UseJitLink);
5533  SYCLDeviceLibLinked = addSYCLDeviceLibs(
5534  TC, SYCLDeviceLibs, UseAOTLink,
5535  C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment());
5536  }
5537  if (IsSYCLNativeCPU) {
5538  SYCLDeviceLibLinked |= addSYCLNativeCPULibs(TC, SYCLDeviceLibs);
5539  }
5540  JobAction *LinkSYCLLibs =
5541  C.MakeAction<LinkJobAction>(SYCLDeviceLibs, types::TY_LLVM_BC);
5542  for (Action *FullLinkObject : FullLinkObjects) {
5543  if (FullLinkObject->getKind() ==
5545  continue;
5546  Action *FullDeviceLinkAction = nullptr;
5547  ActionList WrapperInputs;
5548 
5549  if (SYCLDeviceLibLinked) {
5550  if (IsRDC) {
5551  // First object has to be non-DeviceLib for only-needed to be
5552  // passed.
5553  SYCLDeviceLibs.insert(SYCLDeviceLibs.begin(), FullLinkObject);
5554  FullDeviceLinkAction = C.MakeAction<LinkJobAction>(
5555  SYCLDeviceLibs, types::TY_LLVM_BC);
5556  } else {
5557  FullDeviceLinkAction = FullLinkObject;
5558 
5559  ActionList DeviceCodeAndSYCLLibs{FullDeviceLinkAction,
5560  LinkSYCLLibs};
5561  JobAction *LinkDeviceCode = C.MakeAction<LinkJobAction>(
5562  DeviceCodeAndSYCLLibs, types::TY_LLVM_BC);
5563 
5564  if (FullDeviceLinkAction->getType() == types::TY_Tempfilelist) {
5565  // If our compiler input outputs a temp file list (eg. fat
5566  // static archive), we need to link the device code against
5567  // each entry in the static archive.
5568  auto *ParallelLinkDeviceCode =
5569  C.MakeAction<ForEachWrappingAction>(
5570  cast<JobAction>(FullDeviceLinkAction), LinkDeviceCode);
5571  // The SYCL device library action tree should not be
5572  // for-eached, it only needs to happen once total. The
5573  // for-each action should start linking device code with the
5574  // device libraries.
5575  std::function<void(const Action *)> traverseActionTree =
5576  [&](const Action *Act) {
5577  ParallelLinkDeviceCode->addSerialAction(Act);
5578  for (const auto &Input : Act->getInputs()) {
5579  traverseActionTree(Input);
5580  }
5581  };
5582  traverseActionTree(LinkSYCLLibs);
5583  ActionList TformInputs{FullDeviceLinkAction,
5584  ParallelLinkDeviceCode};
5585  auto *ReplaceFilesAction =
5586  C.MakeAction<FileTableTformJobAction>(
5587  TformInputs, types::TY_Tempfilelist,
5588  types::TY_Tempfilelist);
5589  ReplaceFilesAction->addReplaceColumnTform(
5592  ReplaceFilesAction->addExtractColumnTform(
5593  FileTableTformJobAction::COL_ZERO, false /*drop titles*/);
5594  FullDeviceLinkAction = ReplaceFilesAction;
5595  } else {
5596  // If our compiler input is singular, just do a single link.
5597  FullDeviceLinkAction = LinkDeviceCode;
5598  }
5599  }
5600  } else
5601  FullDeviceLinkAction = FullLinkObject;
5602 
5603  // reflects whether current target is ahead-of-time and can't
5604  // support runtime setting of specialization constants
5605  bool IsAOT = IsNVPTX || IsAMDGCN || IsSpirvAOT || IsSYCLNativeCPU;
5606 
5607  // post link is not optional - even if not splitting, always need to
5608  // process specialization constants
5609  types::ID PostLinkOutType = IsSPIR || IsSYCLNativeCPU
5610  ? types::TY_Tempfiletable
5611  : types::TY_LLVM_BC;
5612  auto createPostLinkAction = [&]() {
5613  // For SPIR-V targets, force TY_Tempfiletable.
5614  auto TypedPostLinkAction = C.MakeAction<SYCLPostLinkJobAction>(
5615  FullDeviceLinkAction, PostLinkOutType, types::TY_Tempfiletable);
5616  TypedPostLinkAction->setRTSetsSpecConstants(!IsAOT);
5617  return TypedPostLinkAction;
5618  };
5619  Action *PostLinkAction = createPostLinkAction();
5620  if (IsSYCLNativeCPU) {
5621  // for SYCL Native CPU, we just take the linked device
5622  // modules, lower them to an object file , and link it to the host
5623  // object file.
5624  auto *BackendAct = C.MakeAction<BackendJobAction>(
5625  FullDeviceLinkAction, types::TY_PP_Asm);
5626  auto *AsmAct =
5627  C.MakeAction<AssembleJobAction>(BackendAct, types::TY_Object);
5628  addDeps(AsmAct, TC, BoundArch);
5629  auto *DeviceWrappingAction = C.MakeAction<OffloadWrapperJobAction>(
5630  PostLinkAction, types::TY_Object);
5631  addDeps(DeviceWrappingAction, TC, BoundArch);
5632  continue;
5633  }
5634  if ((IsNVPTX || IsAMDGCN) &&
5635  Args.hasArg(options::OPT_fsycl_embed_ir)) {
5636  // When compiling for Nvidia/AMD devices and the user requested the
5637  // IR to be embedded in the application (via option), run the output
5638  // of sycl-post-link (filetable referencing LLVM Bitcode + symbols)
5639  // through the offload wrapper and link the resulting object to the
5640  // application.
5641  auto *WrapBitcodeAction = C.MakeAction<OffloadWrapperJobAction>(
5642  PostLinkAction, types::TY_Object, true);
5643  addDeps(WrapBitcodeAction, TC, BoundArch);
5644  }
5645  bool NoRDCFatStaticArchive =
5646  !IsRDC &&
5647  FullDeviceLinkAction->getType() == types::TY_Tempfilelist;
5648  if (NoRDCFatStaticArchive)
5649  PostLinkAction = C.MakeAction<ForEachWrappingAction>(
5650  cast<JobAction>(FullDeviceLinkAction),
5651  cast<JobAction>(PostLinkAction));
5652 
5653  auto createExtractIRFilesAction = [&]() {
5654  auto *TypedExtractIRFilesAction =
5655  C.MakeAction<FileTableTformJobAction>(
5656  PostLinkAction,
5657  IsSPIR ? types::TY_Tempfilelist : PostLinkAction->getType(),
5658  types::TY_Tempfilelist);
5659  // single column w/o title fits TY_Tempfilelist format
5660  TypedExtractIRFilesAction->addExtractColumnTform(
5661  FileTableTformJobAction::COL_CODE, false /*drop titles*/);
5662  return TypedExtractIRFilesAction;
5663  };
5664 
5665  Action *ExtractIRFilesAction = createExtractIRFilesAction();
5666 
5667  if (IsNVPTX || IsAMDGCN) {
5668  JobAction *FinAction =
5669  IsNVPTX ? finalizeNVPTXDependences(ExtractIRFilesAction,
5670  TC->getTriple())
5671  : finalizeAMDGCNDependences(ExtractIRFilesAction,
5672  TC->getTriple());
5673  auto *ForEachWrapping = C.MakeAction<ForEachWrappingAction>(
5674  cast<JobAction>(ExtractIRFilesAction), FinAction);
5675 
5676  ActionList TformInputs{PostLinkAction, ForEachWrapping};
5677  auto *ReplaceFilesAction = C.MakeAction<FileTableTformJobAction>(
5678  TformInputs, types::TY_Tempfiletable, types::TY_Tempfiletable);
5679  ReplaceFilesAction->addReplaceColumnTform(
5682 
5683  WrapperInputs.push_back(ReplaceFilesAction);
5684  } else {
5685  if (NoRDCFatStaticArchive) {
5686  ExtractIRFilesAction = C.MakeAction<ForEachWrappingAction>(
5687  cast<JobAction>(FullDeviceLinkAction),
5688  cast<JobAction>(ExtractIRFilesAction));
5689 
5690  auto *MergeAllTablesIntoOne =
5691  C.MakeAction<FileTableTformJobAction>(ExtractIRFilesAction,
5692  types::TY_Tempfilelist,
5693  types::TY_Tempfilelist);
5694  MergeAllTablesIntoOne->addMergeTform(
5696  ExtractIRFilesAction = MergeAllTablesIntoOne;
5697  }
5698  // For SPIRV-based targets - translate to SPIRV then optionally
5699  // compile ahead-of-time to native architecture
5700  Action *BuildCodeAction = C.MakeAction<SPIRVTranslatorJobAction>(
5701  ExtractIRFilesAction, types::TY_Tempfilelist);
5702 
5703  // After the Link, wrap the files before the final host link
5704  if (IsAOT) {
5705  types::ID OutType = types::TY_Tempfilelist;
5706  if (!DeviceCodeSplit) {
5707  OutType = (TargetTriple.getSubArch() ==
5708  llvm::Triple::SPIRSubArch_fpga)
5709  ? FPGAOutType
5710  : types::TY_Image;
5711  }
5712  // Do the additional Ahead of Time compilation when the specific
5713  // triple calls for it (provided a valid subarch).
5714  ActionList BEInputs;
5715  BEInputs.push_back(BuildCodeAction);
5716  auto unbundleAdd = [&](Action *A, types::ID T) {
5717  ActionList AL;
5718  AL.push_back(A);
5719  Action *UnbundleAction =
5720  C.MakeAction<OffloadUnbundlingJobAction>(AL, T);
5721  BEInputs.push_back(UnbundleAction);
5722  };
5723  // Send any known objects/archives through the unbundler to grab
5724  // the dependency file associated. This is only done for
5725  // -fintelfpga.
5726  for (Action *A : FPGAObjectInputs)
5727  unbundleAdd(A, types::TY_FPGA_Dependencies);
5728  for (Action *A : FPGAArchiveInputs)
5729  unbundleAdd(A, types::TY_FPGA_Dependencies_List);
5730  for (const auto &A : FPGADeviceLibObjects)
5731  BEInputs.push_back(A);
5732  BuildCodeAction =
5733  C.MakeAction<BackendCompileJobAction>(BEInputs, OutType);
5734  }
5735  if (NoRDCFatStaticArchive) {
5736  auto *MergeAllTablesIntoOne =
5737  C.MakeAction<FileTableTformJobAction>(PostLinkAction,
5738  types::TY_Tempfilelist,
5739  types::TY_Tempfilelist);
5740  MergeAllTablesIntoOne->addMergeTform(
5742  PostLinkAction = MergeAllTablesIntoOne;
5743  }
5744  ActionList TformInputs{PostLinkAction, BuildCodeAction};
5745  auto *ReplaceFilesAction = C.MakeAction<FileTableTformJobAction>(
5746  TformInputs, types::TY_Tempfiletable, types::TY_Tempfiletable);
5747  ReplaceFilesAction->addReplaceColumnTform(
5750  WrapperInputs.push_back(ReplaceFilesAction);
5751  }
5752  if (SkipWrapper) {
5753  // Wrapper step not requested.
5754  withBoundArchForToolChain(TC, [&](const char *BoundArch) {
5755  addDeps(WrapperInputs.front(), TC, BoundArch);
5756  });
5757  continue;
5758  }
5759 
5760  // After the Link, wrap the files before the final host link
5761  // Add the unbundled wrapped AOC device binary to the wrapper
5762  // call.
5763  auto *DeviceWrappingAction = C.MakeAction<OffloadWrapperJobAction>(
5764  WrapperInputs, types::TY_Object);
5765 
5766  if (IsSpirvAOT) {
5767  // For FPGA with -fsycl-link, we need to bundle the output.
5768  if (TargetTriple.getSubArch() == llvm::Triple::SPIRSubArch_fpga) {
5769  Action *DeviceAction = DeviceWrappingAction;
5770  if (Args.hasArg(options::OPT_fsycl_link_EQ)) {
5771  // We do not want to compile the wrapped binary before the link.
5772  if (auto *OWA = dyn_cast<OffloadWrapperJobAction>(DeviceAction))
5773  OWA->setCompileStep(false);
5774  ActionList BundlingActions;
5775  BundlingActions.push_back(DeviceWrappingAction);
5776 
5777  // Wrap and compile the wrapped device device binary. This will
5778  // be used later when consumed as the input .bc file to retain
5779  // the symbols and properties associated.
5780  DeviceAction = C.MakeAction<OffloadWrapperJobAction>(
5781  BundlingActions, types::TY_Object);
5782  if (auto *OWA = dyn_cast<OffloadWrapperJobAction>(DeviceAction))
5784  Action *CompiledDeviceAction =
5785  C.MakeAction<OffloadWrapperJobAction>(WrapperInputs,
5786  types::TY_Object);
5787  addDeps(CompiledDeviceAction, TC, nullptr);
5788  }
5789  addDeps(DeviceAction, TC, nullptr);
5790  } else {
5791  bool AddBA =
5792  (TargetTriple.getSubArch() == llvm::Triple::SPIRSubArch_gen &&
5793  BoundArch != nullptr);
5794  addDeps(DeviceWrappingAction, TC, AddBA ? BoundArch : nullptr);
5795  }
5796  } else {
5797  withBoundArchForToolChain(TC, [&](const char *BoundArch) {
5798  addDeps(DeviceWrappingAction, TC, BoundArch);
5799  });
5800  }
5801  }
5802  }
5803  }
5804 
5805  bool addSYCLNativeCPULibs(const ToolChain *TC,
5806  ActionList &DeviceLinkObjects) {
5807  std::string LibSpirvFile;
5808  if (Args.hasArg(options::OPT_fsycl_libspirv_path_EQ)) {
5809  auto ProvidedPath =
5810  Args.getLastArgValue(options::OPT_fsycl_libspirv_path_EQ).str();
5811  if (llvm::sys::fs::exists(ProvidedPath))
5812  LibSpirvFile = ProvidedPath;
5813  } else {
5814  SmallVector<StringRef, 8> LibraryPaths;
5815 
5816  // Expected path w/out install.
5817  SmallString<256> WithoutInstallPath(C.getDriver().ResourceDir);
5818  llvm::sys::path::append(WithoutInstallPath, Twine("../../clc"));
5819  LibraryPaths.emplace_back(WithoutInstallPath.c_str());
5820 
5821  // Expected path w/ install.
5822  SmallString<256> WithInstallPath(C.getDriver().ResourceDir);
5823  llvm::sys::path::append(WithInstallPath, Twine("../../../share/clc"));
5824  LibraryPaths.emplace_back(WithInstallPath.c_str());
5825 
5826  // Select libclc variant based on target triple.
5827  // On Windows long is 32 bits, so we have to select the right remangled
5828  // libclc version.
5829  std::string LibSpirvTargetName =
5830  (TC->getAuxTriple()->isOSWindows())
5831  ? "remangled-l32-signed_char.libspirv-"
5832  : "remangled-l64-signed_char.libspirv-";
5833  LibSpirvTargetName.append(TC->getTripleString() + ".bc");
5834 
5835  for (StringRef LibraryPath : LibraryPaths) {
5836  SmallString<128> LibSpirvTargetFile(LibraryPath);
5837  llvm::sys::path::append(LibSpirvTargetFile, LibSpirvTargetName);
5838  if (llvm::sys::fs::exists(LibSpirvTargetFile) ||
5839  Args.hasArg(options::OPT__HASH_HASH_HASH)) {
5840  LibSpirvFile = std::string(LibSpirvTargetFile.str());
5841  break;
5842  }
5843  }
5844  }
5845 
5846  if (!LibSpirvFile.empty()) {
5847  Arg *LibClcInputArg = MakeInputArg(Args, C.getDriver().getOpts(),
5848  Args.MakeArgString(LibSpirvFile));
5849  auto *SYCLLibClcInputAction =
5850  C.MakeAction<InputAction>(*LibClcInputArg, types::TY_LLVM_BC);
5851  DeviceLinkObjects.push_back(SYCLLibClcInputAction);
5852  return true;
5853  }
5854  return false;
5855  }
5856 
5857  bool addSYCLDeviceLibs(const ToolChain *TC, ActionList &DeviceLinkObjects,
5858  bool isSpirvAOT, bool isMSVCEnv) {
5859  int NumOfDeviceLibLinked = 0;
5860  SmallVector<SmallString<128>, 4> LibLocCandidates;
5861  SYCLInstallation.getSYCLDeviceLibPath(LibLocCandidates);
5862 
5863  SmallVector<std::string, 8> DeviceLibraries;
5864  DeviceLibraries =
5865  tools::SYCL::getDeviceLibraries(C, TC->getTriple(), isSpirvAOT);
5866 
5867  for (const auto &DeviceLib : DeviceLibraries) {
5868  bool LibLocSelected = false;
5869  for (const auto &LLCandidate : LibLocCandidates) {
5870  if (LibLocSelected)
5871  break;
5872  SmallString<128> LibName(LLCandidate);
5873  llvm::sys::path::append(LibName, DeviceLib);
5874  if (llvm::sys::fs::exists(LibName)) {
5875  ++NumOfDeviceLibLinked;
5876  Arg *InputArg = MakeInputArg(Args, C.getDriver().getOpts(),
5877  Args.MakeArgString(LibName));
5878  if (TC->getTriple().isNVPTX() ||
5879  (TC->getTriple().isSPIR() &&
5880  TC->getTriple().getSubArch() ==
5881  llvm::Triple::SPIRSubArch_fpga)) {
5882  auto *SYCLDeviceLibsInputAction =
5883  C.MakeAction<InputAction>(*InputArg, types::TY_Object);
5884  auto *SYCLDeviceLibsUnbundleAction =
5885  C.MakeAction<OffloadUnbundlingJobAction>(
5886  SYCLDeviceLibsInputAction);
5887 
5888  // We are using BoundArch="" here since the NVPTX bundles in
5889  // the devicelib .o files do not contain any arch information
5890  SYCLDeviceLibsUnbundleAction->registerDependentActionInfo(
5891  TC, /*BoundArch=*/"", Action::OFK_SYCL);
5893  Dep.add(*SYCLDeviceLibsUnbundleAction, *TC, /*BoundArch=*/"",
5895  auto *SYCLDeviceLibsDependenciesAction =
5896  C.MakeAction<OffloadAction>(
5897  Dep, SYCLDeviceLibsUnbundleAction->getType());
5898  DeviceLinkObjects.push_back(SYCLDeviceLibsDependenciesAction);
5899  } else {
5900  // We are using the LLVM-IR device libraries directly, no need
5901  // to unbundle any objects.
5902  auto *SYCLDeviceLibsInputAction =
5903  C.MakeAction<InputAction>(*InputArg, types::TY_LLVM_BC);
5904  DeviceLinkObjects.push_back(SYCLDeviceLibsInputAction);
5905  }
5906  if (!LibLocSelected)
5907  LibLocSelected = !LibLocSelected;
5908  }
5909  }
5910  }
5911 
5912  // For NVPTX backend we need to also link libclc and CUDA libdevice
5913  // at the same stage that we link all of the unbundled SYCL libdevice
5914  // objects together.
5915  if (TC->getTriple().isNVPTX() && NumOfDeviceLibLinked) {
5916  std::string LibSpirvFile;
5917  if (Args.hasArg(options::OPT_fsycl_libspirv_path_EQ)) {
5918  auto ProvidedPath =
5919  Args.getLastArgValue(options::OPT_fsycl_libspirv_path_EQ).str();
5920  if (llvm::sys::fs::exists(ProvidedPath))
5921  LibSpirvFile = ProvidedPath;
5922  } else {
5923  SmallVector<StringRef, 8> LibraryPaths;
5924 
5925  // Expected path w/out install.
5926  SmallString<256> WithoutInstallPath(C.getDriver().ResourceDir);
5927  llvm::sys::path::append(WithoutInstallPath, Twine("../../clc"));
5928  LibraryPaths.emplace_back(WithoutInstallPath.c_str());
5929 
5930  // Expected path w/ install.
5931  SmallString<256> WithInstallPath(C.getDriver().ResourceDir);
5932  llvm::sys::path::append(WithInstallPath, Twine("../../../share/clc"));
5933  LibraryPaths.emplace_back(WithInstallPath.c_str());
5934 
5935  // Select remangled libclc variant
5936  std::string LibSpirvTargetName =
5937  (TC->getAuxTriple()->isOSWindows())
5938  ? "remangled-l32-signed_char.libspirv-nvptx64-nvidia-cuda."
5939  "bc"
5940  : "remangled-l64-signed_char.libspirv-nvptx64-nvidia-cuda."
5941  "bc";
5942 
5943  for (StringRef LibraryPath : LibraryPaths) {
5944  SmallString<128> LibSpirvTargetFile(LibraryPath);
5945  llvm::sys::path::append(LibSpirvTargetFile, LibSpirvTargetName);
5946  if (llvm::sys::fs::exists(LibSpirvTargetFile) ||
5947  Args.hasArg(options::OPT__HASH_HASH_HASH)) {
5948  LibSpirvFile = std::string(LibSpirvTargetFile.str());
5949  break;
5950  }
5951  }
5952  }
5953 
5954  if (!LibSpirvFile.empty()) {
5955  Arg *LibClcInputArg = MakeInputArg(Args, C.getDriver().getOpts(),
5956  Args.MakeArgString(LibSpirvFile));
5957  auto *SYCLLibClcInputAction =
5958  C.MakeAction<InputAction>(*LibClcInputArg, types::TY_LLVM_BC);
5959  DeviceLinkObjects.push_back(SYCLLibClcInputAction);
5960  }
5961 
5962  const toolchains::CudaToolChain *CudaTC =
5963  static_cast<const toolchains::CudaToolChain *>(TC);
5964  for (const auto &LinkInputEnum : enumerate(DeviceLinkerInputs)) {
5965  const char *BoundArch =
5966  SYCLTargetInfoList[LinkInputEnum.index()].BoundArch;
5967  std::string LibDeviceFile =
5968  CudaTC->CudaInstallation.getLibDeviceFile(BoundArch);
5969  if (!LibDeviceFile.empty()) {
5970  Arg *CudaDeviceLibInputArg =
5971  MakeInputArg(Args, C.getDriver().getOpts(),
5972  Args.MakeArgString(LibDeviceFile));
5973  auto *SYCLDeviceLibInputAction = C.MakeAction<InputAction>(
5974  *CudaDeviceLibInputArg, types::TY_LLVM_BC);
5975  DeviceLinkObjects.push_back(SYCLDeviceLibInputAction);
5976  }
5977  }
5978  }
5979  return NumOfDeviceLibLinked != 0;
5980  }
5981 
5982  void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {
5983  for (auto &SAI : SYCLAOTInputs) {
5984  // Extract binary file name
5985  std::string FN(SAI.second);
5986  const char *FNStr = Args.MakeArgString(FN);
5987  Arg *myArg = Args.MakeSeparateArg(
5988  nullptr, C.getDriver().getOpts().getOption(options::OPT_INPUT),
5989  FNStr);
5990  auto *SYCLAdd =
5991  C.MakeAction<InputAction>(*myArg, types::TY_SYCL_FATBIN);
5992  auto *DeviceWrappingAction =
5993  C.MakeAction<OffloadWrapperJobAction>(SYCLAdd, types::TY_Object);
5994 
5995  // Extract the target triple for this binary
5996  llvm::Triple TT(SAI.first);
5997  // Extract the toolchain for this target triple
5998  auto SYCLDeviceTC = llvm::find_if(
5999  ToolChains, [&](auto &TC) { return TC->getTriple() == TT; });
6000  assert(SYCLDeviceTC != ToolChains.end() &&
6001  "No toolchain found for this AOT input");
6002 
6003  DA.add(*DeviceWrappingAction, **SYCLDeviceTC,
6004  /*BoundArch=*/nullptr, Action::OFK_SYCL);
6005  }
6006  }
6007 
6008  void addDeviceLinkDependencies(OffloadDepsJobAction *DA) override {
6009  unsigned I = 0;
6010  for (auto &TargetInfo : SYCLTargetInfoList) {
6013  DeviceLinkerInputs[I++].push_back(DA);
6014  }
6015  }
6016 
6017  /// Initialize the GPU architecture list from arguments - this populates
6018  /// `GpuArchList` from `--offload-arch` flags. Only relevant if compiling to
6019  /// CUDA or AMDGCN. Return true if any initialization errors are found.
6020  /// FIXME: "offload-arch" and the BoundArch mechanism should also be
6021  // used in the SYCLToolChain for SPIR-V AOT to track the offload
6022  // architecture instead of the Triple sub-arch it currently uses.
6023  bool initializeGpuArchMap() {
6024  const OptTable &Opts = C.getDriver().getOpts();
6025  for (auto *A : Args) {
6026  unsigned Index;
6027  llvm::Triple *TargetBE = nullptr;
6028 
6029  auto GetTripleIt = [&, this](llvm::StringRef Triple) {
6030  llvm::Triple TargetTriple{Triple};
6031  auto TripleIt = llvm::find_if(SYCLTripleList, [&](auto &SYCLTriple) {
6032  return SYCLTriple == TargetTriple;
6033  });
6034  return TripleIt != SYCLTripleList.end() ? &*TripleIt : nullptr;
6035  };
6036 
6037  if (A->getOption().matches(options::OPT_Xsycl_backend_EQ)) {
6038  TargetBE = GetTripleIt(A->getValue(0));
6039  // Passing device args: -Xsycl-target-backend=<triple> -opt=val.
6040  if (TargetBE)
6041  Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
6042  else
6043  continue;
6044  } else if (A->getOption().matches(options::OPT_Xsycl_backend)) {
6045  if (SYCLTripleList.size() > 1) {
6046  C.getDriver().Diag(diag::err_drv_Xsycl_target_missing_triple)
6047  << A->getSpelling();
6048  continue;
6049  }
6050  // Passing device args: -Xsycl-target-backend -opt=val.
6051  TargetBE = &SYCLTripleList.front();
6052  Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
6053  } else
6054  continue;
6055 
6056  auto ParsedArg = Opts.ParseOneArg(Args, Index);
6057 
6058  // TODO: Support --no-cuda-gpu-arch, --{,no-}cuda-gpu-arch=all.
6059  if (ParsedArg &&
6060  ParsedArg->getOption().matches(options::OPT_offload_arch_EQ)) {
6061  const char *ArchStr = ParsedArg->getValue(0);
6062  if (TargetBE->isNVPTX()) {
6063  // CUDA arch also applies to AMDGCN ...
6064  CudaArch Arch = StringToCudaArch(ArchStr);
6065  if (Arch == CudaArch::UNKNOWN || !IsNVIDIAGpuArch(Arch)) {
6066  C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch)
6067  << ArchStr;
6068  continue;
6069  }
6070  ArchStr = CudaArchToString(Arch);
6071  } else if (TargetBE->isAMDGCN()) {
6072  llvm::StringMap<bool> Features;
6073  auto Arch = parseTargetID(
6074  *getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs()),
6075  ArchStr, &Features);
6076  if (!Arch) {
6077  C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
6078  continue;
6079  }
6080  auto CanId = getCanonicalTargetID(Arch.value(), Features);
6081  ArchStr = Args.MakeArgStringRef(CanId);
6082  }
6083  ParsedArg->claim();
6084  GpuArchList.emplace_back(*TargetBE, ArchStr);
6085  A->claim();
6086  }
6087  }
6088 
6089  // Handle defaults architectures
6090  for (auto &Triple : SYCLTripleList) {
6091  // For NVIDIA use SM_50 as a default
6092  if (Triple.isNVPTX() && llvm::none_of(GpuArchList, [&](auto &P) {
6093  return P.first.isNVPTX();
6094  })) {
6095  const char *DefaultArch = CudaArchToString(CudaArch::SM_50);
6096  GpuArchList.emplace_back(Triple, DefaultArch);
6097  }
6098 
6099  // For AMD require the architecture to be set by the user
6100  if (Triple.isAMDGCN() && llvm::none_of(GpuArchList, [&](auto &P) {
6101  return P.first.isAMDGCN();
6102  })) {
6103  C.getDriver().Diag(clang::diag::err_drv_sycl_missing_amdgpu_arch)
6104  << (SYCLTripleList.size() > 1) << Triple.str();
6105  return true;
6106  }
6107  }
6108 
6109  return false;
6110  }
6111 
6112  // Goes through all of the arguments, including inputs expected for the
6113  // linker directly, to determine if the targets contained in the objects and
6114  // archives match target expectations being performed.
6115  void
6116  checkForOffloadMismatch(Compilation &C, DerivedArgList &Args,
6117  SmallVector<DeviceTargetInfo, 4> &Targets) const {
6118  if (Targets.empty())
6119  return;
6120 
6121  SmallVector<const char *, 16> OffloadLibArgs(
6122  getLinkerArgs(C, Args, true));
6123  // Gather all of the sections seen in the offload objects/archives
6124  SmallVector<std::string, 4> UniqueSections;
6125  for (StringRef OLArg : OffloadLibArgs) {
6126  SmallVector<std::string, 4> Sections(getOffloadSections(C, OLArg));
6127  for (auto &Section : Sections) {
6128  // We only care about sections that start with 'sycl-'. Also remove
6129  // the prefix before adding it.
6130  std::string Prefix("sycl-");
6131  if (Section.compare(0, Prefix.length(), Prefix) != 0)
6132  continue;
6133 
6134  std::string Arch = Section.substr(Prefix.length());
6135 
6136  // There are a few different variants for FPGA, if we see one, just
6137  // use the default FPGA triple to reduce possible match confusion.
6138  if (Arch.compare(0, 4, "fpga") == 0)
6139  Arch = C.getDriver().MakeSYCLDeviceTriple("spir64_fpga").str();
6140 
6141  if (std::find(UniqueSections.begin(), UniqueSections.end(), Arch) ==
6142  UniqueSections.end())
6143  UniqueSections.push_back(Arch);
6144  }
6145  }
6146 
6147  if (!UniqueSections.size())
6148  return;
6149 
6150  for (auto &SyclTarget : Targets) {
6151  std::string SectionTriple = SyclTarget.TC->getTriple().str();
6152  if (SyclTarget.BoundArch) {
6153  SectionTriple += "-";
6154  SectionTriple += SyclTarget.BoundArch;
6155  }
6156  // If any matching section is found, we are good.
6157  if (std::find(UniqueSections.begin(), UniqueSections.end(),
6158  SectionTriple) != UniqueSections.end())
6159  continue;
6160  // If any section found is an 'image' based object that was created
6161  // with the intention of not requiring the matching SYCL target, do
6162  // not emit the diagnostic.
6163  if (SyclTarget.TC->getTriple().isSPIROrSPIRV()) {
6164  bool SectionFound = false;
6165  for (auto Section : UniqueSections) {
6166  if (SectionFound)
6167  break;
6168  SmallVector<std::string, 3> ArchList = {"spir64_gen", "spir64_fpga",
6169  "spir64_x86_64"};
6170  for (auto ArchStr : ArchList) {
6171  std::string Arch(ArchStr + "_image");
6172  if (Section.find(Arch) != std::string::npos) {
6173  SectionFound = true;
6174  break;
6175  }
6176  }
6177  }
6178  if (SectionFound)
6179  continue;
6180  }
6181  // Didn't find any matches, return the full list for the diagnostic.
6182  SmallString<128> ArchListStr;
6183  int Cnt = 0;
6184  for (std::string Section : UniqueSections) {
6185  if (Cnt)
6186  ArchListStr += ", ";
6187  ArchListStr += Section;
6188  Cnt++;
6189  }
6191  C.getDriver().Diag(diag::err_drv_no_rdc_sycl_target_missing)
6192  << SectionTriple << ArchListStr;
6193  C.setContainsError();
6194  } else {
6195  C.getDriver().Diag(diag::warn_drv_sycl_target_missing)
6196  << SectionTriple << ArchListStr;
6197  }
6198  }
6199  }
6200 
6201  // Function checks that user passed -fsycl-add-default-spec-consts-image
6202  // flag with at least one AOT target. If no AOT target has been passed then
6203  // a warning is issued.
6204  void checkForMisusedAddDefaultSpecConstsImageFlag(
6205  Compilation &C, const DerivedArgList &Args,
6206  const SmallVector<DeviceTargetInfo, 4> &Targets) const {
6207  if (!Args.hasFlag(options::OPT_fsycl_add_default_spec_consts_image,
6208  options::OPT_fno_sycl_add_default_spec_consts_image,
6209  false))
6210  return;
6211 
6212  bool foundAOT = std::any_of(
6213  Targets.begin(), Targets.end(), [](const DeviceTargetInfo &DTI) {
6214  llvm::Triple T = DTI.TC->getTriple();
6215  bool isSpirvAOT =
6216  T.getSubArch() == llvm::Triple::SPIRSubArch_fpga ||
6217  T.getSubArch() == llvm::Triple::SPIRSubArch_gen ||
6218  T.getSubArch() == llvm::Triple::SPIRSubArch_x86_64;
6219 
6220  return T.isNVPTX() || T.isAMDGCN() || isSpirvAOT;
6221  });
6222 
6223  if (!foundAOT)
6224  C.getDriver().Diag(
6225  diag::warn_drv_fsycl_add_default_spec_consts_image_flag_in_non_AOT);
6226  }
6227 
6228  // Go through the offload sections of the provided binary. Gather all
6229  // all of the sections which match the expected format of the triple
6230  // generated when creating fat objects that contain full device binaries.
6231  // Expected format is sycl-<aot_arch>_image-unknown-unknown.
6232  // <aot_arch> values: spir64_gen, spir64_x86_64, spir64_fpga
6233  SmallVector<std::string, 4> deviceBinarySections(Compilation &C,
6234  const StringRef &Input) {
6235  SmallVector<std::string, 4> Sections(getOffloadSections(C, Input));
6236  SmallVector<std::string, 4> FinalDeviceSections;
6237  for (auto S : Sections) {
6238  SmallVector<std::string, 3> ArchList = {"spir64_gen", "spir64_fpga",
6239  "spir64_x86_64"};
6240  for (auto A : ArchList) {
6241  std::string Arch("sycl-" + A + "_image");
6242  if (S.find(Arch) != std::string::npos)
6243  FinalDeviceSections.push_back(S);
6244  }
6245  }
6246  return FinalDeviceSections;
6247  }
6248 
6249  /// Reads device config file to find information about the SYCL targets in
6250  /// `Targets`, and defines device traits macros accordingly.
6251  void populateSYCLDeviceTraitsMacrosArgs(
6252  Compilation &C, const DerivedArgList &Args,
6253  const SmallVector<DeviceTargetInfo, 4> &Targets) const {
6254  if (Targets.empty())
6255  return;
6256 
6257  const auto &TargetTable = DeviceConfigFile::TargetTable;
6258  std::map<StringRef, unsigned int> AllDevicesHave;
6259  std::map<StringRef, bool> AnyDeviceHas;
6260  bool AnyDeviceHasAnyAspect = false;
6261  unsigned int ValidTargets = 0;
6262  for (const auto &[TC, BoundArch] : Targets) {
6263  assert(TC && "Invalid SYCL Offload Toolchain");
6264  // Try and find the device arch, if it's empty, try to search for either
6265  // the whole Triple or just the 'ArchName' string.
6266  auto TargetIt = TargetTable.end();
6267  const llvm::Triple &TargetTriple = TC->getTriple();
6268  const StringRef TargetArch{BoundArch};
6269  if (!TargetArch.empty()) {
6270  TargetIt = llvm::find_if(TargetTable, [&](const auto &Value) {
6271  using namespace tools::SYCL;
6272  StringRef Device{Value.first};
6273  if (Device.consume_front(gen::AmdGPU))
6274  return TargetArch == Device && TargetTriple.isAMDGCN();
6275  if (Device.consume_front(gen::NvidiaGPU))
6276  return TargetArch == Device && TargetTriple.isNVPTX();
6277  if (Device.consume_front(gen::IntelGPU))
6278  return TargetArch == Device && TargetTriple.isSPIRAOT();
6279  return TargetArch == Device && isValidSYCLTriple(TargetTriple);
6280  });
6281  } else {
6282  TargetIt = TargetTable.find(TargetTriple.str());
6283  if (TargetIt == TargetTable.end())
6284  TargetIt = TargetTable.find(TargetTriple.getArchName().str());
6285  }
6286 
6287  if (TargetIt != TargetTable.end()) {
6288  const DeviceConfigFile::TargetInfo &Info = (*TargetIt).second;
6289  ++ValidTargets;
6290  const auto &AspectList = Info.aspects;
6291  const auto &MaySupportOtherAspects = Info.maySupportOtherAspects;
6292  if (!AnyDeviceHasAnyAspect)
6293  AnyDeviceHasAnyAspect = MaySupportOtherAspects;
6294  for (const auto &Aspect : AspectList) {
6295  // If target has an entry in the config file, the set of aspects
6296  // supported by all devices supporting the target is 'AspectList'.
6297  // If there's no entry, such set is empty.
6298  const auto &AspectIt = AllDevicesHave.find(Aspect);
6299  if (AspectIt != AllDevicesHave.end())
6300  ++AllDevicesHave[Aspect];
6301  else
6302  AllDevicesHave[Aspect] = 1;
6303  // If target has an entry in the config file AND
6304  // 'MaySupportOtherAspects' is false, the set of aspects supported
6305  // by any device supporting the target is 'AspectList'. If there's
6306  // no entry OR 'MaySupportOtherAspects' is true, such set contains
6307  // all the aspects.
6308  AnyDeviceHas[Aspect] = true;
6309  }
6310  }
6311  }
6312 
6313  // If there's no entry for the target in the device config file, the set
6314  // of aspects supported by any device supporting the target contains all
6315  // the aspects.
6316  if (ValidTargets == 0)
6317  AnyDeviceHasAnyAspect = true;
6318 
6319  const Driver &D = C.getDriver();
6320  if (AnyDeviceHasAnyAspect) {
6321  // There exists some target that supports any given aspect.
6322  constexpr static StringRef MacroAnyDeviceAnyAspect{
6323  "-D__SYCL_ANY_DEVICE_HAS_ANY_ASPECT__=1"};
6324  D.addSYCLDeviceTraitsMacroArg(Args, MacroAnyDeviceAnyAspect);
6325  } else {
6326  // Some of the aspects are not supported at all by any of the targets.
6327  // Thus, we need to define individual macros for each supported aspect.
6328  for (const auto &[TargetKey, SupportedTarget] : AnyDeviceHas) {
6329  assert(SupportedTarget);
6330  const SmallString<64> MacroAnyDevice{
6331  {"-D__SYCL_ANY_DEVICE_HAS_", TargetKey, "__=1"}};
6332  D.addSYCLDeviceTraitsMacroArg(Args, MacroAnyDevice);
6333  }
6334  }
6335  for (const auto &[TargetKey, SupportedTargets] : AllDevicesHave) {
6336  if (SupportedTargets != ValidTargets)
6337  continue;
6338  const SmallString<64> MacroAllDevices{
6339  {"-D__SYCL_ALL_DEVICES_HAVE_", TargetKey, "__=1"}};
6340  D.addSYCLDeviceTraitsMacroArg(Args, MacroAllDevices);
6341  }
6342  }
6343 
6344  bool initialize() override {
6345  using namespace tools::SYCL;
6346  // Get the SYCL toolchains. If we don't get any, the action builder will
6347  // know there is nothing to do related to SYCL offloading.
6348  auto SYCLTCRange = C.getOffloadToolChains<Action::OFK_SYCL>();
6349  for (auto TI = SYCLTCRange.first, TE = SYCLTCRange.second; TI != TE;
6350  ++TI)
6351  ToolChains.push_back(TI->second);
6352 
6353  // Nothing to offload if no SYCL Toolchain
6354  if (ToolChains.empty())
6355  return false;
6356 
6357  auto *DeviceCodeSplitArg =
6358  Args.getLastArg(options::OPT_fsycl_device_code_split_EQ);
6359  // -fsycl-device-code-split is an alias to
6360  // -fsycl-device-code-split=auto
6361  DeviceCodeSplit = DeviceCodeSplitArg &&
6362  DeviceCodeSplitArg->getValue() != StringRef("off");
6363  // Gather information about the SYCL Ahead of Time targets. The targets
6364  // are determined on the SubArch values passed along in the triple.
6365  Arg *SYCLTargets =
6366  C.getInputArgs().getLastArg(options::OPT_fsycl_targets_EQ);
6367  Arg *SYCLfpga = C.getInputArgs().getLastArg(options::OPT_fintelfpga);
6368  bool HasValidSYCLRuntime = C.getInputArgs().hasFlag(
6369  options::OPT_fsycl, options::OPT_fno_sycl, false);
6370  bool SYCLfpgaTriple = false;
6371  bool ShouldAddDefaultTriple = true;
6372  bool GpuInitHasErrors = false;
6373  bool HasSYCLTargetsOption = SYCLTargets;
6374 
6375  // Make -fintelfpga flag imply -fsycl.
6376  if (SYCLfpga && !HasValidSYCLRuntime)
6377  HasValidSYCLRuntime = true;
6378 
6379  if (HasSYCLTargetsOption) {
6380  if (SYCLTargets) {
6381  Arg *SYCLTargetsValues = SYCLTargets;
6382  // Fill SYCLTripleList
6383  llvm::StringMap<StringRef> FoundNormalizedTriples;
6384  for (StringRef Val : SYCLTargetsValues->getValues()) {
6385  StringRef UserTargetName(Val);
6386  if (auto ValidDevice = gen::isGPUTarget<gen::IntelGPU>(Val)) {
6387  if (ValidDevice->empty())
6388  // Unrecognized, we have already diagnosed this earlier; skip.
6389  continue;
6390  // Add the proper -device value to the list.
6391  GpuArchList.emplace_back(C.getDriver().MakeSYCLDeviceTriple(
6392  "spir64_gen"), ValidDevice->data());
6393  UserTargetName = "spir64_gen";
6394  } else if (auto ValidDevice =
6395  gen::isGPUTarget<gen::NvidiaGPU>(Val)) {
6396  if (ValidDevice->empty())
6397  // Unrecognized, we have already diagnosed this earlier; skip.
6398  continue;
6399  // Add the proper -device value to the list.
6400  GpuArchList.emplace_back(
6401  C.getDriver().MakeSYCLDeviceTriple("nvptx64-nvidia-cuda"),
6402  ValidDevice->data());
6403  UserTargetName = "nvptx64-nvidia-cuda";
6404  } else if (auto ValidDevice = gen::isGPUTarget<gen::AmdGPU>(Val)) {
6405  if (ValidDevice->empty())
6406  // Unrecognized, we have already diagnosed this earlier; skip.
6407  continue;
6408  // Add the proper -device value to the list.
6409  GpuArchList.emplace_back(
6410  C.getDriver().MakeSYCLDeviceTriple("amdgcn-amd-amdhsa"),
6411  ValidDevice->data());
6412  UserTargetName = "amdgcn-amd-amdhsa";
6413  } else if (Val == "native_cpu") {
6414  const ToolChain *HostTC =
6415  C.getSingleOffloadToolChain<Action::OFK_Host>();
6416  llvm::Triple TT = HostTC->getTriple();
6417  SYCLTripleList.push_back(TT);
6418  continue;
6419  }
6420 
6421  llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple(Val));
6422  std::string NormalizedName = TT.normalize();
6423 
6424  // Make sure we don't have a duplicate triple.
6425  auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
6426  if (Duplicate != FoundNormalizedTriples.end())
6427  continue;
6428 
6429  // Store the current triple so that we can check for duplicates in
6430  // the following iterations.
6431  FoundNormalizedTriples[NormalizedName] = Val;
6432 
6433  SYCLTripleList.push_back(
6434  C.getDriver().MakeSYCLDeviceTriple(UserTargetName));
6435  if (TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga)
6436  SYCLfpgaTriple = true;
6437  // For user specified spir64_gen, add an empty device value as a
6438  // placeholder.
6439  if (TT.getSubArch() == llvm::Triple::SPIRSubArch_gen)
6440  GpuArchList.emplace_back(TT, nullptr);
6441  }
6442 
6443  // Fill GpuArchList, end if there are issues in initializingGpuArchMap
6444  GpuInitHasErrors = initializeGpuArchMap();
6445  if (GpuInitHasErrors)
6446  return true;
6447 
6448  int I = 0;
6449  // Fill SYCLTargetInfoList
6450  for (auto &TT : SYCLTripleList) {
6451  auto TCIt = llvm::find_if(
6452  ToolChains, [&](auto &TC) { return TT == TC->getTriple(); });
6453  assert(TCIt != ToolChains.end() &&
6454  "Toolchain was not created for this platform");
6455  if (!TT.isNVPTX() && !TT.isAMDGCN()) {
6456  // When users specify the target as 'intel_gpu_*', the proper
6457  // triple is 'spir64_gen'. The given string from intel_gpu_*
6458  // is the target device.
6459  if (TT.isSPIR() &&
6460  TT.getSubArch() == llvm::Triple::SPIRSubArch_gen) {
6461  StringRef Device(GpuArchList[I].second);
6462  SYCLTargetInfoList.emplace_back(
6463  *TCIt, Device.empty() ? nullptr : Device.data());
6464  ++I;
6465  continue;
6466  }
6467  SYCLTargetInfoList.emplace_back(*TCIt, nullptr);
6468  } else {
6469  const char *OffloadArch = nullptr;
6470  for (auto &A : GpuArchList) {
6471  if (TT == A.first) {
6472  OffloadArch = A.second;
6473  break;
6474  }
6475  }
6476  assert(OffloadArch && "Failed to find matching arch.");
6477  SYCLTargetInfoList.emplace_back(*TCIt, OffloadArch);
6478  ++I;
6479  }
6480  }
6481  }
6482  } else if (HasValidSYCLRuntime) {
6483  // -fsycl is provided without -fsycl-*targets.
6484  bool SYCLfpga = C.getInputArgs().hasArg(options::OPT_fintelfpga);
6485  // -fsycl -fintelfpga implies spir64_fpga
6486  const char *SYCLTargetArch =
6487  SYCLfpga ? "spir64_fpga" : getDefaultSYCLArch(C);
6488  llvm::Triple TT = C.getDriver().MakeSYCLDeviceTriple(SYCLTargetArch);
6489  auto TCIt = llvm::find_if(
6490  ToolChains, [&](auto &TC) { return TT == TC->getTriple(); });
6491  assert(TCIt != ToolChains.end() &&
6492  "Toolchain was not created for this platform");
6493  SYCLTripleList.push_back(TT);
6494  SYCLTargetInfoList.emplace_back(*TCIt, nullptr);
6495  if (SYCLfpga)
6496  SYCLfpgaTriple = true;
6497  }
6498 
6499  WrapDeviceOnlyBinary =
6500  Args.hasArg(options::OPT_fsycl_link_EQ) && !SYCLfpgaTriple;
6501  // Device only compilation for -fsycl-link (no FPGA)
6502  CompileDeviceOnly = WrapDeviceOnlyBinary;
6503 
6504  // Set the FPGA output type based on command line (-fsycl-link).
6505  if (auto *A = C.getInputArgs().getLastArg(options::OPT_fsycl_link_EQ)) {
6506  FPGAOutType = (A->getValue() == StringRef("early"))
6507  ? types::TY_FPGA_AOCR
6508  : types::TY_FPGA_AOCX;
6509  if (C.getDriver().IsFPGAEmulationMode())
6510  FPGAOutType = (A->getValue() == StringRef("early"))
6511  ? types::TY_FPGA_AOCR_EMU
6512  : types::TY_FPGA_AOCX;
6513  }
6514 
6515  auto makeInputAction = [&](const StringRef Name,
6516  types::ID Type) -> Action * {
6517  const llvm::opt::OptTable &Opts = C.getDriver().getOpts();
6518  Arg *InputArg = MakeInputArg(Args, Opts, Args.MakeArgString(Name));
6519  Action *Current = C.MakeAction<InputAction>(*InputArg, Type);
6520  return Current;
6521  };
6522  // Populate FPGA archives that could contain dep files to be
6523  // incorporated into the aoc compilation. Consider AOCR type archives
6524  // as well for tracking symbols and properties information.
6525  if (SYCLfpgaTriple && Args.hasArg(options::OPT_fintelfpga)) {
6526  SmallVector<const char *, 16> LinkArgs(getLinkerArgs(C, Args));
6527  for (StringRef LA : LinkArgs) {
6528  if (isStaticArchiveFile(LA) && hasOffloadSections(C, LA, Args)) {
6529  FPGAArchiveInputs.push_back(makeInputAction(LA, types::TY_Archive));
6530  for (types::ID Type : {types::TY_FPGA_AOCR, types::TY_FPGA_AOCR_EMU,
6531  types::TY_FPGA_AOCX}) {
6532  if (hasFPGABinary(C, LA.str(), Type)) {
6533  FPGAAOCArchives.push_back(makeInputAction(LA, Type));
6534  break;
6535  }
6536  }
6537  }
6538  }
6539  }
6540  // Discover any objects and archives that contain final device binaries.
6541  if (HasValidSYCLRuntime) {
6542  SmallVector<const char *, 16> LinkArgs(getLinkerArgs(C, Args, true));
6543  for (StringRef LA : LinkArgs) {
6544  SmallVector<std::string, 4> DeviceTargets(
6545  deviceBinarySections(C, LA));
6546  if (!DeviceTargets.empty()) {
6547  bool IsArchive = isStaticArchiveFile(LA);
6549  IsArchive ? types::TY_Archive : types::TY_Object;
6550  SYCLFinalDeviceList.push_back(
6551  std::make_pair(makeInputAction(LA, FileType), DeviceTargets));
6552  }
6553  }
6554  }
6555 
6556  if (ShouldAddDefaultTriple && addSYCLDefaultTriple(C, SYCLTripleList)) {
6557  // If a SYCLDefaultTriple is added to SYCLTripleList,
6558  // add new target to SYCLTargetInfoList
6559  llvm::Triple TT = SYCLTripleList.front();
6560  auto TCIt = llvm::find_if(
6561  ToolChains, [&](auto &TC) { return TT == TC->getTriple(); });
6562  SYCLTargetInfoList.emplace_back(*TCIt, nullptr);
6563  }
6564  if (SYCLTargetInfoList.empty()) {
6565  // If there are no SYCL Targets add the front toolchain, this is for
6566  // `-fsycl-device-only` is provided with no `fsycl` or when all dummy
6567  // targets are given
6568  const auto *TC = ToolChains.front();
6569  SYCLTargetInfoList.emplace_back(TC, nullptr);
6570  }
6571 
6572  checkForOffloadMismatch(C, Args, SYCLTargetInfoList);
6573  checkForMisusedAddDefaultSpecConstsImageFlag(C, Args, SYCLTargetInfoList);
6574 
6575  // Define macros associated with `any_device_has/all_devices_have`
6576  // according to the aspects defined in the DeviceConfigFile for the SYCL
6577  // targets.
6578  populateSYCLDeviceTraitsMacrosArgs(C, Args, SYCLTargetInfoList);
6579 
6580  DeviceLinkerInputs.resize(SYCLTargetInfoList.size());
6581  return false;
6582  }
6583 
6584  bool canUseBundlerUnbundler() const override {
6585  // SYCL should use bundled files whenever possible.
6586  return true;
6587  }
6588  };
6589 
6590  ///
6591  /// TODO: Add the implementation for other specialized builders here.
6592  ///
6593 
6594  /// Specialized builders being used by this offloading action builder.
6595  SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
6596 
6597  /// Flag set to true if all valid builders allow file bundling/unbundling.
6598  bool CanUseBundler;
6599 
6600 public:
6601  OffloadingActionBuilder(Compilation &C, DerivedArgList &Args,
6602  const Driver::InputList &Inputs)
6603  : C(C) {
6604  // Create a specialized builder for each device toolchain.
6605 
6606  IsValid = true;
6607 
6608  // Create a specialized builder for CUDA.
6609  SpecializedBuilders.push_back(
6610  new CudaActionBuilder(C, Args, Inputs, *this));
6611 
6612  // Create a specialized builder for HIP.
6613  SpecializedBuilders.push_back(new HIPActionBuilder(C, Args, Inputs, *this));
6614 
6615  // Create a specialized builder for OpenMP.
6616  SpecializedBuilders.push_back(
6617  new OpenMPActionBuilder(C, Args, Inputs, *this));
6618 
6619  // Create a specialized builder for SYCL.
6620  SpecializedBuilders.push_back(
6621  new SYCLActionBuilder(C, Args, Inputs, *this));
6622 
6623  //
6624  // TODO: Build other specialized builders here.
6625  //
6626 
6627  // Initialize all the builders, keeping track of errors. If all valid
6628  // builders agree that we can use bundling, set the flag to true.
6629  unsigned ValidBuilders = 0u;
6630  unsigned ValidBuildersSupportingBundling = 0u;
6631  for (auto *SB : SpecializedBuilders) {
6632  IsValid = IsValid && !SB->initialize();
6633 
6634  // Update the counters if the builder is valid.
6635  if (SB->isValid()) {
6636  ++ValidBuilders;
6637  if (SB->canUseBundlerUnbundler())
6638  ++ValidBuildersSupportingBundling;
6639  }
6640  }
6641  CanUseBundler =
6642  ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
6643  }
6644 
6645  ~OffloadingActionBuilder() {
6646  for (auto *SB : SpecializedBuilders)
6647  delete SB;
6648  }
6649 
6650  /// Push an action coming from a specialized DeviceActionBuilder (i.e.,
6651  /// foreign action) to the other ones
6652  void pushForeignAction(Action *A) {
6653  for (auto *SB : SpecializedBuilders) {
6654  if (SB->isValid())
6655  SB->pushForeignAction(A);
6656  }
6657  }
6658 
6659  /// Record a host action and its originating input argument.
6660  void recordHostAction(Action *HostAction, const Arg *InputArg) {
6661  assert(HostAction && "Invalid host action");
6662  assert(InputArg && "Invalid input argument");
6663  auto Loc = HostActionToInputArgMap.find(HostAction);
6664  if (Loc == HostActionToInputArgMap.end())
6665  HostActionToInputArgMap[HostAction] = InputArg;
6666  assert(HostActionToInputArgMap[HostAction] == InputArg &&
6667  "host action mapped to multiple input arguments");
6668  }
6669 
6670  /// Generate an action that adds device dependences (if any) to a host action.
6671  /// If no device dependence actions exist, just return the host action \a
6672  /// HostAction. If an error is found or if no builder requires the host action
6673  /// to be generated, return nullptr.
6674  Action *
6675  addDeviceDependencesToHostAction(Action *HostAction, const Arg *InputArg,
6676  phases::ID CurPhase, phases::ID FinalPhase,
6677  DeviceActionBuilder::PhasesTy &Phases) {
6678  if (!IsValid)
6679  return nullptr;
6680 
6681  if (SpecializedBuilders.empty())
6682  return HostAction;
6683 
6684  assert(HostAction && "Invalid host action!");
6685  recordHostAction(HostAction, InputArg);
6686 
6688  // Check if all the programming models agree we should not emit the host
6689  // action. Also, keep track of the offloading kinds employed.
6690  auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
6691  unsigned InactiveBuilders = 0u;
6692  unsigned IgnoringBuilders = 0u;
6693  for (auto *SB : SpecializedBuilders) {
6694  if (!SB->isValid()) {
6695  ++InactiveBuilders;
6696  continue;
6697  }
6698  auto RetCode =
6699  SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
6700 
6701  // If the builder explicitly says the host action should be ignored,
6702  // we need to increment the variable that tracks the builders that request
6703  // the host object to be ignored.
6704  if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
6705  ++IgnoringBuilders;
6706 
6707  // Unless the builder was inactive for this action, we have to record the
6708  // offload kind because the host will have to use it.
6709  if (RetCode != DeviceActionBuilder::ABRT_Inactive)
6710  OffloadKind |= SB->getAssociatedOffloadKind();
6711  }
6712 
6713  // If all builders agree that the host object should be ignored, just return
6714  // nullptr.
6715  if (IgnoringBuilders &&
6716  SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
6717  return nullptr;
6718 
6719  if (DDeps.getActions().empty())
6720  return HostAction;
6721 
6722  // Add host-cuda-sycl offload kind for the SYCL compilation of .cu files
6723  if (OffloadKind == (Action::OFK_Cuda | Action::OFK_SYCL)) {
6725  *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
6726  /*BoundArch=*/nullptr, Action::OFK_SYCL | Action::OFK_Cuda);
6727  return C.MakeAction<OffloadAction>(HDep, DDeps);
6728  }
6729 
6730  // We have dependences we need to bundle together. We use an offload action
6731  // for that.
6733  *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
6734  /*BoundArch=*/nullptr, DDeps);
6735  return C.MakeAction<OffloadAction>(HDep, DDeps);
6736  }
6737 
6738  // Update Input action to reflect FPGA device archive specifics based
6739  // on archive contents.
6740  bool updateInputForFPGA(Action *&A, const Arg *InputArg,
6741  DerivedArgList &Args) {
6742  std::string InputName = InputArg->getAsString(Args);
6743  const Driver &D = C.getDriver();
6744  // Only check for FPGA device information when using fpga SubArch.
6745  if (A->getType() == types::TY_Object && isObjectFile(InputName))
6746  return true;
6747 
6748  auto ArchiveTypeMismatch = [&D, &InputName](bool EmitDiag) {
6749  if (EmitDiag)
6750  D.Diag(clang::diag::warn_drv_mismatch_fpga_archive) << InputName;
6751  };
6752  // Type FPGA aoco is a special case for static archives
6753  if (A->getType() == types::TY_FPGA_AOCO) {
6754  if (!hasFPGABinary(C, InputName, types::TY_FPGA_AOCO))
6755  return false;
6756  A = C.MakeAction<InputAction>(*InputArg, types::TY_FPGA_AOCO);
6757  return true;
6758  }
6759 
6760  // Type FPGA aocx is considered the same way for Hardware and Emulation.
6761  if (hasFPGABinary(C, InputName, types::TY_FPGA_AOCX)) {
6762  A = C.MakeAction<InputAction>(*InputArg, types::TY_FPGA_AOCX);
6763  return true;
6764  }
6765 
6766  SmallVector<std::pair<types::ID, bool>, 4> FPGAAOCTypes = {
6767  {types::TY_FPGA_AOCR, false},
6768  {types::TY_FPGA_AOCR_EMU, true}};
6769  for (const auto &ArchiveType : FPGAAOCTypes) {
6770  bool BinaryFound = hasFPGABinary(C, InputName, ArchiveType.first);
6771  if (BinaryFound && ArchiveType.second == D.IsFPGAEmulationMode()) {
6772  // Binary matches check and emulation type, we keep this one.
6773  A = C.MakeAction<InputAction>(*InputArg, ArchiveType.first);
6774  return true;
6775  }
6776  ArchiveTypeMismatch(BinaryFound &&
6777  ArchiveType.second == D.IsFPGAHWMode());
6778  }
6779  return true;
6780  }
6781 
6782  /// Generate an action that adds a host dependence to a device action. The
6783  /// results will be kept in this action builder. Return true if an error was
6784  /// found.
6785  bool addHostDependenceToDeviceActions(Action *&HostAction,
6786  const Arg *InputArg,
6787  DerivedArgList &Args) {
6788  if (!IsValid)
6789  return true;
6790 
6791  // An FPGA AOCX input does not have a host dependence to the unbundler
6792  if (HostAction->getType() == types::TY_FPGA_AOCX)
6793  return false;
6794  recordHostAction(HostAction, InputArg);
6795 
6796  // If we are supporting bundling/unbundling and the current action is an
6797  // input action of non-source file, we replace the host action by the
6798  // unbundling action. The bundler tool has the logic to detect if an input
6799  // is a bundle or not and if the input is not a bundle it assumes it is a
6800  // host file. Therefore it is safe to create an unbundling action even if
6801  // the input is not a bundle.
6802  bool HasFPGATarget = false;
6803  if (CanUseBundler && isa<InputAction>(HostAction) &&
6804  InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
6805  !InputArg->getOption().hasFlag(options::LinkerInput) &&
6806  (!types::isSrcFile(HostAction->getType()) ||
6807  HostAction->getType() == types::TY_PP_HIP)) {
6808  ActionList HostActionList;
6809  Action *A(HostAction);
6810  bool HasSPIRTarget = false;
6811  // Only check for FPGA device information when using fpga SubArch.
6812  auto SYCLTCRange = C.getOffloadToolChains<Action::OFK_SYCL>();
6813  for (auto TI = SYCLTCRange.first, TE = SYCLTCRange.second; TI != TE;
6814  ++TI) {
6815  HasFPGATarget |= TI->second->getTriple().getSubArch() ==
6816  llvm::Triple::SPIRSubArch_fpga;
6817  HasSPIRTarget |= TI->second->getTriple().isSPIROrSPIRV();
6818  }
6819  bool isArchive = !(HostAction->getType() == types::TY_Object &&
6820  isObjectFile(InputArg->getAsString(Args)));
6821  if (!HasFPGATarget && isArchive &&
6822  HostAction->getType() == types::TY_FPGA_AOCO)
6823  // Archive with Non-FPGA target with AOCO type should not be unbundled.
6824  return false;
6825  if (HasFPGATarget && !updateInputForFPGA(A, InputArg, Args))
6826  return false;
6827  // FIXME - unbundling action with -fsycl-link is unbundling for both host
6828  // and device, where only the device is needed.
6829  auto UnbundlingHostAction = C.MakeAction<OffloadUnbundlingJobAction>(
6830  A, (HasSPIRTarget && HostAction->getType() == types::TY_Archive)
6831  ? types::TY_Tempfilelist
6832  : A->getType());
6833  UnbundlingHostAction->registerDependentActionInfo(
6834  C.getSingleOffloadToolChain<Action::OFK_Host>(),
6835  /*BoundArch=*/StringRef(), Action::OFK_Host);
6836  HostAction = UnbundlingHostAction;
6837  recordHostAction(HostAction, InputArg);
6838  }
6839 
6840  assert(HostAction && "Invalid host action!");
6841 
6842  // Register the offload kinds that are used.
6843  auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
6844  for (auto *SB : SpecializedBuilders) {
6845  if (!SB->isValid())
6846  continue;
6847 
6848  auto RetCode = SB->addDeviceDependences(HostAction);
6849 
6850  // Host dependences for device actions are not compatible with that same
6851  // action being ignored.
6852  assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
6853  "Host dependence not expected to be ignored.!");
6854 
6855  // Unless the builder was inactive for this action, we have to record the
6856  // offload kind because the host will have to use it.
6857  if (RetCode != DeviceActionBuilder::ABRT_Inactive)
6858  OffloadKind |= SB->getAssociatedOffloadKind();
6859  }
6860 
6861  // Do not use unbundler if the Host does not depend on device action.
6862  // Now that we have unbundled the object, when doing -fsycl-link we
6863  // want to continue the host link with the input object.
6864  // For unbundling of an FPGA AOCX binary, we want to link with the original
6865  // FPGA device archive.
6866  if ((OffloadKind == Action::OFK_None && CanUseBundler) ||
6867  (Args.hasArg(options::OPT_fsycl_link_EQ) && !HasFPGATarget) ||
6868  (HasFPGATarget && ((Args.hasArg(options::OPT_fsycl_link_EQ) &&
6869  HostAction->getType() == types::TY_Object) ||
6870  HostAction->getType() == types::TY_FPGA_AOCX)))
6871  if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
6872  HostAction = UA->getInputs().back();
6873 
6874  return false;
6875  }
6876 
6877  /// Add the offloading top level actions that are specific for unique
6878  /// linking situations where objects are used at only the device link
6879  /// with no intermedate steps.
6880  bool appendTopLevelLinkAction(ActionList &AL) {
6881  // Get the device actions to be appended.
6882  ActionList OffloadAL;
6883  for (auto *SB : SpecializedBuilders) {
6884  if (!SB->isValid())
6885  continue;
6886  SB->appendTopLevelLinkAction(OffloadAL);
6887  }
6888  // Append the device actions.
6889  AL.append(OffloadAL.begin(), OffloadAL.end());
6890  return false;
6891  }
6892 
6893  /// Add the offloading top level actions to the provided action list. This
6894  /// function can replace the host action by a bundling action if the
6895  /// programming models allow it.
6896  bool appendTopLevelActions(ActionList &AL, Action *HostAction,
6897  const Arg *InputArg) {
6898  if (HostAction)
6899  recordHostAction(HostAction, InputArg);
6900 
6901  // Get the device actions to be appended.
6902  ActionList OffloadAL;
6903  for (auto *SB : SpecializedBuilders) {
6904  if (!SB->isValid())
6905  continue;
6906  SB->appendTopLevelActions(OffloadAL);
6907  }
6908 
6909  // If we can use the bundler, replace the host action by the bundling one in
6910  // the resulting list. Otherwise, just append the device actions. For
6911  // device only compilation, HostAction is a null pointer, therefore only do
6912  // this when HostAction is not a null pointer.
6913  if (CanUseBundler && HostAction &&
6914  HostAction->getType() != types::TY_Nothing && !OffloadAL.empty()) {
6915  // Add the host action to the list in order to create the bundling action.
6916  OffloadAL.push_back(HostAction);
6917 
6918  // We expect that the host action was just appended to the action list
6919  // before this method was called.
6920  assert(HostAction == AL.back() && "Host action not in the list??");
6921  HostAction = C.MakeAction<OffloadBundlingJobAction>(OffloadAL);
6922  recordHostAction(HostAction, InputArg);
6923  AL.back() = HostAction;
6924  } else
6925  AL.append(OffloadAL.begin(), OffloadAL.end());
6926 
6927  // Propagate to the current host action (if any) the offload information
6928  // associated with the current input.
6929  if (HostAction)
6930  HostAction->propagateHostOffloadInfo(InputArgToOffloadKindMap[InputArg],
6931  /*BoundArch=*/nullptr);
6932  return false;
6933  }
6934 
6935  /// Create link job from the given host inputs and feed the result to offload
6936  /// deps job which fetches device dependencies from the linked host image.
6937  /// Offload deps output is then forwarded to active device action builders so
6938  /// they can add it to the device linker inputs.
6939  void addDeviceLinkDependenciesFromHost(ActionList &LinkerInputs) {
6940  // Link image for reading dependencies from it.
6941  auto *LA = C.MakeAction<LinkJobAction>(LinkerInputs,
6942  types::TY_Host_Dependencies_Image);
6943 
6944  // Calculate all the offload kinds used in the current compilation.
6945  unsigned ActiveOffloadKinds = 0u;
6946  for (auto &I : InputArgToOffloadKindMap)
6947  ActiveOffloadKinds |= I.second;
6948 
6950  *LA, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
6951  /*BoundArch*/ nullptr, ActiveOffloadKinds);
6952 
6953  auto *DA = C.MakeAction<OffloadDepsJobAction>(HDep, types::TY_LLVM_BC);
6954 
6955  for (auto *SB : SpecializedBuilders) {
6956  if (!SB->isValid())
6957  continue;
6958  SB->addDeviceLinkDependencies(DA);
6959  }
6960  }
6961 
6962  void appendDeviceLinkActions(ActionList &AL) {
6963  for (DeviceActionBuilder *SB : SpecializedBuilders) {
6964  if (!SB->isValid())
6965  continue;
6966  SB->appendLinkDeviceActions(AL);
6967  }
6968  }
6969 
6970  void makeHostLinkDeviceOnlyAction(ActionList &Inputs) {
6971  // Build a list of device linking actions.
6972  ActionList DeviceAL;
6973  appendDeviceLinkActions(DeviceAL);
6974  if (DeviceAL.empty())
6975  return;
6976 
6977  // Let builders add host linking actions.
6978  Action *HA = nullptr;
6979  for (DeviceActionBuilder *SB : SpecializedBuilders) {
6980  if (!SB->isValid())
6981  continue;
6982  HA = SB->appendLinkHostActions(DeviceAL);
6983  if (!HA)
6984  continue;
6985  // This created host action has no originating input argument, therefore
6986  // needs to set its offloading kind directly.
6987  HA->propagateHostOffloadInfo(SB->getAssociatedOffloadKind(),
6988  /*BoundArch=*/nullptr);
6989  Inputs.push_back(HA);
6990  }
6991  }
6992 
6993  void makeHostLinkAction(ActionList &LinkerInputs) {
6994 
6995  bool IsCUinSYCL = false;
6996  for (auto &I : InputArgToOffloadKindMap) {
6997  if (I.second == (Action::OFK_Cuda | Action::OFK_SYCL)) {
6998  IsCUinSYCL = true;
6999  }
7000  }
7001 
7002  // Add offload action for the SYCL compilation of .cu files
7003  if (IsCUinSYCL) {
7004  for (size_t i = 0; i < LinkerInputs.size(); ++i) {
7006  *LinkerInputs[i], *C.getSingleOffloadToolChain<Action::OFK_Host>(),
7007  nullptr,
7008  InputArgToOffloadKindMap[HostActionToInputArgMap[LinkerInputs[i]]]);
7009  LinkerInputs[i] = C.MakeAction<OffloadAction>(HDep);
7010  }
7011  }
7012 
7013  // Build a list of device linking actions.
7014  ActionList DeviceAL;
7015  appendDeviceLinkActions(DeviceAL);
7016  if (DeviceAL.empty())
7017  return;
7018 
7019  // Let builders add host linking actions.
7020  Action* HA = nullptr;
7021  for (DeviceActionBuilder *SB : SpecializedBuilders) {
7022  if (!SB->isValid())
7023  continue;
7024  HA = SB->appendLinkHostActions(DeviceAL);
7025  // This created host action has no originating input argument, therefore
7026  // needs to set its offloading kind directly.
7027  if (HA) {
7028  HA->propagateHostOffloadInfo(SB->getAssociatedOffloadKind(),
7029  /*BoundArch=*/nullptr);
7030  LinkerInputs.push_back(HA);
7031  } else {
7032  // Nothing appended to create a singular input, so add each device
7033  // individually to the inputs.
7034  for (auto &DeviceAction : DeviceAL) {
7035  DeviceAction->propagateHostOffloadInfo(SB->getAssociatedOffloadKind(),
7036  /*BoundArch=*/nullptr);
7037  LinkerInputs.push_back(DeviceAction);
7038  }
7039  }
7040  }
7041  }
7042 
7043  /// Processes the host linker action. This currently consists of replacing it
7044  /// with an offload action if there are device link objects and propagate to
7045  /// the host action all the offload kinds used in the current compilation. The
7046  /// resulting action is returned.
7047  Action *processHostLinkAction(Action *HostAction) {
7048  // Add all the dependences from the device linking actions.
7050  for (auto *SB : SpecializedBuilders) {
7051  if (!SB->isValid())
7052  continue;
7053 
7054  SB->appendLinkDependences(DDeps);
7055  }
7056 
7057  // Calculate all the offload kinds used in the current compilation.
7058  unsigned ActiveOffloadKinds = 0u;
7059  for (auto &I : InputArgToOffloadKindMap)
7060  ActiveOffloadKinds |= I.second;
7061 
7062  // If we don't have device dependencies, we don't have to create an offload
7063  // action.
7064  if (DDeps.getActions().empty()) {
7065  // Set all the active offloading kinds to the link action. Given that it
7066  // is a link action it is assumed to depend on all actions generated so
7067  // far.
7068  HostAction->setHostOffloadInfo(ActiveOffloadKinds,
7069  /*BoundArch=*/nullptr);
7070  // Propagate active offloading kinds for each input to the link action.
7071  // Each input may have different active offloading kind.
7072  for (auto *A : HostAction->inputs()) {
7073  auto ArgLoc = HostActionToInputArgMap.find(A);
7074  if (ArgLoc == HostActionToInputArgMap.end())
7075  continue;
7076  auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
7077  if (OFKLoc == InputArgToOffloadKindMap.end())
7078  continue;
7079  A->propagateHostOffloadInfo(OFKLoc->second, /*BoundArch=*/nullptr);
7080  }
7081  return HostAction;
7082  }
7083 
7084  // Create the offload action with all dependences. When an offload action
7085  // is created the kinds are propagated to the host action, so we don't have
7086  // to do that explicitly here.
7088  *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
7089  /*BoundArch*/ nullptr, ActiveOffloadKinds);
7090  return C.MakeAction<OffloadAction>(HDep, DDeps);
7091  }
7092 
7093  void unbundleStaticArchives(Compilation &C, DerivedArgList &Args) {
7094  if (!Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false))
7095  return;
7096 
7097  // Go through all of the args, and create a Linker specific argument list.
7098  // When dealing with fat static archives each archive is individually
7099  // unbundled.
7100  SmallVector<const char *, 16> LinkArgs(getLinkerArgs(C, Args));
7101  const llvm::opt::OptTable &Opts = C.getDriver().getOpts();
7102  auto unbundleStaticLib = [&](types::ID T, const StringRef &A) {
7103  Arg *InputArg = MakeInputArg(Args, Opts, Args.MakeArgString(A));
7104  Action *Current = C.MakeAction<InputAction>(*InputArg, T);
7105  addHostDependenceToDeviceActions(Current, InputArg, Args);
7106  auto PL = types::getCompilationPhases(T);
7107  addDeviceDependencesToHostAction(Current, InputArg, phases::Link,
7108  PL.back(), PL);
7109  };
7110  for (StringRef LA : LinkArgs) {
7111  // At this point, we will process the archives for FPGA AOCO and
7112  // individual archive unbundling for Windows.
7113  if (!isStaticArchiveFile(LA))
7114  continue;
7115  // FPGA AOCX/AOCR files are archives, but we do not want to unbundle them
7116  // here as they have already been unbundled and processed for linking.
7117  // TODO: The multiple binary checks for FPGA types getting a little out
7118  // of hand. Improve this by doing a single scan of the args and holding
7119  // that in a data structure for reference.
7120  if (hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCX) ||
7121  hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCR) ||
7122  hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCR_EMU))
7123  continue;
7124  if (hasOffloadSections(C, LA, Args)) {
7125  // Pass along the static libraries to check if we need to add them for
7126  // unbundling for FPGA AOT static lib usage. Uses FPGA aoco type to
7127  // differentiate if aoco unbundling is needed. Unbundling of aoco is
7128  // not needed for emulation, as these are treated as regular archives.
7129  if (C.getDriver().IsFPGAHWMode())
7130  unbundleStaticLib(types::TY_FPGA_AOCO, LA);
7131  unbundleStaticLib(types::TY_Archive, LA);
7132  }
7133  }
7134  }
7135 };
7136 } // anonymous namespace.
7137 
7138 void Driver::handleArguments(Compilation &C, DerivedArgList &Args,
7139  const InputList &Inputs,
7140  ActionList &Actions) const {
7141 
7142  // Ignore /Yc/Yu if both /Yc and /Yu passed but with different filenames.
7143  Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
7144  Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
7145  if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
7146  Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
7147  Args.eraseArg(options::OPT__SLASH_Yc);
7148  Args.eraseArg(options::OPT__SLASH_Yu);
7149  YcArg = YuArg = nullptr;
7150  }
7151  if (YcArg && Inputs.size() > 1) {
7152  Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
7153  Args.eraseArg(options::OPT__SLASH_Yc);
7154  YcArg = nullptr;
7155  }
7156 
7157  Arg *FinalPhaseArg;
7158  phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
7159 
7160  if (FinalPhase == phases::Link) {
7161  if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
7162  Args.AddFlagArg(nullptr, getOpts().getOption(options::OPT_hip_link));
7163  Args.AddFlagArg(nullptr,
7164  getOpts().getOption(options::OPT_frtlib_add_rpath));
7165  }
7166  // Emitting LLVM while linking disabled except in HIPAMD Toolchain
7167  if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
7168  Diag(clang::diag::err_drv_emit_llvm_link);
7169  if (IsCLMode() && LTOMode != LTOK_None &&
7170  !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7171  .equals_insensitive("lld"))
7172  Diag(clang::diag::err_drv_lto_without_lld);
7173 
7174  // If -dumpdir is not specified, give a default prefix derived from the link
7175  // output filename. For example, `clang -g -gsplit-dwarf a.c -o x` passes
7176  // `-dumpdir x-` to cc1. If -o is unspecified, use
7177  // stem(getDefaultImageName()) (usually stem("a.out") = "a").
7178  if (!Args.hasArg(options::OPT_dumpdir)) {
7179  Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
7180  Arg *Arg = Args.MakeSeparateArg(
7181  nullptr, getOpts().getOption(options::OPT_dumpdir),
7182  Args.MakeArgString(
7183  (FinalOutput ? FinalOutput->getValue()
7184  : llvm::sys::path::stem(getDefaultImageName())) +
7185  "-"));
7186  Arg->claim();
7187  Args.append(Arg);
7188  }
7189  }
7190 
7191  if (FinalPhase == phases::Preprocess || Args.hasArg(options::OPT__SLASH_Y_)) {
7192  // If only preprocessing or /Y- is used, all pch handling is disabled.
7193  // Rather than check for it everywhere, just remove clang-cl pch-related
7194  // flags here.
7195  Args.eraseArg(options::OPT__SLASH_Fp);
7196  Args.eraseArg(options::OPT__SLASH_Yc);
7197  Args.eraseArg(options::OPT__SLASH_Yu);
7198  YcArg = YuArg = nullptr;
7199  }
7200 
7201  unsigned LastPLSize = 0;
7202  for (auto &I : Inputs) {
7203  types::ID InputType = I.first;
7204  const Arg *InputArg = I.second;
7205 
7206  auto PL = types::getCompilationPhases(InputType);
7207  LastPLSize = PL.size();
7208 
7209  // If the first step comes after the final phase we are doing as part of
7210  // this compilation, warn the user about it.
7211  phases::ID InitialPhase = PL[0];
7212  if (InitialPhase > FinalPhase) {
7213  if (InputArg->isClaimed())
7214  continue;
7215 
7216  // Claim here to avoid the more general unused warning.
7217  InputArg->claim();
7218 
7219  // Suppress all unused style warnings with -Qunused-arguments
7220  if (Args.hasArg(options::OPT_Qunused_arguments))
7221  continue;
7222 
7223  // Special case when final phase determined by binary name, rather than
7224  // by a command-line argument with a corresponding Arg.
7225  if (CCCIsCPP())
7226  Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
7227  << InputArg->getAsString(Args) << getPhaseName(InitialPhase);
7228  // Special case '-E' warning on a previously preprocessed file to make
7229  // more sense.
7230  else if (InitialPhase == phases::Compile &&
7231  (Args.getLastArg(options::OPT__SLASH_EP,
7232  options::OPT__SLASH_P) ||
7233  Args.getLastArg(options::OPT_E) ||
7234  Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
7235  getPreprocessedType(InputType) == types::TY_INVALID)
7236  Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
7237  << InputArg->getAsString(Args) << !!FinalPhaseArg
7238  << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
7239  else
7240  Diag(clang::diag::warn_drv_input_file_unused)
7241  << InputArg->getAsString(Args) << getPhaseName(InitialPhase)
7242  << !!FinalPhaseArg
7243  << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
7244  continue;
7245  }
7246 
7247  if (YcArg) {
7248  // Add a separate precompile phase for the compile phase.
7249  if (FinalPhase >= phases::Compile) {
7251  // Build the pipeline for the pch file.
7252  Action *ClangClPch = C.MakeAction<InputAction>(*InputArg, HeaderType);
7254  ClangClPch = ConstructPhaseAction(C, Args, Phase, ClangClPch);
7255  assert(ClangClPch);
7256  Actions.push_back(ClangClPch);
7257  // The driver currently exits after the first failed command. This
7258  // relies on that behavior, to make sure if the pch generation fails,
7259  // the main compilation won't run.
7260  // FIXME: If the main compilation fails, the PCH generation should
7261  // probably not be considered successful either.
7262  }
7263  }
7264  }
7265 
7266  // If we are linking, claim any options which are obviously only used for
7267  // compilation.
7268  // FIXME: Understand why the last Phase List length is used here.
7269  if (FinalPhase == phases::Link && LastPLSize == 1) {
7270  Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
7271  Args.ClaimAllArgs(options::OPT_cl_compile_Group);
7272  }
7273 }
7274 
7275 void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
7276  const InputList &Inputs, ActionList &Actions) const {
7277  llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
7278 
7279  if (!SuppressMissingInputWarning && Inputs.empty()) {
7280  Diag(clang::diag::err_drv_no_input_files);
7281  return;
7282  }
7283 
7284  // Diagnose misuse of /Fo.
7285  if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
7286  StringRef V = A->getValue();
7287  if (Inputs.size() > 1 && !V.empty() &&
7288  !llvm::sys::path::is_separator(V.back())) {
7289  // Check whether /Fo tries to name an output file for multiple inputs.
7290  Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
7291  << A->getSpelling() << V;
7292  Args.eraseArg(options::OPT__SLASH_Fo);
7293  }
7294  }
7295 
7296  // Diagnose misuse of /Fa.
7297  if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
7298  StringRef V = A->getValue();
7299  if (Inputs.size() > 1 && !V.empty() &&
7300  !llvm::sys::path::is_separator(V.back())) {
7301  // Check whether /Fa tries to name an asm file for multiple inputs.
7302  Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
7303  << A->getSpelling() << V;
7304  Args.eraseArg(options::OPT__SLASH_Fa);
7305  }
7306  }
7307 
7308  // Diagnose misuse of /o.
7309  if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
7310  if (A->getValue()[0] == '\0') {
7311  // It has to have a value.
7312  Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
7313  Args.eraseArg(options::OPT__SLASH_o);
7314  }
7315  }
7316 
7317  handleArguments(C, Args, Inputs, Actions);
7318 
7319  // If '-fintelfpga' is passed, add '-fsycl' to the list of arguments
7320  const llvm::opt::OptTable &Opts = getOpts();
7321  Arg *SYCLFpgaArg = C.getInputArgs().getLastArg(options::OPT_fintelfpga);
7322  if (SYCLFpgaArg &&
7323  !Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false))
7324  Args.AddFlagArg(0, Opts.getOption(options::OPT_fsycl));
7325 
7326  // When compiling for -fsycl, generate the integration header files and the
7327  // Unique ID that will be used during the compilation.
7328  if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
7329  const bool IsSaveTemps = isSaveTempsEnabled();
7330  SmallString<128> OutFileDir;
7331  if (IsSaveTemps) {
7332  if (SaveTemps == SaveTempsObj) {
7333  auto *OptO = C.getArgs().getLastArg(options::OPT_o);
7334  OutFileDir = (OptO ? OptO->getValues()[0] : "");
7335  llvm::sys::path::remove_filename(OutFileDir);
7336  if (!OutFileDir.empty())
7337  OutFileDir.append(llvm::sys::path::get_separator());
7338  }
7339  }
7340  for (auto &I : Inputs) {
7341  std::string SrcFileName(I.second->getAsString(Args));
7342  if ((I.first == types::TY_PP_C || I.first == types::TY_PP_CXX ||
7343  types::isSrcFile(I.first))) {
7344  // Unique ID is generated for source files and preprocessed files.
7345  SmallString<128> ResultID;
7346  llvm::sys::fs::createUniquePath("uid%%%%%%%%%%%%%%%%", ResultID, false);
7347  addSYCLUniqueID(Args.MakeArgString(ResultID.str()), SrcFileName);
7348  }
7349  if (!types::isSrcFile(I.first))
7350  continue;
7351 
7352  std::string TmpFileNameHeader;
7353  std::string TmpFileNameFooter;
7354  auto StemmedSrcFileName = llvm::sys::path::stem(SrcFileName).str();
7355  if (IsSaveTemps) {
7356  TmpFileNameHeader.append(C.getDriver().GetUniquePath(
7357  OutFileDir.c_str() + StemmedSrcFileName + "-header", "h"));
7358  TmpFileNameFooter.append(C.getDriver().GetUniquePath(
7359  OutFileDir.c_str() + StemmedSrcFileName + "-footer", "h"));
7360  } else {
7361  TmpFileNameHeader.assign(C.getDriver().GetTemporaryPath(
7362  StemmedSrcFileName + "-header", "h"));
7363  TmpFileNameFooter =
7364  C.getDriver().GetTemporaryPath(StemmedSrcFileName + "-footer", "h");
7365  }
7366  StringRef TmpFileHeader =
7367  C.addTempFile(C.getArgs().MakeArgString(TmpFileNameHeader));
7368  StringRef TmpFileFooter =
7369  C.addTempFile(C.getArgs().MakeArgString(TmpFileNameFooter));
7370  // Use of -fsycl-footer-path puts the integration footer into that
7371  // specified location.
7372  if (Arg *A = C.getArgs().getLastArg(options::OPT_fsycl_footer_path_EQ)) {
7373  SmallString<128> OutName(A->getValue());
7374  llvm::sys::path::append(OutName,
7375  llvm::sys::path::filename(TmpFileNameFooter));
7376  TmpFileFooter = C.addTempFile(C.getArgs().MakeArgString(OutName));
7377  }
7378  addIntegrationFiles(TmpFileHeader, TmpFileFooter, SrcFileName);
7379  }
7380  }
7381 
7382  bool UseNewOffloadingDriver =
7383  C.isOffloadingHostKind(Action::OFK_OpenMP) ||
7384  Args.hasFlag(options::OPT_offload_new_driver,
7385  options::OPT_no_offload_new_driver, false);
7386 
7387  // Builder to be used to build offloading actions.
7388  std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
7389  !UseNewOffloadingDriver
7390  ? std::make_unique<OffloadingActionBuilder>(C, Args, Inputs)
7391  : nullptr;
7392 
7393  // Construct the actions to perform.
7395  ActionList LinkerInputs;
7396  ActionList MergerInputs;
7397  ActionList HostActions;
7398  llvm::SmallVector<const Arg *, 6> LinkerInputArgs;
7400 
7401  for (auto &I : Inputs) {
7402  types::ID InputType = I.first;
7403  const Arg *InputArg = I.second;
7404 
7405  PL = types::getCompilationPhases(*this, Args, InputType);
7406  if (PL.empty())
7407  continue;
7408 
7409  auto FullPL = types::getCompilationPhases(InputType);
7410 
7411  // Build the pipeline for this file.
7412  Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
7413 
7414  // Use the current host action in any of the offloading actions, if
7415  // required.
7416  if (!UseNewOffloadingDriver)
7417  if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg, Args))
7418  break;
7419 
7420  for (phases::ID Phase : PL) {
7421 
7422  // Add any offload action the host action depends on.
7423  if (!UseNewOffloadingDriver)
7424  Current = OffloadBuilder->addDeviceDependencesToHostAction(
7425  Current, InputArg, Phase, PL.back(), FullPL);
7426  if (!Current)
7427  break;
7428 
7429  // Queue linker inputs.
7430  if (Phase == phases::Link) {
7431  assert(Phase == PL.back() && "linking must be final compilation step.");
7432 
7433  // We don't need to generate additional link commands if emitting AMD
7434  // bitcode or compiling only for the offload device
7435  if (!(C.getInputArgs().hasArg(options::OPT_hip_link) &&
7436  (C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
7437  !offloadDeviceOnly())
7438  LinkerInputs.push_back(Current);
7439  Current = nullptr;
7440  break;
7441  }
7442 
7443  // TODO: Consider removing this because the merged may not end up being
7444  // the final Phase in the pipeline. Perhaps the merged could just merge
7445  // and then pass an artifact of some sort to the Link Phase.
7446  // Queue merger inputs.
7447  if (Phase == phases::IfsMerge) {
7448  assert(Phase == PL.back() && "merging must be final compilation step.");
7449  MergerInputs.push_back(Current);
7450  Current = nullptr;
7451  break;
7452  }
7453 
7454  if (Phase == phases::Precompile && ExtractAPIAction) {
7455  ExtractAPIAction->addHeaderInput(Current);
7456  Current = nullptr;
7457  break;
7458  }
7459 
7460  // FIXME: Should we include any prior module file outputs as inputs of
7461  // later actions in the same command line?
7462 
7463  // Otherwise construct the appropriate action.
7464  Action *NewCurrent = ConstructPhaseAction(C, Args, Phase, Current);
7465 
7466  // We didn't create a new action, so we will just move to the next phase.
7467  if (NewCurrent == Current)
7468  continue;
7469 
7470  if (auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
7471  ExtractAPIAction = EAA;
7472 
7473  Current = NewCurrent;
7474 
7475  // Try to build the offloading actions and add the result as a dependency
7476  // to the host.
7477  if (UseNewOffloadingDriver)
7478  Current = BuildOffloadingActions(C, Args, I, Current);
7479  // Use the current host action in any of the offloading actions, if
7480  // required.
7481  else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
7482  InputArg,
7483  Args))
7484  break;
7485 
7486  if (Current->getType() == types::TY_Nothing)
7487  break;
7488  }
7489 
7490  // If we ended with something, add to the output list.
7491  if (Current)
7492  Actions.push_back(Current);
7493 
7494  // Add any top level actions generated for offloading.
7495  if (!UseNewOffloadingDriver)
7496  OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
7497  else if (Current)
7498  Current->propagateHostOffloadInfo(C.getActiveOffloadKinds(),
7499  /*BoundArch=*/nullptr);
7500  }
7501 
7502  if (!UseNewOffloadingDriver) {
7503  OffloadBuilder->appendTopLevelLinkAction(Actions);
7504 
7505  // With static fat archives we need to create additional steps for
7506  // generating dependence objects for device link actions.
7507  if (!LinkerInputs.empty() && C.getDriver().getOffloadStaticLibSeen())
7508  OffloadBuilder->addDeviceLinkDependenciesFromHost(LinkerInputs);
7509 
7510  OffloadBuilder->unbundleStaticArchives(C, Args);
7511  }
7512 
7513  // For an FPGA archive, we add the unbundling step above to take care of
7514  // the device side, but also unbundle here to extract the host side
7515  bool EarlyLink = false;
7516  if (const Arg *A = Args.getLastArg(options::OPT_fsycl_link_EQ))
7517  EarlyLink = A->getValue() == StringRef("early");
7518  for (auto &LI : LinkerInputs) {
7519  Action *UnbundlerInput = nullptr;
7520  auto wrapObject = [&] {
7521  if (EarlyLink && Args.hasArg(options::OPT_fintelfpga)) {
7522  // Only wrap the object with -fsycl-link=early
7523  auto *BC = C.MakeAction<OffloadWrapperJobAction>(LI, types::TY_LLVM_BC);
7524  auto *ASM = C.MakeAction<BackendJobAction>(BC, types::TY_PP_Asm);
7525  auto *OBJ = C.MakeAction<AssembleJobAction>(ASM, types::TY_Object);
7527  *OBJ, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
7528  /*BoundArch=*/nullptr, Action::OFK_SYCL);
7529  LI = C.MakeAction<OffloadAction>(HDep);
7530  }
7531  };
7532  if (auto *IA = dyn_cast<InputAction>(LI)) {
7533  if (IA->getType() == types::TY_FPGA_AOCR ||
7534  IA->getType() == types::TY_FPGA_AOCX ||
7535  IA->getType() == types::TY_FPGA_AOCR_EMU) {
7536  // Add to unbundler.
7537  UnbundlerInput = LI;
7538  } else {
7539  std::string FileName = IA->getInputArg().getAsString(Args);
7540  if ((IA->getType() == types::TY_Object && !isObjectFile(FileName)) ||
7541  IA->getInputArg().getOption().hasFlag(options::LinkerInput))
7542  continue;
7543  wrapObject();
7544  }
7545  } else
7546  wrapObject();
7547  if (UnbundlerInput && !PL.empty()) {
7548  if (auto *IA = dyn_cast<InputAction>(UnbundlerInput)) {
7549  std::string FileName = IA->getInputArg().getAsString(Args);
7550  Arg *InputArg = MakeInputArg(Args, getOpts(), FileName);
7551  if (!UseNewOffloadingDriver)
7552  OffloadBuilder->addHostDependenceToDeviceActions(UnbundlerInput,
7553  InputArg, Args);
7554  }
7555  }
7556  }
7557 
7558  // Add a link action if necessary.
7559  Arg *FinalPhaseArg;
7560  if (!UseNewOffloadingDriver &&
7561  getFinalPhase(Args, &FinalPhaseArg) == phases::Link) {
7562  if (Args.hasArg(options::OPT_fsycl_link_EQ) &&
7563  !Args.hasArg(options::OPT_fintelfpga)) {
7564  ActionList LAList;
7565  OffloadBuilder->makeHostLinkDeviceOnlyAction(LAList);
7566  if (!LAList.empty()) {
7567  Action *LA = LAList.front();
7568  LA = OffloadBuilder->processHostLinkAction(LA);
7569  Actions.push_back(LA);
7570  }
7571  } else if (LinkerInputs.empty())
7572  OffloadBuilder->appendDeviceLinkActions(Actions);
7573  }
7574 
7575  if (!LinkerInputs.empty()) {
7576  if (!UseNewOffloadingDriver)
7577  OffloadBuilder->makeHostLinkAction(LinkerInputs);
7578  types::ID LinkType(types::TY_Image);
7579  if (Args.hasArg(options::OPT_fsycl_link_EQ))
7580  LinkType = types::TY_Archive;
7581  Action *LA;
7582  // Check if this Linker Job should emit a static library.
7583  if (ShouldEmitStaticLibrary(Args)) {
7584  LA = C.MakeAction<StaticLibJobAction>(LinkerInputs, LinkType);
7585  } else if (UseNewOffloadingDriver ||
7586  Args.hasArg(options::OPT_offload_link)) {
7587  LA = C.MakeAction<LinkerWrapperJobAction>(LinkerInputs, types::TY_Image);
7588  LA->propagateHostOffloadInfo(C.getActiveOffloadKinds(),
7589  /*BoundArch=*/nullptr);
7590  } else {
7591  LA = C.MakeAction<LinkJobAction>(LinkerInputs, LinkType);
7592  }
7593  if (!UseNewOffloadingDriver)
7594  LA = OffloadBuilder->processHostLinkAction(LA);
7595  Actions.push_back(LA);
7596  }
7597 
7598  // Add an interface stubs merge action if necessary.
7599  if (!MergerInputs.empty())
7600  Actions.push_back(
7601  C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
7602 
7603  if (Args.hasArg(options::OPT_emit_interface_stubs)) {
7604  auto PhaseList = types::getCompilationPhases(
7605  types::TY_IFS_CPP,
7606  Args.hasArg(options::OPT_c) ? phases::Compile : phases::IfsMerge);
7607 
7608  ActionList MergerInputs;
7609 
7610  for (auto &I : Inputs) {
7611  types::ID InputType = I.first;
7612  const Arg *InputArg = I.second;
7613 
7614  // Currently clang and the llvm assembler do not support generating symbol
7615  // stubs from assembly, so we skip the input on asm files. For ifs files
7616  // we rely on the normal pipeline setup in the pipeline setup code above.
7617  if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
7618  InputType == types::TY_Asm)
7619  continue;
7620 
7621  Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
7622 
7623  for (auto Phase : PhaseList) {
7624  switch (Phase) {
7625  default:
7626  llvm_unreachable(
7627  "IFS Pipeline can only consist of Compile followed by IfsMerge.");
7628  case phases::Compile: {
7629  // Only IfsMerge (llvm-ifs) can handle .o files by looking for ifs
7630  // files where the .o file is located. The compile action can not
7631  // handle this.
7632  if (InputType == types::TY_Object)
7633  break;
7634 
7635  Current = C.MakeAction<CompileJobAction>(Current, types::TY_IFS_CPP);
7636  break;
7637  }
7638  case phases::IfsMerge: {
7639  assert(Phase == PhaseList.back() &&
7640  "merging must be final compilation step.");
7641  MergerInputs.push_back(Current);
7642  Current = nullptr;
7643  break;
7644  }
7645  }
7646  }
7647 
7648  // If we ended with something, add to the output list.
7649  if (Current)
7650  Actions.push_back(Current);
7651  }
7652 
7653  // Add an interface stubs merge action if necessary.
7654  if (!MergerInputs.empty())
7655  Actions.push_back(
7656  C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
7657  }
7658 
7659  for (auto Opt : {options::OPT_print_supported_cpus,
7660  options::OPT_print_supported_extensions}) {
7661  // If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a
7662  // custom Compile phase that prints out supported cpu models and quits.
7663  //
7664  // If --print-supported-extensions is specified, call the helper function
7665  // RISCVMarchHelp in RISCVISAInfo.cpp that prints out supported extensions
7666  // and quits.
7667  if (Arg *A = Args.getLastArg(Opt)) {
7668  if (Opt == options::OPT_print_supported_extensions &&
7669  !C.getDefaultToolChain().getTriple().isRISCV() &&
7670  !C.getDefaultToolChain().getTriple().isAArch64() &&
7671  !C.getDefaultToolChain().getTriple().isARM()) {
7672  C.getDriver().Diag(diag::err_opt_not_valid_on_target)
7673  << "--print-supported-extensions";
7674  return;
7675  }
7676 
7677  // Use the -mcpu=? flag as the dummy input to cc1.
7678  Actions.clear();
7679  Action *InputAc = C.MakeAction<InputAction>(*A, types::TY_C);
7680  Actions.push_back(
7681  C.MakeAction<PrecompileJobAction>(InputAc, types::TY_Nothing));
7682  for (auto &I : Inputs)
7683  I.second->claim();
7684  }
7685  }
7686 
7687  // Call validator for dxil when -Vd not in Args.
7688  if (C.getDefaultToolChain().getTriple().isDXIL()) {
7689  // Only add action when needValidation.
7690  const auto &TC =
7691  static_cast<const toolchains::HLSLToolChain &>(C.getDefaultToolChain());
7692  if (TC.requiresValidation(Args)) {
7693  Action *LastAction = Actions.back();
7694  Actions.push_back(C.MakeAction<BinaryAnalyzeJobAction>(
7695  LastAction, types::TY_DX_CONTAINER));
7696  }
7697  }
7698 
7699  // Claim ignored clang-cl options.
7700  Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
7701 }
7702 
7703 /// Returns the canonical name for the offloading architecture when using a HIP
7704 /// or CUDA architecture.
7706  const llvm::opt::DerivedArgList &Args,
7707  StringRef ArchStr,
7708  const llvm::Triple &Triple,
7709  bool SuppressError = false) {
7710  // Lookup the CUDA / HIP architecture string. Only report an error if we were
7711  // expecting the triple to be only NVPTX / AMDGPU.
7712  CudaArch Arch = StringToCudaArch(getProcessorFromTargetID(Triple, ArchStr));
7713  if (!SuppressError && Triple.isNVPTX() &&
7714  (Arch == CudaArch::UNKNOWN || !IsNVIDIAGpuArch(Arch))) {
7715  C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
7716  << "CUDA" << ArchStr;
7717  return StringRef();
7718  } else if (!SuppressError && Triple.isAMDGPU() &&
7719  (Arch == CudaArch::UNKNOWN || !IsAMDGpuArch(Arch))) {
7720  C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
7721  << "HIP" << ArchStr;
7722  return StringRef();
7723  }
7724 
7725  if (IsNVIDIAGpuArch(Arch))
7726  return Args.MakeArgStringRef(CudaArchToString(Arch));
7727 
7728  if (IsAMDGpuArch(Arch)) {
7729  llvm::StringMap<bool> Features;
7730  auto HIPTriple = getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs());
7731  if (!HIPTriple)
7732  return StringRef();
7733  auto Arch = parseTargetID(*HIPTriple, ArchStr, &Features);
7734  if (!Arch) {
7735  C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
7736  C.setContainsError();
7737  return StringRef();
7738  }
7739  return Args.MakeArgStringRef(getCanonicalTargetID(*Arch, Features));
7740  }
7741 
7742  // If the input isn't CUDA or HIP just return the architecture.
7743  return ArchStr;
7744 }
7745 
7746 /// Checks if the set offloading architectures does not conflict. Returns the
7747 /// incompatible pair if a conflict occurs.
7748 static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
7750  llvm::Triple Triple) {
7751  if (!Triple.isAMDGPU())
7752  return std::nullopt;
7753 
7754  std::set<StringRef> ArchSet;
7755  llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
7756  return getConflictTargetIDCombination(ArchSet);
7757 }
7758 
7760 Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
7761  Action::OffloadKind Kind, const ToolChain *TC,
7762  bool SuppressError) const {
7763  if (!TC)
7764  TC = &C.getDefaultToolChain();
7765 
7766  // --offload and --offload-arch options are mutually exclusive.
7767  if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
7768  Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
7769  options::OPT_no_offload_arch_EQ)) {
7770  C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
7771  << "--offload"
7772  << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
7773  ? "--offload-arch"
7774  : "--no-offload-arch");
7775  }
7776 
7777  if (KnownArchs.contains(TC))
7778  return KnownArchs.lookup(TC);
7779 
7781  for (auto *Arg : Args) {
7782  // Extract any '--[no-]offload-arch' arguments intended for this toolchain.
7783  std::unique_ptr<llvm::opt::Arg> ExtractedArg = nullptr;
7784  if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
7785  ToolChain::getOpenMPTriple(Arg->getValue(0)) == TC->getTriple()) {
7786  Arg->claim();
7787  unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
7788  ExtractedArg = getOpts().ParseOneArg(Args, Index);
7789  Arg = ExtractedArg.get();
7790  }
7791 
7792  // Add or remove the seen architectures in order of appearance. If an
7793  // invalid architecture is given we simply exit.
7794  if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
7795  for (StringRef Arch : llvm::split(Arg->getValue(), ",")) {
7796  if (Arch == "native" || Arch.empty()) {
7797  auto GPUsOrErr = TC->getSystemGPUArchs(Args);
7798  if (!GPUsOrErr) {
7799  if (SuppressError)
7800  llvm::consumeError(GPUsOrErr.takeError());
7801  else
7802  TC->getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
7803  << llvm::Triple::getArchTypeName(TC->getArch())
7804  << llvm::toString(GPUsOrErr.takeError()) << "--offload-arch";
7805  continue;
7806  }
7807 
7808  for (auto ArchStr : *GPUsOrErr) {
7809  Archs.insert(
7810  getCanonicalArchString(C, Args, Args.MakeArgString(ArchStr),
7811  TC->getTriple(), SuppressError));
7812  }
7813  } else {
7814  StringRef ArchStr = getCanonicalArchString(
7815  C, Args, Arch, TC->getTriple(), SuppressError);
7816  if (ArchStr.empty())
7817  return Archs;
7818  Archs.insert(ArchStr);
7819  }
7820  }
7821  } else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
7822  for (StringRef Arch : llvm::split(Arg->getValue(), ",")) {
7823  if (Arch == "all") {
7824  Archs.clear();
7825  } else {
7826  StringRef ArchStr = getCanonicalArchString(
7827  C, Args, Arch, TC->getTriple(), SuppressError);
7828  if (ArchStr.empty())
7829  return Archs;
7830  Archs.erase(ArchStr);
7831  }
7832  }
7833  }
7834  }
7835 
7836  if (auto ConflictingArchs =
7838  C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
7839  << ConflictingArchs->first << ConflictingArchs->second;
7840  C.setContainsError();
7841  }
7842 
7843  // Skip filling defaults if we're just querying what is availible.
7844  if (SuppressError)
7845  return Archs;
7846 
7847  if (Archs.empty()) {
7848  if (Kind == Action::OFK_Cuda)
7849  Archs.insert(CudaArchToString(CudaArch::CudaDefault));
7850  else if (Kind == Action::OFK_HIP)
7851  Archs.insert(CudaArchToString(CudaArch::HIPDefault));
7852  else if (Kind == Action::OFK_OpenMP)
7853  Archs.insert(StringRef());
7854  else if (Kind == Action::OFK_SYCL)
7855  Archs.insert(StringRef());
7856  } else {
7857  Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
7858  Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
7859  }
7860 
7861  return Archs;
7862 }
7863 
7865  llvm::opt::DerivedArgList &Args,
7866  const InputTy &Input,
7867  Action *HostAction) const {
7868  // Don't build offloading actions if explicitly disabled or we do not have a
7869  // valid source input and compile action to embed it in. If preprocessing only
7870  // ignore embedding.
7871  if (offloadHostOnly() || !types::isSrcFile(Input.first) ||
7872  !(isa<CompileJobAction>(HostAction) ||
7874  return HostAction;
7875 
7876  ActionList OffloadActions;
7878 
7879  const Action::OffloadKind OffloadKinds[] = {
7881 
7882  for (Action::OffloadKind Kind : OffloadKinds) {
7884  ActionList DeviceActions;
7885 
7886  auto TCRange = C.getOffloadToolChains(Kind);
7887  for (auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
7888  ToolChains.push_back(TI->second);
7889 
7890  if (ToolChains.empty())
7891  continue;
7892 
7893  types::ID InputType = Input.first;
7894  const Arg *InputArg = Input.second;
7895 
7896  // The toolchain can be active for unsupported file types.
7897  if ((Kind == Action::OFK_Cuda && !types::isCuda(InputType)) ||
7898  (Kind == Action::OFK_HIP && !types::isHIP(InputType)))
7899  continue;
7900 
7901  // Get the product of all bound architectures and toolchains.
7903  for (const ToolChain *TC : ToolChains)
7904  for (StringRef Arch : getOffloadArchs(C, Args, Kind, TC))
7905  TCAndArchs.push_back(std::make_pair(TC, Arch));
7906 
7907  for (unsigned I = 0, E = TCAndArchs.size(); I != E; ++I)
7908  DeviceActions.push_back(C.MakeAction<InputAction>(*InputArg, InputType));
7909 
7910  if (DeviceActions.empty())
7911  return HostAction;
7912 
7913  auto PL = types::getCompilationPhases(*this, Args, InputType);
7914 
7915  for (phases::ID Phase : PL) {
7916  if (Phase == phases::Link) {
7917  assert(Phase == PL.back() && "linking must be final compilation step.");
7918  break;
7919  }
7920 
7921  // Assemble actions are not used for the SYCL device side. Both compile
7922  // and backend actions are used to generate IR and textual IR if needed.
7923  if (Kind == Action::OFK_SYCL && Phase == phases::Assemble)
7924  continue;
7925 
7926  auto TCAndArch = TCAndArchs.begin();
7927  for (Action *&A : DeviceActions) {
7928  if (A->getType() == types::TY_Nothing)
7929  continue;
7930 
7931  // Propagate the ToolChain so we can use it in ConstructPhaseAction.
7932  A->propagateDeviceOffloadInfo(Kind, TCAndArch->second.data(),
7933  TCAndArch->first);
7934  A = ConstructPhaseAction(C, Args, Phase, A, Kind);
7935 
7936  if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
7937  Kind == Action::OFK_OpenMP &&
7938  HostAction->getType() != types::TY_Nothing) {
7939  // OpenMP offloading has a dependency on the host compile action to
7940  // identify which declarations need to be emitted. This shouldn't be
7941  // collapsed with any other actions so we can use it in the device.
7944  *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
7945  TCAndArch->second.data(), Kind);
7947  DDep.add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
7948  A = C.MakeAction<OffloadAction>(HDep, DDep);
7949  }
7950 
7951  ++TCAndArch;
7952  }
7953  }
7954  // Use of -fsycl-device-obj=spirv converts the original LLVM-IR file to
7955  // SPIR-V for later consumption.
7956  for (Action *&A : DeviceActions) {
7957  if (!Args.getLastArgValue(options::OPT_fsycl_device_obj_EQ)
7958  .equals_insensitive("spirv") ||
7959  Kind != Action::OFK_SYCL || A->getType() != types::TY_LLVM_BC)
7960  continue;
7961  A = C.MakeAction<SPIRVTranslatorJobAction>(A, types::TY_SPIRV);
7962  }
7963 
7964  // Compiling HIP in non-RDC mode requires linking each action individually.
7965  for (Action *&A : DeviceActions) {
7966  if ((A->getType() != types::TY_Object &&
7967  A->getType() != types::TY_LTO_BC) ||
7968  Kind != Action::OFK_HIP ||
7969  Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false))
7970  continue;
7971  ActionList LinkerInput = {A};
7972  A = C.MakeAction<LinkJobAction>(LinkerInput, types::TY_Image);
7973  }
7974 
7975  auto TCAndArch = TCAndArchs.begin();
7976  for (Action *A : DeviceActions) {
7977  DDeps.add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
7979  DDep.add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
7980 
7981  // Compiling CUDA in non-RDC mode uses the PTX output if available.
7982  for (Action *Input : A->getInputs())
7983  if (Kind == Action::OFK_Cuda && A->getType() == types::TY_Object &&
7984  !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
7985  false))
7986  DDep.add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
7987  OffloadActions.push_back(C.MakeAction<OffloadAction>(DDep, A->getType()));
7988 
7989  ++TCAndArch;
7990  }
7991  }
7992 
7993  // HIP code in non-RDC mode will bundle the output if it invoked the linker.
7994  bool ShouldBundleHIP =
7995  C.isOffloadingHostKind(Action::OFK_HIP) &&
7996  Args.hasFlag(options::OPT_gpu_bundle_output,
7997  options::OPT_no_gpu_bundle_output, true) &&
7998  !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false) &&
7999  !llvm::any_of(OffloadActions,
8000  [](Action *A) { return A->getType() != types::TY_Image; });
8001 
8002  // All kinds exit now in device-only mode except for non-RDC mode HIP.
8003  if (offloadDeviceOnly() && !ShouldBundleHIP)
8004  return C.MakeAction<OffloadAction>(DDeps, types::TY_Nothing);
8005 
8006  if (OffloadActions.empty())
8007  return HostAction;
8008 
8010  if (C.isOffloadingHostKind(Action::OFK_Cuda) &&
8011  !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false)) {
8012  // If we are not in RDC-mode we just emit the final CUDA fatbinary for
8013  // each translation unit without requiring any linking.
8014  Action *FatbinAction =
8015  C.MakeAction<LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
8016  DDep.add(*FatbinAction, *C.getSingleOffloadToolChain<Action::OFK_Cuda>(),
8017  nullptr, Action::OFK_Cuda);
8018  } else if (C.isOffloadingHostKind(Action::OFK_HIP) &&
8019  !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
8020  false)) {
8021  // If we are not in RDC-mode we just emit the final HIP fatbinary for each
8022  // translation unit, linking each input individually.
8023  Action *FatbinAction =
8024  C.MakeAction<LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
8025  DDep.add(*FatbinAction, *C.getSingleOffloadToolChain<Action::OFK_HIP>(),
8026  nullptr, Action::OFK_HIP);
8027  } else {
8028  // Package all the offloading actions into a single output that can be
8029  // embedded in the host and linked.
8030  Action *PackagerAction =
8031  C.MakeAction<OffloadPackagerJobAction>(OffloadActions, types::TY_Image);
8032  DDep.add(*PackagerAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
8033  nullptr, C.getActiveOffloadKinds());
8034  }
8035 
8036  // HIP wants '--offload-device-only' to create a fatbinary by default.
8037  if (offloadDeviceOnly())
8038  return C.MakeAction<OffloadAction>(DDep, types::TY_Nothing);
8039 
8040  // If we are unable to embed a single device output into the host, we need to
8041  // add each device output as a host dependency to ensure they are still built.
8042  bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](Action *A) {
8043  return A->getType() == types::TY_Nothing;
8044  }) && isa<CompileJobAction>(HostAction);
8046  *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
8047  /*BoundArch=*/nullptr, SingleDeviceOutput ? DDep : DDeps);
8048  return C.MakeAction<OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
8049 }
8050 
8052  Compilation &C, const ArgList &Args, phases::ID Phase, Action *Input,
8053  Action::OffloadKind TargetDeviceOffloadKind) const {
8054  llvm::PrettyStackTraceString CrashInfo("Constructing phase actions");
8055 
8056  // Some types skip the assembler phase (e.g., llvm-bc), but we can't
8057  // encode this in the steps because the intermediate type depends on
8058  // arguments. Just special case here.
8059  if (Phase == phases::Assemble && Input->getType() != types::TY_PP_Asm)
8060  return Input;
8061 
8062  // Build the appropriate action.
8063  switch (Phase) {
8064  case phases::Link:
8065  llvm_unreachable("link action invalid here.");
8066  case phases::IfsMerge:
8067  llvm_unreachable("ifsmerge action invalid here.");
8068  case phases::Preprocess: {
8069  types::ID OutputTy;
8070  // -M and -MM specify the dependency file name by altering the output type,
8071  // -if -MD and -MMD are not specified.
8072  if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
8073  !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
8074  OutputTy = types::TY_Dependencies;
8075  } else {
8076  OutputTy = Input->getType();
8077  // For these cases, the preprocessor is only translating forms, the Output
8078  // still needs preprocessing.
8079  if (!Args.hasFlag(options::OPT_frewrite_includes,
8080  options::OPT_fno_rewrite_includes, false) &&
8081  !Args.hasFlag(options::OPT_frewrite_imports,
8082  options::OPT_fno_rewrite_imports, false) &&
8083  !Args.hasFlag(options::OPT_fdirectives_only,
8084  options::OPT_fno_directives_only, false) &&
8086  OutputTy = types::getPreprocessedType(OutputTy);
8087  assert(OutputTy != types::TY_INVALID &&
8088  "Cannot preprocess this input type!");
8089  }
8090  types::ID HostPPType = types::getPreprocessedType(Input->getType());
8091  if (Args.hasArg(options::OPT_fsycl) && HostPPType != types::TY_INVALID &&
8092  !Args.hasArg(options::OPT_fno_sycl_use_footer) &&
8093  TargetDeviceOffloadKind == Action::OFK_None &&
8094  Input->getType() != types::TY_CUDA_DEVICE) {
8095  // Performing a host compilation with -fsycl. Append the integration
8096  // footer to the source file.
8097  auto *AppendFooter =
8098  C.MakeAction<AppendFooterJobAction>(Input, Input->getType());
8099  // FIXME: There are 2 issues with dependency generation in regards to
8100  // the integration footer that need to be addressed.
8101  // 1) Input file referenced on the RHS of a dependency is based on the
8102  // input src, which is a temporary. We want this to be the true
8103  // user input src file.
8104  // 2) When generating dependencies against a preprocessed file, header
8105  // file information (using -MD or-MMD) is not provided.
8106  return C.MakeAction<PreprocessJobAction>(AppendFooter, OutputTy);
8107  }
8108  return C.MakeAction<PreprocessJobAction>(Input, OutputTy);
8109  }
8110  case phases::Precompile: {
8111  // API extraction should not generate an actual precompilation action.
8112  if (Args.hasArg(options::OPT_extract_api))
8113  return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO);
8114 
8115  // With 'fexperimental-modules-reduced-bmi', we don't want to run the
8116  // precompile phase unless the user specified '--precompile'. In the case
8117  // the '--precompile' flag is enabled, we will try to emit the reduced BMI
8118  // as a by product in GenerateModuleInterfaceAction.
8119  if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
8120  !Args.getLastArg(options::OPT__precompile))
8121  return Input;
8122 
8123  types::ID OutputTy = getPrecompiledType(Input->getType());
8124  assert(OutputTy != types::TY_INVALID &&
8125  "Cannot precompile this input type!");
8126 
8127  // If we're given a module name, precompile header file inputs as a
8128  // module, not as a precompiled header.
8129  const char *ModName = nullptr;
8130  if (OutputTy == types::TY_PCH) {
8131  if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
8132  ModName = A->getValue();
8133  if (ModName)
8134  OutputTy = types::TY_ModuleFile;
8135  }
8136 
8137  if (Args.hasArg(options::OPT_fsyntax_only)) {
8138  // Syntax checks should not emit a PCH file
8139  OutputTy = types::TY_Nothing;
8140  }
8141 
8142  return C.MakeAction<PrecompileJobAction>(Input, OutputTy);
8143  }
8144  case phases::Compile: {
8145  if (Args.hasArg(options::OPT_fsyntax_only))
8146  return C.MakeAction<CompileJobAction>(Input, types::TY_Nothing);
8147  if (Args.hasArg(options::OPT_rewrite_objc))
8148  return C.MakeAction<CompileJobAction>(Input, types::TY_RewrittenObjC);
8149  if (Args.hasArg(options::OPT_rewrite_legacy_objc))
8150  return C.MakeAction<CompileJobAction>(Input,
8151  types::TY_RewrittenLegacyObjC);
8152  if (Args.hasArg(options::OPT__analyze))
8153  return C.MakeAction<AnalyzeJobAction>(Input, types::TY_Plist);
8154  if (Args.hasArg(options::OPT__migrate))
8155  return C.MakeAction<MigrateJobAction>(Input, types::TY_Remap);
8156  if (Args.hasArg(options::OPT_emit_ast))
8157  return C.MakeAction<CompileJobAction>(Input, types::TY_AST);
8158  if (Args.hasArg(options::OPT_emit_cir))
8159  return C.MakeAction<CompileJobAction>(Input, types::TY_CIR);
8160  if (Args.hasArg(options::OPT_module_file_info))
8161  return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile);
8162  if (Args.hasArg(options::OPT_verify_pch))
8163  return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing);
8164  if (Args.hasArg(options::OPT_extract_api))
8165  return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO);
8166  return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC);
8167  }
8168  case phases::Backend: {
8169  if (isUsingLTO() && TargetDeviceOffloadKind == Action::OFK_None) {
8170  types::ID Output;
8171  if (Args.hasArg(options::OPT_ffat_lto_objects) &&
8172  !Args.hasArg(options::OPT_emit_llvm))
8173  Output = types::TY_PP_Asm;
8174  else if (Args.hasArg(options::OPT_S))
8175  Output = types::TY_LTO_IR;
8176  else
8177  Output = types::TY_LTO_BC;
8178  return C.MakeAction<BackendJobAction>(Input, Output);
8179  }
8180  if (isUsingLTO(/* IsOffload */ true) &&
8181  TargetDeviceOffloadKind != Action::OFK_None) {
8182  types::ID Output =
8183  Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
8184  if (getUseNewOffloadingDriver() &&
8185  getLTOMode(/*IsDeviceOffloadAction=*/true) == LTOK_Thin &&
8186  TargetDeviceOffloadKind == Action::OFK_SYCL) {
8187  // For SYCL with thinLTO, run sycl-post-link, extract the BC files from
8188  // the output table, run the backend on each output table.
8189  llvm::Triple OffloadTriple =
8190  Input->getOffloadingToolChain()->getTriple();
8191  SYCLPostLinkJobAction *TypedPostLinkAction =
8192  C.MakeAction<SYCLPostLinkJobAction>(Input, types::TY_Tempfiletable,
8193  types::TY_Tempfiletable);
8194  TypedPostLinkAction->setRTSetsSpecConstants(
8195  OffloadTriple.isSPIROrSPIRV() && !OffloadTriple.isSPIRAOT());
8196  auto *TypedExtractIRFilesAction = C.MakeAction<FileTableTformJobAction>(
8197  TypedPostLinkAction, types::TY_Tempfilelist,
8198  types::TY_Tempfilelist);
8199 
8200  TypedExtractIRFilesAction->addExtractColumnTform(
8201  FileTableTformJobAction::COL_CODE, false /*drop titles*/);
8202  auto *OutputAction =
8203  C.MakeAction<BackendJobAction>(TypedExtractIRFilesAction, Output);
8204 
8205  auto *ForEach = C.MakeAction<ForEachWrappingAction>(
8206  TypedExtractIRFilesAction, OutputAction);
8207  // This final job is mostly a no-op, but we need it to set the Action
8208  // type to Tempfilelist which is expected by clang-offload-packager.
8209  auto *ExtractBCFiles = C.MakeAction<FileTableTformJobAction>(
8210  ForEach, types::TY_Tempfilelist, types::TY_Tempfilelist);
8211  ExtractBCFiles->addExtractColumnTform(FileTableTformJobAction::COL_ZERO,
8212  false /*drop titles*/);
8213  return ExtractBCFiles;
8214  }
8215  return C.MakeAction<BackendJobAction>(Input, Output);
8216  }
8217  if (Args.hasArg(options::OPT_emit_llvm) ||
8218  ((TargetDeviceOffloadKind == Action::OFK_SYCL &&
8219  C.getDriver().getUseNewOffloadingDriver()) ||
8220  (((Input->getOffloadingToolChain() &&
8221  Input->getOffloadingToolChain()->getTriple().isAMDGPU()) ||
8222  TargetDeviceOffloadKind == Action::OFK_HIP) &&
8223  (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
8224  false) ||
8225  TargetDeviceOffloadKind == Action::OFK_OpenMP)))) {
8226  types::ID Output =
8227  Args.hasArg(options::OPT_S) &&
8228  (TargetDeviceOffloadKind == Action::OFK_None ||
8229  offloadDeviceOnly() ||
8230  (TargetDeviceOffloadKind == Action::OFK_HIP &&
8231  !Args.hasFlag(options::OPT_offload_new_driver,
8232  options::OPT_no_offload_new_driver, false)))
8233  ? types::TY_LLVM_IR
8234  : types::TY_LLVM_BC;
8235  return C.MakeAction<BackendJobAction>(Input, Output);
8236  }
8237  return C.MakeAction<BackendJobAction>(Input, types::TY_PP_Asm);
8238  }
8239  case phases::Assemble:
8240  return C.MakeAction<AssembleJobAction>(std::move(Input), types::TY_Object);
8241  }
8242 
8243  llvm_unreachable("invalid phase in ConstructPhaseAction");
8244 }
8245 
8247  llvm::PrettyStackTraceString CrashInfo("Building compilation jobs");
8248 
8249  Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
8250 
8251  // It is an error to provide a -o option if we are making multiple output
8252  // files. There are exceptions:
8253  //
8254  // IfsMergeJob: when generating interface stubs enabled we want to be able to
8255  // generate the stub file at the same time that we generate the real
8256  // library/a.out. So when a .o, .so, etc are the output, with clang interface
8257  // stubs there will also be a .ifs and .ifso at the same location.
8258  //
8259  // CompileJob of type TY_IFS_CPP: when generating interface stubs is enabled
8260  // and -c is passed, we still want to be able to generate a .ifs file while
8261  // we are also generating .o files. So we allow more than one output file in
8262  // this case as well.
8263  //
8264  // OffloadClass of type TY_Nothing: device-only output will place many outputs
8265  // into a single offloading action. We should count all inputs to the action
8266  // as outputs. Also ignore device-only outputs if we're compiling with
8267  // -fsyntax-only.
8268  if (FinalOutput) {
8269  unsigned NumOutputs = 0;
8270  unsigned NumIfsOutputs = 0;
8271  for (const Action *A : C.getActions()) {
8272  if (A->getType() != types::TY_Nothing &&
8273  A->getType() != types::TY_DX_CONTAINER &&
8274  !(A->getKind() == Action::IfsMergeJobClass ||
8275  (A->getType() == clang::driver::types::TY_IFS_CPP &&
8277  0 == NumIfsOutputs++) ||
8278  (A->getKind() == Action::BindArchClass && A->getInputs().size() &&
8279  A->getInputs().front()->getKind() == Action::IfsMergeJobClass)))
8280  ++NumOutputs;
8281  else if (A->getKind() == Action::OffloadClass &&
8282  A->getType() == types::TY_Nothing &&
8283  !C.getArgs().hasArg(options::OPT_fsyntax_only))
8284  NumOutputs += A->size();
8285  }
8286 
8287  if (NumOutputs > 1) {
8288  Diag(clang::diag::err_drv_output_argument_with_multiple_files);
8289  FinalOutput = nullptr;
8290  }
8291  }
8292 
8293  const llvm::Triple &RawTriple = C.getDefaultToolChain().getTriple();
8294 
8295  // Collect the list of architectures.
8296  llvm::StringSet<> ArchNames;
8297  if (RawTriple.isOSBinFormatMachO())
8298  for (const Arg *A : C.getArgs())
8299  if (A->getOption().matches(options::OPT_arch))
8300  ArchNames.insert(A->getValue());
8301 
8302  // Set of (Action, canonical ToolChain triple) pairs we've built jobs for.
8303  std::map<std::pair<const Action *, std::string>, InputInfoList> CachedResults;
8304  for (Action *A : C.getActions()) {
8305  // If we are linking an image for multiple archs then the linker wants
8306  // -arch_multiple and -final_output <final image name>. Unfortunately, this
8307  // doesn't fit in cleanly because we have to pass this information down.
8308  //
8309  // FIXME: This is a hack; find a cleaner way to integrate this into the
8310  // process.
8311  const char *LinkingOutput = nullptr;
8312  if (isa<LipoJobAction>(A)) {
8313  if (FinalOutput)
8314  LinkingOutput = FinalOutput->getValue();
8315  else
8316  LinkingOutput = getDefaultImageName();
8317  }
8318 
8319  BuildJobsForAction(C, A, &C.getDefaultToolChain(),
8320  /*BoundArch*/ StringRef(),
8321  /*AtTopLevel*/ true,
8322  /*MultipleArchs*/ ArchNames.size() > 1,
8323  /*LinkingOutput*/ LinkingOutput, CachedResults,
8324  /*TargetDeviceOffloadKind*/ Action::OFK_None);
8325  }
8326 
8327  // If we have more than one job, then disable integrated-cc1 for now. Do this
8328  // also when we need to report process execution statistics.
8329  if (C.getJobs().size() > 1 || CCPrintProcessStats)
8330  for (auto &J : C.getJobs())
8331  J.InProcess = false;
8332 
8333  if (CCPrintProcessStats) {
8334  C.setPostCallback([=](const Command &Cmd, int Res) {
8335  std::optional<llvm::sys::ProcessStatistics> ProcStat =
8336  Cmd.getProcessStatistics();
8337  if (!ProcStat)
8338  return;
8339 
8340  const char *LinkingOutput = nullptr;
8341  if (FinalOutput)
8342  LinkingOutput = FinalOutput->getValue();
8343  else if (!Cmd.getOutputFilenames().empty())
8344  LinkingOutput = Cmd.getOutputFilenames().front().c_str();
8345  else
8346  LinkingOutput = getDefaultImageName();
8347 
8348  if (CCPrintStatReportFilename.empty()) {
8349  using namespace llvm;
8350  // Human readable output.
8351  outs() << sys::path::filename(Cmd.getExecutable()) << ": "
8352  << "output=" << LinkingOutput;
8353  outs() << ", total="
8354  << format("%.3f", ProcStat->TotalTime.count() / 1000.) << " ms"
8355  << ", user="
8356  << format("%.3f", ProcStat->UserTime.count() / 1000.) << " ms"
8357  << ", mem=" << ProcStat->PeakMemory << " Kb\n";
8358  } else {
8359  // CSV format.
8360  std::string Buffer;
8361  llvm::raw_string_ostream Out(Buffer);
8362  llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
8363  /*Quote*/ true);
8364  Out << ',';
8365  llvm::sys::printArg(Out, LinkingOutput, true);
8366  Out << ',' << ProcStat->TotalTime.count() << ','
8367  << ProcStat->UserTime.count() << ',' << ProcStat->PeakMemory
8368  << '\n';
8369  Out.flush();
8370  std::error_code EC;
8371  llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
8372  llvm::sys::fs::OF_Append |
8373  llvm::sys::fs::OF_Text);
8374  if (EC)
8375  return;
8376  auto L = OS.lock();
8377  if (!L) {
8378  llvm::errs() << "ERROR: Cannot lock file "
8379  << CCPrintStatReportFilename << ": "
8380  << toString(L.takeError()) << "\n";
8381  return;
8382  }
8383  OS << Buffer;
8384  OS.flush();
8385  }
8386  });
8387  }
8388 
8389  // If the user passed -Qunused-arguments or there were errors, don't warn
8390  // about any unused arguments.
8391  if (Diags.hasErrorOccurred() ||
8392  C.getArgs().hasArg(options::OPT_Qunused_arguments))
8393  return;
8394 
8395  // Claim -fdriver-only here.
8396  (void)C.getArgs().hasArg(options::OPT_fdriver_only);
8397  // Claim -### here.
8398  (void)C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
8399 
8400  // Claim --driver-mode, --rsp-quoting, it was handled earlier.
8401  (void)C.getArgs().hasArg(options::OPT_driver_mode);
8402  (void)C.getArgs().hasArg(options::OPT_rsp_quoting);
8403 
8404  bool HasAssembleJob = llvm::any_of(C.getJobs(), [](auto &J) {
8405  // Match ClangAs and other derived assemblers of Tool. ClangAs uses a
8406  // longer ShortName "clang integrated assembler" while other assemblers just
8407  // use "assembler".
8408  return strstr(J.getCreator().getShortName(), "assembler");
8409  });
8410  for (Arg *A : C.getArgs()) {
8411  // FIXME: It would be nice to be able to send the argument to the
8412  // DiagnosticsEngine, so that extra values, position, and so on could be
8413  // printed.
8414  if (!A->isClaimed()) {
8415  if (A->getOption().hasFlag(options::NoArgumentUnused))
8416  continue;
8417 
8418  // Suppress the warning automatically if this is just a flag, and it is an
8419  // instance of an argument we already claimed.
8420  const Option &Opt = A->getOption();
8421  if (Opt.getKind() == Option::FlagClass) {
8422  bool DuplicateClaimed = false;
8423 
8424  for (const Arg *AA : C.getArgs().filtered(&Opt)) {
8425  if (AA->isClaimed()) {
8426  DuplicateClaimed = true;
8427  break;
8428  }
8429  }
8430 
8431  if (DuplicateClaimed)
8432  continue;
8433  }
8434 
8435  // In clang-cl, don't mention unknown arguments here since they have
8436  // already been warned about.
8437  if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
8438  if (A->getOption().hasFlag(options::TargetSpecific) &&
8439  !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
8440  // When for example -### or -v is used
8441  // without a file, target specific options are not
8442  // consumed/validated.
8443  // Instead emitting an error emit a warning instead.
8444  !C.getActions().empty()) {
8445  Diag(diag::err_drv_unsupported_opt_for_target)
8446  << A->getSpelling() << getTargetTriple();
8447  } else {
8448  Diag(clang::diag::warn_drv_unused_argument)
8449  << A->getAsString(C.getArgs());
8450  }
8451  }
8452  }
8453  }
8454 }
8455 
8456 namespace {
8457 /// Utility class to control the collapse of dependent actions and select the
8458 /// tools accordingly.
8459 class ToolSelector final {
8460  /// The tool chain this selector refers to.
8461  const ToolChain &TC;
8462 
8463  /// The compilation this selector refers to.
8464  const Compilation &C;
8465 
8466  /// The base action this selector refers to.
8467  const JobAction *BaseAction;
8468 
8469  /// Set to true if the current toolchain refers to host actions.
8470  bool IsHostSelector;
8471 
8472  /// Set to true if save-temps and embed-bitcode functionalities are active.
8473  bool SaveTemps;
8474  bool EmbedBitcode;
8475 
8476  /// Get previous dependent action or null if that does not exist. If
8477  /// \a CanBeCollapsed is false, that action must be legal to collapse or
8478  /// null will be returned.
8479  const JobAction *getPrevDependentAction(const ActionList &Inputs,
8480  ActionList &SavedOffloadAction,
8481  bool CanBeCollapsed = true) {
8482  // An option can be collapsed only if it has a single input.
8483  if (Inputs.size() != 1)
8484  return nullptr;
8485 
8486  Action *CurAction = *Inputs.begin();
8487  if (CanBeCollapsed &&
8489  return nullptr;
8490 
8491  // If the input action is an offload action. Look through it and save any
8492  // offload action that can be dropped in the event of a collapse.
8493  if (auto *OA = dyn_cast<OffloadAction>(CurAction)) {
8494  // If the dependent action is a device action, we will attempt to collapse
8495  // only with other device actions. Otherwise, we would do the same but
8496  // with host actions only.
8497  if (!IsHostSelector) {
8498  if (OA->hasSingleDeviceDependence(/*DoNotConsiderHostActions=*/true)) {
8499  CurAction =
8500  OA->getSingleDeviceDependence(/*DoNotConsiderHostActions=*/true);
8501  if (CanBeCollapsed &&
8503  return nullptr;
8504  SavedOffloadAction.push_back(OA);
8505  return dyn_cast<JobAction>(CurAction);
8506  }
8507  } else if (OA->hasHostDependence()) {
8508  CurAction = OA->getHostDependence();
8509  if (CanBeCollapsed &&
8511  return nullptr;
8512  SavedOffloadAction.push_back(OA);
8513  return dyn_cast<JobAction>(CurAction);
8514  }
8515  return nullptr;
8516  }
8517 
8518  return dyn_cast<JobAction>(CurAction);
8519  }
8520 
8521  /// Return true if an assemble action can be collapsed.
8522  bool canCollapseAssembleAction() const {
8523  return TC.useIntegratedAs() && !SaveTemps &&
8524  !C.getArgs().hasArg(options::OPT_via_file_asm) &&
8525  !C.getArgs().hasArg(options::OPT__SLASH_FA) &&
8526  !C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
8527  !C.getArgs().hasArg(options::OPT_dxc_Fc);
8528  }
8529 
8530  /// Return true if a preprocessor action can be collapsed.
8531  bool canCollapsePreprocessorAction() const {
8532  return !C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
8533  !C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
8534  !C.getArgs().hasArg(options::OPT_rewrite_objc);
8535  }
8536 
8537  /// Struct that relates an action with the offload actions that would be
8538  /// collapsed with it.
8539  struct JobActionInfo final {
8540  /// The action this info refers to.
8541  const JobAction *JA = nullptr;
8542  /// The offload actions we need to take care off if this action is
8543  /// collapsed.
8544  ActionList SavedOffloadAction;
8545  };
8546 
8547  /// Append collapsed offload actions from the give nnumber of elements in the
8548  /// action info array.
8549  static void AppendCollapsedOffloadAction(ActionList &CollapsedOffloadAction,
8550  ArrayRef<JobActionInfo> &ActionInfo,
8551  unsigned ElementNum) {
8552  assert(ElementNum <= ActionInfo.size() && "Invalid number of elements.");
8553  for (unsigned I = 0; I < ElementNum; ++I)
8554  CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
8555  ActionInfo[I].SavedOffloadAction.end());
8556  }
8557 
8558  /// Functions that attempt to perform the combining. They detect if that is
8559  /// legal, and if so they update the inputs \a Inputs and the offload action
8560  /// that were collapsed in \a CollapsedOffloadAction. A tool that deals with
8561  /// the combined action is returned. If the combining is not legal or if the
8562  /// tool does not exist, null is returned.
8563  /// Currently three kinds of collapsing are supported:
8564  /// - Assemble + Backend + Compile;
8565  /// - Assemble + Backend ;
8566  /// - Backend + Compile.
8567  const Tool *
8568  combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
8569  ActionList &Inputs,
8570  ActionList &CollapsedOffloadAction) {
8571  if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
8572  return nullptr;
8573  auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
8574  auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
8575  auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
8576  if (!AJ || !BJ || !CJ)
8577  return nullptr;
8578 
8579  // Get compiler tool.
8580  const Tool *T = TC.SelectTool(*CJ);
8581  if (!T)
8582  return nullptr;
8583 
8584  // Can't collapse if we don't have codegen support unless we are
8585  // emitting LLVM IR.
8586  bool OutputIsLLVM = types::isLLVMIR(ActionInfo[0].JA->getType());
8587  if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR()))
8588  return nullptr;
8589 
8590  // When using -fembed-bitcode, it is required to have the same tool (clang)
8591  // for both CompilerJA and BackendJA. Otherwise, combine two stages.
8592  if (EmbedBitcode) {
8593  const Tool *BT = TC.SelectTool(*BJ);
8594  if (BT == T)
8595  return nullptr;
8596  }
8597 
8598  if (!T->hasIntegratedAssembler())
8599  return nullptr;
8600 
8601  Inputs = CJ->getInputs();
8602  AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
8603  /*NumElements=*/3);
8604  return T;
8605  }
8606  const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
8607  ActionList &Inputs,
8608  ActionList &CollapsedOffloadAction) {
8609  if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
8610  return nullptr;
8611  auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
8612  auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
8613  if (!AJ || !BJ)
8614  return nullptr;
8615 
8616  // Get backend tool.
8617  const Tool *T = TC.SelectTool(*BJ);
8618  if (!T)
8619  return nullptr;
8620 
8621  if (!T->hasIntegratedAssembler())
8622  return nullptr;
8623 
8624  Inputs = BJ->getInputs();
8625  AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
8626  /*NumElements=*/2);
8627  return T;
8628  }
8629  const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
8630  ActionList &Inputs,
8631  ActionList &CollapsedOffloadAction) {
8632  if (ActionInfo.size() < 2)
8633  return nullptr;
8634  auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
8635  auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
8636  if (!BJ || !CJ)
8637  return nullptr;
8638 
8639  // Check if the initial input (to the compile job or its predessor if one
8640  // exists) is LLVM bitcode. In that case, no preprocessor step is required
8641  // and we can still collapse the compile and backend jobs when we have
8642  // -save-temps. I.e. there is no need for a separate compile job just to
8643  // emit unoptimized bitcode.
8644  bool InputIsBitcode = true;
8645  for (size_t i = 1; i < ActionInfo.size(); i++)
8646  if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
8647  ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
8648  InputIsBitcode = false;
8649  break;
8650  }
8651  if (!InputIsBitcode && !canCollapsePreprocessorAction())
8652  return nullptr;
8653 
8654  // Get compiler tool.
8655  const Tool *T = TC.SelectTool(*CJ);
8656  if (!T)
8657  return nullptr;
8658 
8659  // Can't collapse if we don't have codegen support unless we are
8660  // emitting LLVM IR.
8661  bool OutputIsLLVM = types::isLLVMIR(ActionInfo[0].JA->getType());
8662  if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR()))
8663  return nullptr;
8664 
8665  if (T->canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode))
8666  return nullptr;
8667 
8668  Inputs = CJ->getInputs();
8669  AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
8670  /*NumElements=*/2);
8671  return T;
8672  }
8673 
8674  /// Updates the inputs if the obtained tool supports combining with
8675  /// preprocessor action, and the current input is indeed a preprocessor
8676  /// action. If combining results in the collapse of offloading actions, those
8677  /// are appended to \a CollapsedOffloadAction.
8678  void combineWithPreprocessor(const Tool *T, ActionList &Inputs,
8679  ActionList &CollapsedOffloadAction) {
8680  if (!T || !canCollapsePreprocessorAction() || !T->hasIntegratedCPP())
8681  return;
8682 
8683  // Attempt to get a preprocessor action dependence.
8684  ActionList PreprocessJobOffloadActions;
8685  ActionList NewInputs;
8686  for (Action *A : Inputs) {
8687  auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
8688  if (!PJ || !isa<PreprocessJobAction>(PJ)) {
8689  NewInputs.push_back(A);
8690  continue;
8691  }
8692 
8693  // This is legal to combine. Append any offload action we found and add the
8694  // current input to preprocessor inputs.
8695  CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
8696  PreprocessJobOffloadActions.end());
8697  NewInputs.append(PJ->input_begin(), PJ->input_end());
8698  }
8699  Inputs = NewInputs;
8700  }
8701 
8702 public:
8703  ToolSelector(const JobAction *BaseAction, const ToolChain &TC,
8704  const Compilation &C, bool SaveTemps, bool EmbedBitcode)
8705  : TC(TC), C(C), BaseAction(BaseAction), SaveTemps(SaveTemps),
8707  assert(BaseAction && "Invalid base action.");
8708  IsHostSelector = BaseAction->getOffloadingDeviceKind() == Action::OFK_None;
8709  }
8710 
8711  /// Check if a chain of actions can be combined and return the tool that can
8712  /// handle the combination of actions. The pointer to the current inputs \a
8713  /// Inputs and the list of offload actions \a CollapsedOffloadActions
8714  /// connected to collapsed actions are updated accordingly. The latter enables
8715  /// the caller of the selector to process them afterwards instead of just
8716  /// dropping them. If no suitable tool is found, null will be returned.
8717  const Tool *getTool(ActionList &Inputs,
8718  ActionList &CollapsedOffloadAction) {
8719  //
8720  // Get the largest chain of actions that we could combine.
8721  //
8722 
8723  SmallVector<JobActionInfo, 5> ActionChain(1);
8724  ActionChain.back().JA = BaseAction;
8725  while (ActionChain.back().JA) {
8726  const Action *CurAction = ActionChain.back().JA;
8727 
8728  // Grow the chain by one element.
8729  ActionChain.resize(ActionChain.size() + 1);
8730  JobActionInfo &AI = ActionChain.back();
8731 
8732  // Attempt to fill it with the
8733  AI.JA =
8734  getPrevDependentAction(CurAction->getInputs(), AI.SavedOffloadAction);
8735  }
8736 
8737  // Pop the last action info as it could not be filled.
8738  ActionChain.pop_back();
8739 
8740  //
8741  // Attempt to combine actions. If all combining attempts failed, just return
8742  // the tool of the provided action. At the end we attempt to combine the
8743  // action with any preprocessor action it may depend on.
8744  //
8745 
8746  const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
8747  CollapsedOffloadAction);
8748  if (!T)
8749  T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
8750  if (!T)
8751  T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
8752  if (!T) {
8753  Inputs = BaseAction->getInputs();
8754  T = TC.SelectTool(*BaseAction);
8755  }
8756 
8757  combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
8758  return T;
8759  }
8760 };
8761 }
8762 
8763 /// Return a string that uniquely identifies the result of a job. The bound arch
8764 /// is not necessarily represented in the toolchain's triple -- for example,
8765 /// armv7 and armv7s both map to the same triple -- so we need both in our map.
8766 /// Also, we need to add the offloading device kind, as the same tool chain can
8767 /// be used for host and device for some programming models, e.g. OpenMP.
8768 static std::string GetTriplePlusArchString(const ToolChain *TC,
8769  StringRef BoundArch,
8770  Action::OffloadKind OffloadKind) {
8771  std::string TriplePlusArch = TC->getTriple().normalize();
8772  if (!BoundArch.empty()) {
8773  TriplePlusArch += "-";
8774  TriplePlusArch += BoundArch;
8775  }
8776  TriplePlusArch += "-";
8777  TriplePlusArch += Action::GetOffloadKindName(OffloadKind);
8778  return TriplePlusArch;
8779 }
8780 
8782  InputInfoList &InputInfos, const Action *SourceAction, const ToolChain *TC,
8783  StringRef BoundArch, Action::OffloadKind TargetDeviceOffloadKind,
8784  const std::map<std::pair<const Action *, std::string>, InputInfoList>
8785  &CachedResults,
8786  const ForEachWrappingAction *FEA) {
8787  for (const Action *Input : SourceAction->getInputs()) {
8788  // Search for the Input, if not in the cache assume actions were collapsed
8789  // so recurse.
8790  auto Lookup = CachedResults.find(
8791  {Input,
8792  GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)});
8793  if (Lookup != CachedResults.end()) {
8794  if (!FEA->getSerialActions().count(Input)) {
8795  InputInfos.append(Lookup->second);
8796  }
8797  } else {
8798  CollectForEachInputs(InputInfos, Input, TC, BoundArch,
8799  TargetDeviceOffloadKind, CachedResults, FEA);
8800  }
8801  }
8802 }
8803 
8805  Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch,
8806  bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,
8807  std::map<std::pair<const Action *, std::string>, InputInfoList>
8808  &CachedResults,
8809  Action::OffloadKind TargetDeviceOffloadKind) const {
8810  std::pair<const Action *, std::string> ActionTC = {
8811  A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};
8812  auto CachedResult = CachedResults.find(ActionTC);
8813  if (CachedResult != CachedResults.end()) {
8814  return CachedResult->second;
8815  }
8816  InputInfoList Result = BuildJobsForActionNoCache(
8817  C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
8818  CachedResults, TargetDeviceOffloadKind);
8819  CachedResults[ActionTC] = Result;
8820  return Result;
8821 }
8822 
8823 static void handleTimeTrace(Compilation &C, const ArgList &Args,
8824  const JobAction *JA, const char *BaseInput,
8825  const InputInfo &Result) {
8826  Arg *A =
8827  Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
8828  if (!A)
8829  return;
8830  SmallString<128> Path;
8831  if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
8832  Path = A->getValue();
8833  if (llvm::sys::fs::is_directory(Path)) {
8834  SmallString<128> Tmp(Result.getFilename());
8835  llvm::sys::path::replace_extension(Tmp, "json");
8836  llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
8837  }
8838  } else {
8839  if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
8840  // The trace file is ${dumpdir}${basename}.json. Note that dumpdir may not
8841  // end with a path separator.
8842  Path = DumpDir->getValue();
8843  Path += llvm::sys::path::filename(BaseInput);
8844  } else {
8845  Path = Result.getFilename();
8846  }
8847  llvm::sys::path::replace_extension(Path, "json");
8848  }
8849  const char *ResultFile = C.getArgs().MakeArgString(Path);
8850  C.addTimeTraceFile(ResultFile, JA);
8851  C.addResultFile(ResultFile, JA);
8852 }
8853 
8854 InputInfoList Driver::BuildJobsForActionNoCache(
8855  Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch,
8856  bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,
8857  std::map<std::pair<const Action *, std::string>, InputInfoList>
8858  &CachedResults,
8859  Action::OffloadKind TargetDeviceOffloadKind) const {
8860  llvm::PrettyStackTraceString CrashInfo("Building compilation jobs");
8861 
8862  InputInfoList OffloadDependencesInputInfo;
8863  bool BuildingForOffloadDevice = TargetDeviceOffloadKind != Action::OFK_None;
8864  if (const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
8865  // The 'Darwin' toolchain is initialized only when its arguments are
8866  // computed. Get the default arguments for OFK_None to ensure that
8867  // initialization is performed before processing the offload action.
8868  // FIXME: Remove when darwin's toolchain is initialized during construction.
8869  C.getArgsForToolChain(TC, BoundArch, Action::OFK_None);
8870 
8871  // The offload action is expected to be used in four different situations.
8872  //
8873  // a) Set a toolchain/architecture/kind for a host action:
8874  // Host Action 1 -> OffloadAction -> Host Action 2
8875  //
8876  // b) Set a toolchain/architecture/kind for a device action;
8877  // Device Action 1 -> OffloadAction -> Device Action 2
8878  //
8879  // c) Specify a device dependence to a host action;
8880  // Device Action 1 _
8881  // \
8882  // Host Action 1 ---> OffloadAction -> Host Action 2
8883  //
8884  // d) Specify a host dependence to a device action.
8885  // Host Action 1 _
8886  // \
8887  // Device Action 1 ---> OffloadAction -> Device Action 2
8888  //
8889  // For a) and b), we just return the job generated for the dependences. For
8890  // c) and d) we override the current action with the host/device dependence
8891  // if the current toolchain is host/device and set the offload dependences
8892  // info with the jobs obtained from the device/host dependence(s).
8893 
8894  // If there is a single device option or has no host action, just generate
8895  // the job for it.
8896  if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
8897  InputInfoList DevA;
8898  OA->doOnEachDeviceDependence([&](Action *DepA, const ToolChain *DepTC,
8899  const char *DepBoundArch) {
8900  DevA.append(BuildJobsForAction(C, DepA, DepTC, DepBoundArch, AtTopLevel,
8901  /*MultipleArchs*/ !!DepBoundArch,
8902  LinkingOutput, CachedResults,
8903  DepA->getOffloadingDeviceKind()));
8904  });
8905  return DevA;
8906  }
8907 
8908  // If 'Action 2' is host, we generate jobs for the device dependences and
8909  // override the current action with the host dependence. Otherwise, we
8910  // generate the host dependences and override the action with the device
8911  // dependence. The dependences can't therefore be a top-level action.
8912  OA->doOnEachDependence(
8913  /*IsHostDependence=*/BuildingForOffloadDevice,
8914  [&](Action *DepA, const ToolChain *DepTC, const char *DepBoundArch) {
8915  OffloadDependencesInputInfo.append(BuildJobsForAction(
8916  C, DepA, DepTC, DepBoundArch, /*AtTopLevel=*/false,
8917  /*MultipleArchs*/ !!DepBoundArch, LinkingOutput, CachedResults,
8918  DepA->getOffloadingDeviceKind()));
8919  });
8920 
8921  A = BuildingForOffloadDevice
8922  ? OA->getSingleDeviceDependence(/*DoNotConsiderHostActions=*/true)
8923  : OA->getHostDependence();
8924 
8925  // We may have already built this action as a part of the offloading
8926  // toolchain, return the cached input if so.
8927  std::pair<const Action *, std::string> ActionTC = {
8928  OA->getHostDependence(),
8929  GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};
8930  if (CachedResults.find(ActionTC) != CachedResults.end()) {
8931  InputInfoList Inputs = CachedResults[ActionTC];
8932  Inputs.append(OffloadDependencesInputInfo);
8933  return Inputs;
8934  }
8935  }
8936 
8937  if (const InputAction *IA = dyn_cast<InputAction>(A)) {
8938  // FIXME: It would be nice to not claim this here; maybe the old scheme of
8939  // just using Args was better?
8940  const Arg &Input = IA->getInputArg();
8941  Input.claim();
8942  if (Input.getOption().matches(options::OPT_INPUT)) {
8943  const char *Name = Input.getValue();
8944  return {InputInfo(A, Name, /* _BaseInput = */ Name)};
8945  }
8946  return {InputInfo(A, &Input, /* _BaseInput = */ "")};
8947  }
8948  if (const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
8949  const ToolChain *TC;
8950  StringRef ArchName = BAA->getArchName();
8951 
8952  if (!ArchName.empty())
8953  TC = &getToolChain(C.getArgs(),
8954  computeTargetTriple(*this, TargetTriple,
8955  C.getArgs(), ArchName));
8956  else
8957  TC = &C.getDefaultToolChain();
8958 
8959  return BuildJobsForAction(C, *BAA->input_begin(), TC, ArchName, AtTopLevel,
8960  MultipleArchs, LinkingOutput, CachedResults,
8961  TargetDeviceOffloadKind);
8962  }
8963 
8964  if (const ForEachWrappingAction *FEA = dyn_cast<ForEachWrappingAction>(A)) {
8965  // Check that the main action wasn't already processed.
8966  auto MainActionOutput = CachedResults.find(
8967  {FEA->getJobAction(),
8968  GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)});
8969  if (MainActionOutput != CachedResults.end()) {
8970  // The input was processed on behalf of another foreach.
8971  // Add entry in cache and return.
8972  CachedResults[{FEA, GetTriplePlusArchString(TC, BoundArch,
8973  TargetDeviceOffloadKind)}] =
8974  MainActionOutput->second;
8975  return MainActionOutput->second;
8976  }
8977 
8978  // Build commands for the TFormInput then take any command added after as
8979  // needing a llvm-foreach wrapping.
8980  BuildJobsForAction(C, FEA->getTFormInput(), TC, BoundArch,
8981  /*AtTopLevel=*/false, MultipleArchs, LinkingOutput,
8982  CachedResults, TargetDeviceOffloadKind);
8983  unsigned OffsetIdx = C.getJobs().size();
8984  BuildJobsForAction(C, FEA->getJobAction(), TC, BoundArch,
8985  /*AtTopLevel=*/false, MultipleArchs, LinkingOutput,
8986  CachedResults, TargetDeviceOffloadKind);
8987 
8988  auto begin = C.getJobs().getJobsForOverride().begin() + OffsetIdx;
8989  auto end = C.getJobs().getJobsForOverride().end();
8990 
8991  // Steal the commands.
8993  std::make_move_iterator(begin), std::make_move_iterator(end));
8994  C.getJobs().getJobsForOverride().erase(begin, end);
8995 
8997  for (std::unique_ptr<Command> Cmd :
8998  llvm::make_range(std::make_move_iterator(JobsToWrap.begin()),
8999  std::make_move_iterator(JobsToWrap.end()))) {
9000  const JobAction *SourceAction = cast<JobAction>(&Cmd->getSource());
9001  if (FEA->getSerialActions().count(SourceAction)) {
9002  C.addCommand(std::move(Cmd));
9003  continue;
9004  }
9005  ActionResult = CachedResults.at(
9006  {SourceAction,
9007  GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)}).front();
9008  InputInfoList InputInfos;
9009  CollectForEachInputs(InputInfos, SourceAction, TC, BoundArch,
9010  TargetDeviceOffloadKind, CachedResults, FEA);
9011  const Tool *Creator = &Cmd->getCreator();
9012  StringRef ParallelJobs;
9013  if (TargetDeviceOffloadKind == Action::OFK_SYCL)
9014  ParallelJobs = C.getArgs().getLastArgValue(
9015  options::OPT_fsycl_max_parallel_jobs_EQ);
9016 
9018  C, *SourceAction, std::move(Cmd), InputInfos, ActionResult, Creator,
9019  "", types::getTypeTempSuffix(ActionResult.getType()), ParallelJobs);
9020  }
9021  return { ActionResult };
9022  }
9023 
9024  ActionList Inputs = A->getInputs();
9025 
9026  const JobAction *JA = cast<JobAction>(A);
9027  ActionList CollapsedOffloadActions;
9028 
9029  auto *DA = dyn_cast<OffloadDepsJobAction>(JA);
9030  const ToolChain *JATC = DA ? DA->getHostTC() : TC;
9031 
9032  ToolSelector TS(JA, *JATC, C, isSaveTempsEnabled(),
9034  const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
9035 
9036  if (!T)
9037  return {InputInfo()};
9038 
9039  // If we've collapsed action list that contained OffloadAction we
9040  // need to build jobs for host/device-side inputs it may have held.
9041  for (const auto *OA : CollapsedOffloadActions)
9042  cast<OffloadAction>(OA)->doOnEachDependence(
9043  /*IsHostDependence=*/BuildingForOffloadDevice,
9044  [&](Action *DepA, const ToolChain *DepTC, const char *DepBoundArch) {
9045  OffloadDependencesInputInfo.append(BuildJobsForAction(
9046  C, DepA, DepTC, DepBoundArch, /* AtTopLevel */ false,
9047  /*MultipleArchs=*/!!DepBoundArch, LinkingOutput, CachedResults,
9048  DepA->getOffloadingDeviceKind()));
9049  });
9050 
9051  // Only use pipes when there is exactly one input.
9052  InputInfoList InputInfos;
9053  for (const Action *Input : Inputs) {
9054  // Treat dsymutil and verify sub-jobs as being at the top-level too, they
9055  // shouldn't get temporary output names.
9056  // FIXME: Clean this up.
9057  bool SubJobAtTopLevel =
9058  AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
9059  InputInfos.append(BuildJobsForAction(
9060  C, Input, JATC, DA ? DA->getOffloadingArch() : BoundArch,
9061  SubJobAtTopLevel, MultipleArchs, LinkingOutput, CachedResults,
9062  A->getOffloadingDeviceKind()));
9063  }
9064 
9065  // Always use the first file input as the base input.
9066  const char *BaseInput = InputInfos[0].getBaseInput();
9067  for (auto &Info : InputInfos) {
9068  if (Info.isFilename()) {
9069  BaseInput = Info.getBaseInput();
9070  break;
9071  }
9072  }
9073 
9074  // ... except dsymutil actions, which use their actual input as the base
9075  // input.
9076  if (JA->getType() == types::TY_dSYM)
9077  BaseInput = InputInfos[0].getFilename();
9078 
9079  // Append outputs of offload device jobs to the input list
9080  if (!OffloadDependencesInputInfo.empty())
9081  InputInfos.append(OffloadDependencesInputInfo.begin(),
9082  OffloadDependencesInputInfo.end());
9083 
9084  // Set the effective triple of the toolchain for the duration of this job.
9085  llvm::Triple EffectiveTriple;
9086  const ToolChain &ToolTC = T->getToolChain();
9087  const ArgList &Args =
9088  C.getArgsForToolChain(TC, BoundArch, A->getOffloadingDeviceKind());
9089  if (InputInfos.size() != 1) {
9090  EffectiveTriple = llvm::Triple(ToolTC.ComputeEffectiveClangTriple(Args));
9091  } else {
9092  // Pass along the input type if it can be unambiguously determined.
9093  EffectiveTriple = llvm::Triple(
9094  ToolTC.ComputeEffectiveClangTriple(Args, InputInfos[0].getType()));
9095  }
9096  RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
9097 
9098  // Determine the place to write output to, if any.
9099  InputInfo Result;
9100  InputInfoList UnbundlingResults;
9101  if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
9102  // If we have an unbundling job, we need to create results for all the
9103  // outputs. We also update the results cache so that other actions using
9104  // this unbundling action can get the right results.
9105  for (auto &UI : UA->getDependentActionsInfo()) {
9106  assert(UI.DependentOffloadKind != Action::OFK_None &&
9107  "Unbundling with no offloading??");
9108 
9109  // Unbundling actions are never at the top level. When we generate the
9110  // offloading prefix, we also do that for the host file because the
9111  // unbundling action does not change the type of the output which can
9112  // cause a overwrite.
9113  InputInfo CurI;
9114  bool IsFPGAObjLink =
9115  (JA->getType() == types::TY_Object &&
9116  EffectiveTriple.getSubArch() == llvm::Triple::SPIRSubArch_fpga &&
9117  C.getInputArgs().hasArg(options::OPT_fsycl_link_EQ));
9118  if (C.getDriver().getOffloadStaticLibSeen() &&
9119  (JA->getType() == types::TY_Archive ||
9120  JA->getType() == types::TY_Tempfilelist)) {
9121  // Host part of the unbundled static archive is not used.
9122  if (UI.DependentOffloadKind == Action::OFK_Host)
9123  continue;
9124  // Host part of the unbundled object is not used when using the
9125  // FPGA target and -fsycl-link is enabled.
9126  if (UI.DependentOffloadKind == Action::OFK_Host && IsFPGAObjLink)
9127  continue;
9128  std::string TmpFileName = C.getDriver().GetTemporaryPath(
9129  llvm::sys::path::stem(BaseInput),
9130  JA->getType() == types::TY_Archive ? "a" : "txt");
9131  const char *TmpFile = C.addTempFile(
9132  C.getArgs().MakeArgString(TmpFileName), JA->getType());
9133  CurI = InputInfo(JA->getType(), TmpFile, TmpFile);
9134  } else if (types::isFPGA(JA->getType())) {
9135  std::string Ext(types::getTypeTempSuffix(JA->getType()));
9136  types::ID TI = types::TY_Object;
9137  if (EffectiveTriple.isSPIROrSPIRV()) {
9138  if (!UI.DependentToolChain->getTriple().isSPIROrSPIRV())
9139  continue;
9140  // Output file from unbundle is FPGA device. Name the file
9141  // accordingly.
9142  if (UI.DependentOffloadKind == Action::OFK_Host) {
9143  // Do not add the current info for Host with FPGA device. The host
9144  // side isn't used
9145  continue;
9146  }
9147  if (JA->getType() == types::TY_FPGA_AOCO) {
9148  TI = types::TY_TempAOCOfilelist;
9149  Ext = "txt";
9150  }
9151  if (JA->getType() == types::TY_FPGA_AOCR ||
9152  JA->getType() == types::TY_FPGA_AOCX ||
9153  JA->getType() == types::TY_FPGA_AOCR_EMU) {
9154  if (IsFPGAObjLink)
9155  continue;
9156  // AOCR files are always unbundled into a list file.
9157  TI = types::TY_Tempfilelist;
9158  }
9159  } else {
9160  if (UI.DependentOffloadKind == Action::OFK_SYCL)
9161  // Do not add the current info for device with FPGA device. The
9162  // device side isn't used
9163  continue;
9164  TI = types::TY_Tempfilelist;
9165  Ext = "txt";
9166  }
9167  std::string TmpFileName = C.getDriver().GetTemporaryPath(
9168  llvm::sys::path::stem(BaseInput), Ext);
9169  const char *TmpFile =
9170  C.addTempFile(C.getArgs().MakeArgString(TmpFileName), TI);
9171  CurI = InputInfo(TI, TmpFile, TmpFile);
9172  } else {
9173  // Host part of the unbundled object is not used when -fsycl-link is
9174  // enabled with FPGA target
9175  if (UI.DependentOffloadKind == Action::OFK_Host && IsFPGAObjLink)
9176  continue;
9177  std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix(
9178  UI.DependentOffloadKind,
9179  UI.DependentToolChain->getTriple().normalize(),
9180  /*CreatePrefixForHost=*/true);
9181  CurI = InputInfo(
9182  UA,
9183  GetNamedOutputPath(C, *UA, BaseInput, UI.DependentBoundArch,
9184  /*AtTopLevel=*/false,
9185  MultipleArchs ||
9186  UI.DependentOffloadKind == Action::OFK_HIP,
9187  OffloadingPrefix),
9188  BaseInput);
9189  }
9190  // Save the unbundling result.
9191  UnbundlingResults.push_back(CurI);
9192 
9193  // Get the unique string identifier for this dependence and cache the
9194  // result.
9195  StringRef Arch;
9196  if (TargetDeviceOffloadKind == Action::OFK_HIP ||
9197  TargetDeviceOffloadKind == Action::OFK_SYCL) {
9198  if (UI.DependentOffloadKind == Action::OFK_Host)
9199  Arch = StringRef();
9200  else
9201  Arch = UI.DependentBoundArch;
9202  } else
9203  Arch = BoundArch;
9204  // When unbundling for SYCL and there is no Target offload, assume
9205  // Host as the dependent offload, as the host path has been stripped
9206  // in this instance
9207  Action::OffloadKind DependentOffloadKind;
9208  if (UI.DependentOffloadKind == Action::OFK_SYCL &&
9209  TargetDeviceOffloadKind == Action::OFK_None &&
9210  !(isSYCLNativeCPU(Args) && isSYCLNativeCPU(C.getDefaultToolChain().getTriple(), TC->getTriple())))
9211  DependentOffloadKind = Action::OFK_Host;
9212  else
9213  DependentOffloadKind = UI.DependentOffloadKind;
9214 
9215  CachedResults[{A, GetTriplePlusArchString(UI.DependentToolChain, Arch,
9216  DependentOffloadKind)}] = {
9217  CurI};
9218  }
9219  // Do a check for a dependency file unbundle for FPGA. This is out of line
9220  // from a regular unbundle, so just create and return the name of the
9221  // unbundled file.
9222  if (JA->getType() == types::TY_FPGA_Dependencies ||
9223  JA->getType() == types::TY_FPGA_Dependencies_List) {
9224  std::string Ext(types::getTypeTempSuffix(JA->getType()));
9225  std::string TmpFileName =
9226  C.getDriver().GetTemporaryPath(llvm::sys::path::stem(BaseInput), Ext);
9227  const char *TmpFile =
9228  C.addTempFile(C.getArgs().MakeArgString(TmpFileName), JA->getType());
9229  Result = InputInfo(JA->getType(), TmpFile, TmpFile);
9230  UnbundlingResults.push_back(Result);
9231  } else {
9232  // Now that we have all the results generated, select the one that should
9233  // be returned for the current depending action.
9234  std::pair<const Action *, std::string> ActionTC = {
9235  A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};
9236  assert(CachedResults.find(ActionTC) != CachedResults.end() &&
9237  "Result does not exist??");
9238  Result = CachedResults[ActionTC].front();
9239  }
9240  } else if (auto *DA = dyn_cast<OffloadDepsJobAction>(JA)) {
9241  for (auto &DI : DA->getDependentActionsInfo()) {
9242  assert(DI.DependentOffloadKind != Action::OFK_None &&
9243  "Deps job with no offloading");
9244 
9245  std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix(
9246  DI.DependentOffloadKind,
9247  DI.DependentToolChain->getTriple().normalize(),
9248  /*CreatePrefixForHost=*/true);
9249  auto CurI = InputInfo(
9250  DA,
9251  GetNamedOutputPath(C, *DA, BaseInput, DI.DependentBoundArch,
9252  /*AtTopLevel=*/false,
9253  MultipleArchs ||
9254  DI.DependentOffloadKind == Action::OFK_HIP,
9255  OffloadingPrefix),
9256  BaseInput);
9257  // Save the result.
9258  UnbundlingResults.push_back(CurI);
9259 
9260  // Get the unique string identifier for this dependence and cache the
9261  // result.
9262  StringRef Arch = TargetDeviceOffloadKind == Action::OFK_HIP
9263  ? DI.DependentOffloadKind == Action::OFK_Host
9264  ? StringRef()
9265  : DI.DependentBoundArch
9266  : BoundArch;
9267 
9268  CachedResults[{A, GetTriplePlusArchString(DI.DependentToolChain, Arch,
9269  DI.DependentOffloadKind)}] = {
9270  CurI};
9271  }
9272 
9273  // Now that we have all the results generated, select the one that should be
9274  // returned for the current depending action.
9275  std::pair<const Action *, std::string> ActionTC = {
9276  A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};
9277  auto It = CachedResults.find(ActionTC);
9278  assert(It != CachedResults.end() && "Result does not exist??");
9279  Result = It->second.front();
9280  } else if (JA->getType() == types::TY_Nothing)
9281  Result = {InputInfo(A, BaseInput)};
9282  else {
9283  std::string OffloadingPrefix;
9284  // When generating binaries with -fsycl-link, the output file prefix is the
9285  // triple arch only. Do not add the arch when compiling for host.
9286  if (!A->getOffloadingHostActiveKinds() &&
9287  Args.hasArg(options::OPT_fsycl_link_EQ)) {
9288  OffloadingPrefix = "-";
9289  OffloadingPrefix += TC->getTriple().getArchName();
9290  } else {
9291  // We only have to generate a prefix for the host if this is not a
9292  // top-level action.
9293  OffloadingPrefix = Action::GetOffloadingFileNamePrefix(
9294  A->getOffloadingDeviceKind(), TC->getTriple().normalize(),
9295  /*CreatePrefixForHost=*/isa<OffloadPackagerJobAction>(A) ||
9297  AtTopLevel));
9298  }
9299  if (isa<OffloadWrapperJobAction>(JA)) {
9300  if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
9301  BaseInput = FinalOutput->getValue();
9302  // Do not use the default image name when using -fno-sycl-rdc
9304  BaseInput = getDefaultImageName();
9305  BaseInput =
9306  C.getArgs().MakeArgString(std::string(BaseInput) + "-wrapper");
9307  }
9308  Result = InputInfo(A, GetNamedOutputPath(C, *JA, BaseInput, BoundArch,
9309  AtTopLevel, MultipleArchs,
9310  OffloadingPrefix),
9311  BaseInput);
9312  if (T->canEmitIR() && OffloadingPrefix.empty())
9313  handleTimeTrace(C, Args, JA, BaseInput, Result);
9314  }
9315 
9317  llvm::errs() << "# \"" << T->getToolChain().getTripleString() << '"'
9318  << " - \"" << T->getName() << "\", inputs: [";
9319  for (unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
9320  llvm::errs() << InputInfos[i].getAsString();
9321  if (i + 1 != e)
9322  llvm::errs() << ", ";
9323  }
9324  if (UnbundlingResults.empty())
9325  llvm::errs() << "], output: " << Result.getAsString() << "\n";
9326  else {
9327  llvm::errs() << "], outputs: [";
9328  for (unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
9329  llvm::errs() << UnbundlingResults[i].getAsString();
9330  if (i + 1 != e)
9331  llvm::errs() << ", ";
9332  }
9333  llvm::errs() << "] \n";
9334  }
9335  } else {
9336  if (UnbundlingResults.empty())
9337  T->ConstructJob(
9338  C, *JA, Result, InputInfos,
9339  C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()),
9340  LinkingOutput);
9341  else
9342  T->ConstructJobMultipleOutputs(
9343  C, *JA, UnbundlingResults, InputInfos,
9344  C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()),
9345  LinkingOutput);
9346  }
9347  return {Result};
9348 }
9349 
9350 const char *Driver::getDefaultImageName() const {
9351  llvm::Triple Target(llvm::Triple::normalize(TargetTriple));
9352  return Target.isOSWindows() ? "a.exe" : "a.out";
9353 }
9354 
9355 /// Create output filename based on ArgValue, which could either be a
9356 /// full filename, filename without extension, or a directory. If ArgValue
9357 /// does not provide a filename, then use BaseName, and use the extension
9358 /// suitable for FileType.
9359 static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue,
9360  StringRef BaseName,
9361  types::ID FileType) {
9362  SmallString<128> Filename = ArgValue;
9363 
9364  if (ArgValue.empty()) {
9365  // If the argument is empty, output to BaseName in the current dir.
9366  Filename = BaseName;
9367  } else if (llvm::sys::path::is_separator(Filename.back())) {
9368  // If the argument is a directory, output to BaseName in that dir.
9369  llvm::sys::path::append(Filename, BaseName);
9370  }
9371 
9372  if (!llvm::sys::path::has_extension(ArgValue)) {
9373  // If the argument didn't provide an extension, then set it.
9374  const char *Extension = types::getTypeTempSuffix(FileType, true);
9375 
9376  if (FileType == types::TY_Image &&
9377  Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
9378  // The output file is a dll.
9379  Extension = "dll";
9380  }
9381 
9382  llvm::sys::path::replace_extension(Filename, Extension);
9383  }
9384 
9385  return Args.MakeArgString(Filename.c_str());
9386 }
9387 
9388 static bool HasPreprocessOutput(const Action &JA) {
9389  if (isa<PreprocessJobAction>(JA))
9390  return true;
9391  if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.getInputs()[0]))
9392  return true;
9393  if (isa<OffloadBundlingJobAction>(JA) &&
9394  HasPreprocessOutput(*(JA.getInputs()[0])))
9395  return true;
9396  return false;
9397 }
9398 
9399 const char *Driver::CreateTempFile(Compilation &C, StringRef Prefix,
9400  StringRef Suffix, bool MultipleArchs,
9401  StringRef BoundArch,
9402  types::ID Type,
9403  bool NeedUniqueDirectory) const {
9404  SmallString<128> TmpName;
9405  Arg *A = C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
9406  std::optional<std::string> CrashDirectory =
9407  CCGenDiagnostics && A
9408  ? std::string(A->getValue())
9409  : llvm::sys::Process::GetEnv("CLANG_CRASH_DIAGNOSTICS_DIR");
9410  if (CrashDirectory) {
9411  if (!getVFS().exists(*CrashDirectory))
9412  llvm::sys::fs::create_directories(*CrashDirectory);
9413  SmallString<128> Path(*CrashDirectory);
9414  llvm::sys::path::append(Path, Prefix);
9415  const char *Middle = !Suffix.empty() ? "-%%%%%%." : "-%%%%%%";
9416  if (std::error_code EC =
9417  llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
9418  Diag(clang::diag::err_unable_to_make_temp) << EC.message();
9419  return "";
9420  }
9421  } else {
9422  if (MultipleArchs && !BoundArch.empty()) {
9423  if (NeedUniqueDirectory) {
9424  TmpName = GetTemporaryDirectory(Prefix);
9425  llvm::sys::path::append(TmpName,
9426  Twine(Prefix) + "-" + BoundArch + "." + Suffix);
9427  } else {
9428  TmpName =
9429  GetTemporaryPath((Twine(Prefix) + "-" + BoundArch).str(), Suffix);
9430  }
9431 
9432  } else {
9433  TmpName = GetTemporaryPath(Prefix, Suffix);
9434  }
9435  }
9436  return C.addTempFile(C.getArgs().MakeArgString(TmpName), Type);
9437 }
9438 
9439 // Calculate the output path of the module file when compiling a module unit
9440 // with the `-fmodule-output` option or `-fmodule-output=` option specified.
9441 // The behavior is:
9442 // - If `-fmodule-output=` is specfied, then the module file is
9443 // writing to the value.
9444 // - Otherwise if the output object file of the module unit is specified, the
9445 // output path
9446 // of the module file should be the same with the output object file except
9447 // the corresponding suffix. This requires both `-o` and `-c` are specified.
9448 // - Otherwise, the output path of the module file will be the same with the
9449 // input with the corresponding suffix.
9450 static const char *GetModuleOutputPath(Compilation &C, const JobAction &JA,
9451  const char *BaseInput) {
9452  assert(isa<PrecompileJobAction>(JA) && JA.getType() == types::TY_ModuleFile &&
9453  (C.getArgs().hasArg(options::OPT_fmodule_output) ||
9454  C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
9455 
9456  SmallString<256> OutputPath =
9457  tools::getCXX20NamedModuleOutputPath(C.getArgs(), BaseInput);
9458 
9459  return C.addResultFile(C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
9460 }
9461 
9463  const char *BaseInput,
9464  StringRef OrigBoundArch, bool AtTopLevel,
9465  bool MultipleArchs,
9466  StringRef OffloadingPrefix) const {
9467  std::string BoundArch = OrigBoundArch.str();
9468  if (is_style_windows(llvm::sys::path::Style::native)) {
9469  // BoundArch may contains ':', which is invalid in file names on Windows,
9470  // therefore replace it with '%'.
9471  std::replace(BoundArch.begin(), BoundArch.end(), ':', '@');
9472  }
9473 
9474  llvm::PrettyStackTraceString CrashInfo("Computing output path");
9475  // Output to a user requested destination?
9476  if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
9477  if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
9478  return C.addResultFile(FinalOutput->getValue(), &JA);
9479  // Output to destination for -fsycl-device-only and Windows -o
9481  if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT__SLASH_o))
9482  return C.addResultFile(FinalOutput->getValue(), &JA);
9483  }
9484 
9485  // For /P, preprocess to file named after BaseInput.
9486  if (C.getArgs().hasArg(options::OPT__SLASH_P) &&
9487  ((AtTopLevel && isa<PreprocessJobAction>(JA)) ||
9488  isa<OffloadBundlingJobAction>(JA))) {
9489  StringRef BaseName = llvm::sys::path::filename(BaseInput);
9490  StringRef NameArg;
9491  if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi))
9492  NameArg = A->getValue();
9493  return C.addResultFile(
9494  MakeCLOutputFilename(C.getArgs(), NameArg, BaseName, types::TY_PP_C),
9495  &JA);
9496  }
9497 
9498  // Redirect output for the generated source + integration footer.
9499  if (isa<AppendFooterJobAction>(JA)) {
9500  if (Arg *A = C.getArgs().getLastArg(options::OPT_fsycl_footer_path_EQ)) {
9501  SmallString<128> OutName(A->getValue());
9502  StringRef BaseName = llvm::sys::path::filename(BaseInput);
9503  if (isSaveTempsEnabled()) {
9504  // Retain the location specified by the user with -save-temps.
9505  const char *Suffix = types::getTypeTempSuffix(JA.getType());
9506  std::string::size_type End = std::string::npos;
9508  End = BaseName.rfind('.');
9509  SmallString<128> Suffixed(BaseName.substr(0, End));
9510  Suffixed += OffloadingPrefix;
9511  Suffixed += '.';
9512  Suffixed += Suffix;
9513  llvm::sys::path::append(OutName, Suffixed.c_str());
9514  } else {
9515  std::string TmpName =
9516  GetTemporaryPath(llvm::sys::path::stem(BaseName),
9518  llvm::sys::path::append(OutName, llvm::sys::path::filename(TmpName));
9519  }
9520  return C.addTempFile(C.getArgs().MakeArgString(OutName));
9521  }
9522  }
9523 
9524  // Default to writing to stdout?
9525  if (AtTopLevel && !CCGenDiagnostics && HasPreprocessOutput(JA)) {
9526  return "-";
9527  }
9528 
9529  if (JA.getType() == types::TY_ModuleFile &&
9530  C.getArgs().getLastArg(options::OPT_module_file_info)) {
9531  return "-";
9532  }
9533 
9534  if (JA.getType() == types::TY_PP_Asm &&
9535  C.getArgs().hasArg(options::OPT_dxc_Fc)) {
9536  StringRef FcValue = C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
9537  // TODO: Should we use `MakeCLOutputFilename` here? If so, we can probably
9538  // handle this as part of the SLASH_Fa handling below.
9539  return C.addResultFile(C.getArgs().MakeArgString(FcValue.str()), &JA);
9540  }
9541 
9542  if (JA.getType() == types::TY_Object &&
9543  C.getArgs().hasArg(options::OPT_dxc_Fo)) {
9544  StringRef FoValue = C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
9545  // TODO: Should we use `MakeCLOutputFilename` here? If so, we can probably
9546  // handle this as part of the SLASH_Fo handling below.
9547  return C.addResultFile(C.getArgs().MakeArgString(FoValue.str()), &JA);
9548  }
9549 
9550  // Is this the assembly listing for /FA?
9551  if (JA.getType() == types::TY_PP_Asm &&
9552  (C.getArgs().hasArg(options::OPT__SLASH_FA) ||
9553  C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
9554  // Use /Fa and the input filename to determine the asm file name.
9555  StringRef BaseName = llvm::sys::path::filename(BaseInput);
9556  StringRef FaValue = C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
9557  return C.addResultFile(
9558  MakeCLOutputFilename(C.getArgs(), FaValue, BaseName, JA.getType()),
9559  &JA);
9560  }
9561 
9562  if (JA.getType() == types::TY_API_INFO &&
9563  C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
9564  C.getArgs().hasArg(options::OPT_o))
9565  Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
9566  << C.getArgs().getLastArgValue(options::OPT_o);
9567 
9568  // DXC defaults to standard out when generating assembly. We check this after
9569  // any DXC flags that might specify a file.
9570  if (AtTopLevel && JA.getType() == types::TY_PP_Asm && IsDXCMode())
9571  return "-";
9572 
9573  bool SpecifiedModuleOutput =
9574  C.getArgs().hasArg(options::OPT_fmodule_output) ||
9575  C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
9576  if (MultipleArchs && SpecifiedModuleOutput)
9577  Diag(clang::diag::err_drv_module_output_with_multiple_arch);
9578 
9579  // If we're emitting a module output with the specified option
9580  // `-fmodule-output`.
9581  if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
9582  JA.getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
9583  assert(!C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
9584  return GetModuleOutputPath(C, JA, BaseInput);
9585  }
9586 
9587  // Output to a temporary file?
9588  if ((!AtTopLevel && !isSaveTempsEnabled() &&
9589  (!C.getArgs().hasArg(options::OPT__SLASH_Fo) ||
9590  // FIXME - The use of /Fo is limited when offloading is enabled. When
9591  // compiling to exe use of /Fo does not produce the named obj. We also
9592  // should not use the named output when performing unbundling.
9593  (C.getArgs().hasArg(options::OPT__SLASH_Fo) &&
9595  isa<OffloadUnbundlingJobAction>(JA) ||
9597  CCGenDiagnostics) {
9598  StringRef Name = llvm::sys::path::filename(BaseInput);
9599  std::pair<StringRef, StringRef> Split = Name.split('.');
9600  const char *Suffix =
9602  // The non-offloading toolchain on Darwin requires deterministic input
9603  // file name for binaries to be deterministic, therefore it needs unique
9604  // directory.
9605  llvm::Triple Triple(C.getDriver().getTargetTriple());
9606  bool NeedUniqueDirectory =
9609  Triple.isOSDarwin();
9610  return CreateTempFile(C, Split.first, Suffix, MultipleArchs, BoundArch,
9611  JA.getType(), NeedUniqueDirectory);
9612  }
9613 
9614  SmallString<128> BasePath(BaseInput);
9615  SmallString<128> ExternalPath("");
9616  StringRef BaseName;
9617 
9618  // Dsymutil actions should use the full path.
9619  if (isa<DsymutilJobAction>(JA) && C.getArgs().hasArg(options::OPT_dsym_dir)) {
9620  ExternalPath += C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
9621  // We use posix style here because the tests (specifically
9622  // darwin-dsymutil.c) demonstrate that posix style paths are acceptable
9623  // even on Windows and if we don't then the similar test covering this
9624  // fails.
9625  llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
9626  llvm::sys::path::filename(BasePath));
9627  BaseName = ExternalPath;
9628  } else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
9629  BaseName = BasePath;
9630  else
9631  BaseName = llvm::sys::path::filename(BasePath);
9632 
9633  // Determine what the derived output name should be.
9634  const char *NamedOutput;
9635 
9636  if ((JA.getType() == types::TY_Object || JA.getType() == types::TY_LTO_BC ||
9637  JA.getType() == types::TY_Archive) &&
9638  C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
9639  // The /Fo or /o flag decides the object filename.
9640  StringRef Val =
9641  C.getArgs()
9642  .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
9643  ->getValue();
9644  NamedOutput =
9645  MakeCLOutputFilename(C.getArgs(), Val, BaseName, types::TY_Object);
9646  } else if (JA.getType() == types::TY_Image &&
9647  C.getArgs().hasArg(options::OPT__SLASH_Fe,
9648  options::OPT__SLASH_o)) {
9649  // The /Fe or /o flag names the linked file.
9650  StringRef Val =
9651  C.getArgs()
9652  .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
9653  ->getValue();
9654  NamedOutput =
9655  MakeCLOutputFilename(C.getArgs(), Val, BaseName, types::TY_Image);
9656  } else if (JA.getType() == types::TY_Image) {
9657  if (IsCLMode()) {
9658  // clang-cl uses BaseName for the executable name.
9659  NamedOutput =
9660  MakeCLOutputFilename(C.getArgs(), "", BaseName, types::TY_Image);
9661  } else {
9663  // HIP image for device compilation with -fno-gpu-rdc is per compilation
9664  // unit.
9665  bool IsHIPNoRDC = JA.getOffloadingDeviceKind() == Action::OFK_HIP &&
9666  !C.getArgs().hasFlag(options::OPT_fgpu_rdc,
9667  options::OPT_fno_gpu_rdc, false);
9668  bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA) ||
9669  isa<BackendCompileJobAction>(JA);
9670  if (UseOutExtension) {
9671  Output = BaseName;
9672  llvm::sys::path::replace_extension(Output, "");
9673  }
9674  Output += OffloadingPrefix;
9675  if (MultipleArchs && !BoundArch.empty()) {
9676  Output += "-";
9677  Output.append(BoundArch);
9678  }
9679  if (UseOutExtension)
9680  Output += ".out";
9681  NamedOutput = C.getArgs().MakeArgString(Output.c_str());
9682  }
9683  } else if (JA.getType() == types::TY_PCH && IsCLMode()) {
9684  NamedOutput = C.getArgs().MakeArgString(GetClPchPath(C, BaseName));
9685  } else if ((JA.getType() == types::TY_Plist || JA.getType() == types::TY_AST) &&
9686  C.getArgs().hasArg(options::OPT__SLASH_o)) {
9687  StringRef Val =
9688  C.getArgs()
9689  .getLastArg(options::OPT__SLASH_o)
9690  ->getValue();
9691  NamedOutput =
9692  MakeCLOutputFilename(C.getArgs(), Val, BaseName, types::TY_Object);
9693  } else {
9694  const char *Suffix =
9696  assert(Suffix && "All types used for output should have a suffix.");
9697 
9698  std::string::size_type End = std::string::npos;
9700  End = BaseName.rfind('.');
9701  SmallString<128> Suffixed(BaseName.substr(0, End));
9702  Suffixed += OffloadingPrefix;
9703  if (MultipleArchs && !BoundArch.empty()) {
9704  Suffixed += "-";
9705  Suffixed.append(BoundArch);
9706  }
9707  // When using both -save-temps and -emit-llvm, use a ".tmp.bc" suffix for
9708  // the unoptimized bitcode so that it does not get overwritten by the ".bc"
9709  // optimized bitcode output.
9710  auto IsAMDRDCInCompilePhase = [](const JobAction &JA,
9711  const llvm::opt::DerivedArgList &Args) {
9712  // The relocatable compilation in HIP and OpenMP implies -emit-llvm.
9713  // Similarly, use a ".tmp.bc" suffix for the unoptimized bitcode
9714  // (generated in the compile phase.)
9715  const ToolChain *TC = JA.getOffloadingToolChain();
9716  return isa<CompileJobAction>(JA) &&
9718  Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
9719  false)) ||
9721  TC->getTriple().isAMDGPU()));
9722  };
9723  if (!AtTopLevel && JA.getType() == types::TY_LLVM_BC &&
9724  (C.getArgs().hasArg(options::OPT_emit_llvm) ||
9725  IsAMDRDCInCompilePhase(JA, C.getArgs())))
9726  Suffixed += ".tmp";
9727  Suffixed += '.';
9728  Suffixed += Suffix;
9729  NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str());
9730  }
9731 
9732  // Prepend object file path if -save-temps=obj
9733  if (!AtTopLevel && isSaveTempsObj() && C.getArgs().hasArg(options::OPT_o) &&
9734  JA.getType() != types::TY_PCH) {
9735  Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
9736  SmallString<128> TempPath(FinalOutput->getValue());
9737  llvm::sys::path::remove_filename(TempPath);
9738  StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
9739  llvm::sys::path::append(TempPath, OutputFileName);
9740  NamedOutput = C.getArgs().MakeArgString(TempPath.c_str());
9741  }
9742 
9743  if (isSaveTempsEnabled()) {
9744  // If we're saving temps and the temp file conflicts with any
9745  // input/resulting file, then avoid overwriting.
9746  if (!AtTopLevel && NamedOutput == BaseName) {
9747  bool SameFile = false;
9748  SmallString<256> Result;
9749  llvm::sys::fs::current_path(Result);
9750  llvm::sys::path::append(Result, BaseName);
9751  llvm::sys::fs::equivalent(BaseInput, Result.c_str(), SameFile);
9752  // Must share the same path to conflict.
9753  if (SameFile) {
9754  StringRef Name = llvm::sys::path::filename(BaseInput);
9755  std::pair<StringRef, StringRef> Split = Name.split('.');
9756  std::string TmpName = GetTemporaryPath(
9757  Split.first,
9759  return C.addTempFile(C.getArgs().MakeArgString(TmpName));
9760  }
9761  }
9762 
9763  const auto &ResultFiles = C.getResultFiles();
9764  const auto CollidingFilenameIt =
9765  llvm::find_if(ResultFiles, [NamedOutput](const auto &It) {
9766  return StringRef(NamedOutput) == It.second;
9767  });
9768  if (CollidingFilenameIt != ResultFiles.end()) {
9769  // Upon any collision, a unique hash will be appended to the filename,
9770  // similar to what is done for temporary files in the regular flow.
9771  StringRef CollidingName(CollidingFilenameIt->second);
9772  std::pair<StringRef, StringRef> Split = CollidingName.split('.');
9773  std::string UniqueName = GetUniquePath(
9774  Split.first,
9776  return C.addTempFile(C.getArgs().MakeArgString(UniqueName));
9777  }
9778  }
9779 
9780  // Emit an error if PCH(Pre-Compiled Header) file generation is forced in
9781  // -fsycl mode.
9782  if (C.getArgs().hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
9783  JA.getType() == types::TY_PCH)
9784  Diag(clang::diag::err_drv_fsycl_with_pch);
9785  // As an annoying special case, PCH generation doesn't strip the pathname.
9786  if (JA.getType() == types::TY_PCH && !IsCLMode()) {
9787  llvm::sys::path::remove_filename(BasePath);
9788  if (BasePath.empty())
9789  BasePath = NamedOutput;
9790  else
9791  llvm::sys::path::append(BasePath, NamedOutput);
9792  return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str()), &JA);
9793  }
9794 
9795  return C.addResultFile(NamedOutput, &JA);
9796 }
9797 
9798 std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const {
9799  // Search for Name in a list of paths.
9800  auto SearchPaths = [&](const llvm::SmallVectorImpl<std::string> &P)
9801  -> std::optional<std::string> {
9802  // Respect a limited subset of the '-Bprefix' functionality in GCC by
9803  // attempting to use this prefix when looking for file paths.
9804  for (const auto &Dir : P) {
9805  if (Dir.empty())
9806  continue;
9807  SmallString<128> P(Dir[0] == '=' ? SysRoot + Dir.substr(1) : Dir);
9808  llvm::sys::path::append(P, Name);
9809  if (llvm::sys::fs::exists(Twine(P)))
9810  return std::string(P);
9811  }
9812  return std::nullopt;
9813  };
9814 
9815  if (auto P = SearchPaths(PrefixDirs))
9816  return *P;
9817 
9819  llvm::sys::path::append(R, Name);
9820  if (llvm::sys::fs::exists(Twine(R)))
9821  return std::string(R);
9822 
9824  llvm::sys::path::append(P, Name);
9825  if (llvm::sys::fs::exists(Twine(P)))
9826  return std::string(P);
9827 
9828  SmallString<128> D(Dir);
9829  llvm::sys::path::append(D, "..", Name);
9830  if (llvm::sys::fs::exists(Twine(D)))
9831  return std::string(D);
9832 
9833  if (auto P = SearchPaths(TC.getLibraryPaths()))
9834  return *P;
9835 
9836  if (auto P = SearchPaths(TC.getFilePaths()))
9837  return *P;
9838 
9839  return std::string(Name);
9840 }
9841 
9842 void Driver::generatePrefixedToolNames(
9843  StringRef Tool, const ToolChain &TC,
9844  SmallVectorImpl<std::string> &Names) const {
9845  // FIXME: Needs a better variable than TargetTriple
9846  Names.emplace_back((TargetTriple + "-" + Tool).str());
9847  Names.emplace_back(Tool);
9848 }
9849 
9850 static bool ScanDirForExecutable(SmallString<128> &Dir, StringRef Name) {
9851  llvm::sys::path::append(Dir, Name);
9852  if (llvm::sys::fs::can_execute(Twine(Dir)))
9853  return true;
9854  llvm::sys::path::remove_filename(Dir);
9855  return false;
9856 }
9857 
9858 std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const {
9859  SmallVector<std::string, 2> TargetSpecificExecutables;
9860  generatePrefixedToolNames(Name, TC, TargetSpecificExecutables);
9861 
9862  // Respect a limited subset of the '-Bprefix' functionality in GCC by
9863  // attempting to use this prefix when looking for program paths.
9864  for (const auto &PrefixDir : PrefixDirs) {
9865  if (llvm::sys::fs::is_directory(PrefixDir)) {
9866  SmallString<128> P(PrefixDir);
9867  if (ScanDirForExecutable(P, Name))
9868  return std::string(P);
9869  } else {
9870  SmallString<128> P((PrefixDir + Name).str());
9871  if (llvm::sys::fs::can_execute(Twine(P)))
9872  return std::string(P);
9873  }
9874  }
9875 
9876  const ToolChain::path_list &List = TC.getProgramPaths();
9877  for (const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
9878  // For each possible name of the tool look for it in
9879  // program paths first, then the path.
9880  // Higher priority names will be first, meaning that
9881  // a higher priority name in the path will be found
9882  // instead of a lower priority name in the program path.
9883  // E.g. <triple>-gcc on the path will be found instead
9884  // of gcc in the program path
9885  for (const auto &Path : List) {
9886  SmallString<128> P(Path);
9887  if (ScanDirForExecutable(P, TargetSpecificExecutable))
9888  return std::string(P);
9889  }
9890 
9891  // Fall back to the path
9892  if (llvm::ErrorOr<std::string> P =
9893  llvm::sys::findProgramByName(TargetSpecificExecutable))
9894  return *P;
9895  }
9896 
9897  return std::string(Name);
9898 }
9899 
9901  const ToolChain &TC) const {
9902  std::string error = "<NOT PRESENT>";
9903 
9904  switch (TC.GetCXXStdlibType(C.getArgs())) {
9905  case ToolChain::CST_Libcxx: {
9906  auto evaluate = [&](const char *library) -> std::optional<std::string> {
9907  std::string lib = GetFilePath(library, TC);
9908 
9909  // Note when there are multiple flavours of libc++ the module json needs
9910  // to look at the command-line arguments for the proper json. These
9911  // flavours do not exist at the moment, but there are plans to provide a
9912  // variant that is built with sanitizer instrumentation enabled.
9913 
9914  // For example
9915  // StringRef modules = [&] {
9916  // const SanitizerArgs &Sanitize = TC.getSanitizerArgs(C.getArgs());
9917  // if (Sanitize.needsAsanRt())
9918  // return "libc++.modules-asan.json";
9919  // return "libc++.modules.json";
9920  // }();
9921 
9922  SmallString<128> path(lib.begin(), lib.end());
9923  llvm::sys::path::remove_filename(path);
9924  llvm::sys::path::append(path, "libc++.modules.json");
9925  if (TC.getVFS().exists(path))
9926  return static_cast<std::string>(path);
9927 
9928  return {};
9929  };
9930 
9931  if (std::optional<std::string> result = evaluate("libc++.so"); result)
9932  return *result;
9933 
9934  return evaluate("libc++.a").value_or(error);
9935  }
9936 
9938  // libstdc++ does not provide Standard library modules yet.
9939  return error;
9940  }
9941 
9942  return error;
9943 }
9944 
9945 std::string Driver::GetTemporaryPath(StringRef Prefix, StringRef Suffix) const {
9946  SmallString<128> Path;
9947  std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
9948  if (EC) {
9949  Diag(clang::diag::err_unable_to_make_temp) << EC.message();
9950  return "";
9951  }
9952 
9953  return std::string(Path);
9954 }
9955 
9956 std::string Driver::GetUniquePath(StringRef BaseName, StringRef Ext) const {
9957  SmallString<128> Path;
9958  std::error_code EC = llvm::sys::fs::getPotentiallyUniqueFileName(
9959  Twine(BaseName) + Twine("-%%%%%%.") + Ext, Path);
9960  if (EC) {
9961  Diag(clang::diag::err_unable_to_make_temp) << EC.message();
9962  return "";
9963  }
9964 
9965  return std::string(Path.str());
9966 }
9967 
9968 std::string Driver::GetTemporaryDirectory(StringRef Prefix) const {
9969  SmallString<128> Path;
9970  std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
9971  if (EC) {
9972  Diag(clang::diag::err_unable_to_make_temp) << EC.message();
9973  return "";
9974  }
9975 
9976  return std::string(Path);
9977 }
9978 
9979 std::string Driver::GetClPchPath(Compilation &C, StringRef BaseName) const {
9980  SmallString<128> Output;
9981  if (Arg *FpArg = C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
9982  // FIXME: If anybody needs it, implement this obscure rule:
9983  // "If you specify a directory without a file name, the default file name
9984  // is VCx0.pch., where x is the major version of Visual C++ in use."
9985  Output = FpArg->getValue();
9986 
9987  // "If you do not specify an extension as part of the path name, an
9988  // extension of .pch is assumed. "
9989  if (!llvm::sys::path::has_extension(Output))
9990  Output += ".pch";
9991  } else {
9992  if (Arg *YcArg = C.getArgs().getLastArg(options::OPT__SLASH_Yc))
9993  Output = YcArg->getValue();
9994  if (Output.empty())
9995  Output = BaseName;
9996  llvm::sys::path::replace_extension(Output, ".pch");
9997  }
9998  return std::string(Output);
9999 }
10000 
10001 const ToolChain &Driver::getToolChain(const ArgList &Args,
10002  const llvm::Triple &Target) const {
10003 
10004  auto &TC = ToolChains[Target.str()];
10005  if (!TC) {
10006  switch (Target.getOS()) {
10007  case llvm::Triple::AIX:
10008  TC = std::make_unique<toolchains::AIX>(*this, Target, Args);
10009  break;
10010  case llvm::Triple::Haiku:
10011  TC = std::make_unique<toolchains::Haiku>(*this, Target, Args);
10012  break;
10013  case llvm::Triple::Darwin:
10014  case llvm::Triple::MacOSX:
10015  case llvm::Triple::IOS:
10016  case llvm::Triple::TvOS:
10017  case llvm::Triple::WatchOS:
10018  case llvm::Triple::XROS:
10019  case llvm::Triple::DriverKit:
10020  TC = std::make_unique<toolchains::DarwinClang>(*this, Target, Args);
10021  break;
10022  case llvm::Triple::DragonFly:
10023  TC = std::make_unique<toolchains::DragonFly>(*this, Target, Args);
10024  break;
10025  case llvm::Triple::OpenBSD:
10026  TC = std::make_unique<toolchains::OpenBSD>(*this, Target, Args);
10027  break;
10028  case llvm::Triple::NetBSD:
10029  TC = std::make_unique<toolchains::NetBSD>(*this, Target, Args);
10030  break;
10031  case llvm::Triple::FreeBSD:
10032  if (Target.isPPC())
10033  TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*this, Target,
10034  Args);
10035  else
10036  TC = std::make_unique<toolchains::FreeBSD>(*this, Target, Args);
10037  break;
10038  case llvm::Triple::Linux:
10039  case llvm::Triple::ELFIAMCU:
10040  if (Target.getArch() == llvm::Triple::hexagon)
10041  TC = std::make_unique<toolchains::HexagonToolChain>(*this, Target,
10042  Args);
10043  else if ((Target.getVendor() == llvm::Triple::MipsTechnologies) &&
10044  !Target.hasEnvironment())
10045  TC = std::make_unique<toolchains::MipsLLVMToolChain>(*this, Target,
10046  Args);
10047  else if (Target.isPPC())
10048  TC = std::make_unique<toolchains::PPCLinuxToolChain>(*this, Target,
10049  Args);
10050  else if (Target.getArch() == llvm::Triple::ve)
10051  TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args);
10052  else if (Target.isOHOSFamily())
10053  TC = std::make_unique<toolchains::OHOS>(*this, Target, Args);
10054  else
10055  TC = std::make_unique<toolchains::Linux>(*this, Target, Args);
10056  break;
10057  case llvm::Triple::NaCl:
10058  TC = std::make_unique<toolchains::NaClToolChain>(*this, Target, Args);
10059  break;
10060  case llvm::Triple::Fuchsia:
10061  TC = std::make_unique<toolchains::Fuchsia>(*this, Target, Args);
10062  break;
10063  case llvm::Triple::Solaris:
10064  TC = std::make_unique<toolchains::Solaris>(*this, Target, Args);
10065  break;
10066  case llvm::Triple::CUDA:
10067  TC = std::make_unique<toolchains::NVPTXToolChain>(*this, Target, Args);
10068  break;
10069  case llvm::Triple::AMDHSA:
10070  TC = std::make_unique<toolchains::ROCMToolChain>(*this, Target, Args);
10071  break;
10072  case llvm::Triple::AMDPAL:
10073  case llvm::Triple::Mesa3D:
10074  TC = std::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args);
10075  break;
10076  case llvm::Triple::Win32:
10077  switch (Target.getEnvironment()) {
10078  default:
10079  if (Target.isOSBinFormatELF())
10080  TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
10081  else if (Target.isOSBinFormatMachO())
10082  TC = std::make_unique<toolchains::MachO>(*this, Target, Args);
10083  else
10084  TC = std::make_unique<toolchains::Generic_GCC>(*this, Target, Args);
10085  break;
10086  case llvm::Triple::GNU:
10087  TC = std::make_unique<toolchains::MinGW>(*this, Target, Args);
10088  break;
10089  case llvm::Triple::Itanium:
10090  TC = std::make_unique<toolchains::CrossWindowsToolChain>(*this, Target,
10091  Args);
10092  break;
10093  case llvm::Triple::MSVC:
10094  case llvm::Triple::UnknownEnvironment:
10095  if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
10096  .starts_with_insensitive("bfd"))
10097  TC = std::make_unique<toolchains::CrossWindowsToolChain>(
10098  *this, Target, Args);
10099  else
10100  TC =
10101  std::make_unique<toolchains::MSVCToolChain>(*this, Target, Args);
10102  break;
10103  }
10104  break;
10105  case llvm::Triple::PS4:
10106  TC = std::make_unique<toolchains::PS4CPU>(*this, Target, Args);
10107  break;
10108  case llvm::Triple::PS5:
10109  TC = std::make_unique<toolchains::PS5CPU>(*this, Target, Args);
10110  break;
10111  case llvm::Triple::Hurd:
10112  TC = std::make_unique<toolchains::Hurd>(*this, Target, Args);
10113  break;
10114  case llvm::Triple::LiteOS:
10115  TC = std::make_unique<toolchains::OHOS>(*this, Target, Args);
10116  break;
10117  case llvm::Triple::ZOS:
10118  TC = std::make_unique<toolchains::ZOS>(*this, Target, Args);
10119  break;
10120  case llvm::Triple::ShaderModel:
10121  TC = std::make_unique<toolchains::HLSLToolChain>(*this, Target, Args);
10122  break;
10123  default:
10124  // Of these targets, Hexagon is the only one that might have
10125  // an OS of Linux, in which case it got handled above already.
10126  switch (Target.getArch()) {
10127  case llvm::Triple::tce:
10128  TC = std::make_unique<toolchains::TCEToolChain>(*this, Target, Args);
10129  break;
10130  case llvm::Triple::tcele:
10131  TC = std::make_unique<toolchains::TCELEToolChain>(*this, Target, Args);
10132  break;
10133  case llvm::Triple::hexagon:
10134  TC = std::make_unique<toolchains::HexagonToolChain>(*this, Target,
10135  Args);
10136  break;
10137  case llvm::Triple::lanai:
10138  TC = std::make_unique<toolchains::LanaiToolChain>(*this, Target, Args);
10139  break;
10140  case llvm::Triple::xcore:
10141  TC = std::make_unique<toolchains::XCoreToolChain>(*this, Target, Args);
10142  break;
10143  case llvm::Triple::wasm32:
10144  case llvm::Triple::wasm64:
10145  TC = std::make_unique<toolchains::WebAssembly>(*this, Target, Args);
10146  break;
10147  case llvm::Triple::avr:
10148  TC = std::make_unique<toolchains::AVRToolChain>(*this, Target, Args);
10149  break;
10150  case llvm::Triple::msp430:
10151  TC =
10152  std::make_unique<toolchains::MSP430ToolChain>(*this, Target, Args);
10153  break;
10154  case llvm::Triple::riscv32:
10155  case llvm::Triple::riscv64:
10157  TC =
10158  std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args);
10159  else
10160  TC = std::make_unique<toolchains::BareMetal>(*this, Target, Args);
10161  break;
10162  case llvm::Triple::ve:
10163  TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args);
10164  break;
10165  case llvm::Triple::spirv32:
10166  case llvm::Triple::spirv64:
10167  TC = std::make_unique<toolchains::SPIRVToolChain>(*this, Target, Args);
10168  break;
10169  case llvm::Triple::csky:
10170  TC = std::make_unique<toolchains::CSKYToolChain>(*this, Target, Args);
10171  break;
10172  default:
10174  TC = std::make_unique<toolchains::BareMetal>(*this, Target, Args);
10175  else if (Target.isOSBinFormatELF())
10176  TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
10177  else if (Target.isOSBinFormatMachO())
10178  TC = std::make_unique<toolchains::MachO>(*this, Target, Args);
10179  else
10180  TC = std::make_unique<toolchains::Generic_GCC>(*this, Target, Args);
10181  }
10182  }
10183  }
10184 
10185  return *TC;
10186 }
10187 
10188 const ToolChain &Driver::getOffloadingDeviceToolChain(
10189  const ArgList &Args, const llvm::Triple &Target, const ToolChain &HostTC,
10190  const Action::OffloadKind &TargetDeviceOffloadKind) const {
10191  // Use device / host triples offload kind as the key into the ToolChains map
10192  // because the device ToolChain we create depends on both.
10193  auto &TC = ToolChains[Target.str() + "/" + HostTC.getTriple().str() +
10194  std::to_string(TargetDeviceOffloadKind)];
10195  if (!TC) {
10196  // Categorized by offload kind > arch rather than OS > arch like
10197  // the normal getToolChain call, as it seems a reasonable way to categorize
10198  // things.
10199  switch (TargetDeviceOffloadKind) {
10200  case Action::OFK_Cuda:
10201  TC = std::make_unique<toolchains::CudaToolChain>(
10202  *this, Target, HostTC, Args, TargetDeviceOffloadKind);
10203  break;
10204  case Action::OFK_HIP: {
10205  if (Target.getArch() == llvm::Triple::amdgcn &&
10206  Target.getVendor() == llvm::Triple::AMD &&
10207  Target.getOS() == llvm::Triple::AMDHSA)
10208  TC = std::make_unique<toolchains::HIPAMDToolChain>(
10209  *this, Target, HostTC, Args, TargetDeviceOffloadKind);
10210  else if (Target.getArch() == llvm::Triple::spirv64 &&
10211  Target.getVendor() == llvm::Triple::UnknownVendor &&
10212  Target.getOS() == llvm::Triple::UnknownOS)
10213  TC = std::make_unique<toolchains::HIPSPVToolChain>(*this, Target,
10214  HostTC, Args);
10215  break;
10216  }
10217  case Action::OFK_OpenMP:
10218  // omp + nvptx
10219  TC = std::make_unique<toolchains::CudaToolChain>(
10220  *this, Target, HostTC, Args, TargetDeviceOffloadKind);
10221  break;
10222  case Action::OFK_SYCL:
10223  switch (Target.getArch()) {
10224  case llvm::Triple::spir:
10225  case llvm::Triple::spir64:
10226  case llvm::Triple::spirv32:
10227  case llvm::Triple::spirv64:
10228  TC = std::make_unique<toolchains::SYCLToolChain>(*this, Target, HostTC,
10229  Args);
10230  break;
10231  case llvm::Triple::nvptx:
10232  case llvm::Triple::nvptx64:
10233  TC = std::make_unique<toolchains::CudaToolChain>(
10234  *this, Target, HostTC, Args, TargetDeviceOffloadKind);
10235  break;
10236  case llvm::Triple::amdgcn:
10237  TC = std::make_unique<toolchains::HIPAMDToolChain>(
10238  *this, Target, HostTC, Args, TargetDeviceOffloadKind);
10239  break;
10240  default:
10241  if (isSYCLNativeCPU(Args)) {
10242  TC = std::make_unique<toolchains::SYCLToolChain>(*this, Target,
10243  HostTC, Args);
10244  }
10245  break;
10246  }
10247  break;
10248  default:
10249  break;
10250  }
10251  }
10252 
10253  return *TC;
10254 }
10255 
10257  // Say "no" if there is not exactly one input of a type clang understands.
10258  if (JA.size() != 1 ||
10259  !types::isAcceptedByClang((*JA.input_begin())->getType()))
10260  return false;
10261 
10262  // And say "no" if this is not a kind of action clang understands.
10263  if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
10264  !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
10265  !isa<ExtractAPIJobAction>(JA))
10266  return false;
10267 
10268  return true;
10269 }
10270 
10272  // Say "no" if there is not exactly one input of a type flang understands.
10273  if (JA.size() != 1 ||
10274  !types::isAcceptedByFlang((*JA.input_begin())->getType()))
10275  return false;
10276 
10277  // And say "no" if this is not a kind of action flang understands.
10278  if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) &&
10279  !isa<BackendJobAction>(JA))
10280  return false;
10281 
10282  return true;
10283 }
10284 
10285 bool Driver::ShouldEmitStaticLibrary(const ArgList &Args) const {
10286  // Only emit static library if the flag is set explicitly.
10287  if (Args.hasArg(options::OPT_emit_static_lib))
10288  return true;
10289  return false;
10290 }
10291 
10292 /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the
10293 /// grouped values as integers. Numbers which are not provided are set to 0.
10294 ///
10295 /// \return True if the entire string was parsed (9.2), or all groups were
10296 /// parsed (10.3.5extrastuff).
10297 bool Driver::GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor,
10298  unsigned &Micro, bool &HadExtra) {
10299  HadExtra = false;
10300 
10301  Major = Minor = Micro = 0;
10302  if (Str.empty())
10303  return false;
10304 
10305  if (Str.consumeInteger(10, Major))
10306  return false;
10307  if (Str.empty())
10308  return true;
10309  if (!Str.consume_front("."))
10310  return false;
10311 
10312  if (Str.consumeInteger(10, Minor))
10313  return false;
10314  if (Str.empty())
10315  return true;
10316  if (!Str.consume_front("."))
10317  return false;
10318 
10319  if (Str.consumeInteger(10, Micro))
10320  return false;
10321  if (!Str.empty())
10322  HadExtra = true;
10323  return true;
10324 }
10325 
10326 /// Parse digits from a string \p Str and fulfill \p Digits with
10327 /// the parsed numbers. This method assumes that the max number of
10328 /// digits to look for is equal to Digits.size().
10329 ///
10330 /// \return True if the entire string was parsed and there are
10331 /// no extra characters remaining at the end.
10332 bool Driver::GetReleaseVersion(StringRef Str,
10333  MutableArrayRef<unsigned> Digits) {
10334  if (Str.empty())
10335  return false;
10336 
10337  unsigned CurDigit = 0;
10338  while (CurDigit < Digits.size()) {
10339  unsigned Digit;
10340  if (Str.consumeInteger(10, Digit))
10341  return false;
10342  Digits[CurDigit] = Digit;
10343  if (Str.empty())
10344  return true;
10345  if (!Str.consume_front("."))
10346  return false;
10347  CurDigit++;
10348  }
10349 
10350  // More digits than requested, bail out...
10351  return false;
10352 }
10353 
10355 Driver::getOptionVisibilityMask(bool UseDriverMode) const {
10356  if (!UseDriverMode)
10358  if (IsCLMode())
10360  if (IsDXCMode())
10362  if (IsFlangMode()) {
10364  }
10366 }
10367 
10368 const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
10369  switch (Mode) {
10370  case GCCMode:
10371  return "clang";
10372  case GXXMode:
10373  return "clang++";
10374  case CPPMode:
10375  return "clang-cpp";
10376  case CLMode:
10377  return "clang-cl";
10378  case FlangMode:
10379  return "flang";
10380  case DXCMode:
10381  return "clang-dxc";
10382  }
10383 
10384  llvm_unreachable("Unhandled Mode");
10385 }
10386 
10387 bool clang::driver::isOptimizationLevelFast(const ArgList &Args) {
10388  return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group, false);
10389 }
10390 
10391 bool clang::driver::isObjectFile(std::string FileName) {
10392  if (llvm::sys::fs::is_directory(FileName))
10393  return false;
10394  if (!llvm::sys::path::has_extension(FileName))
10395  // Any file with no extension should be considered an Object. Take into
10396  // account -lsomelib library filenames.
10397  return FileName.rfind("-l", 0) != 0;
10398  std::string Ext(llvm::sys::path::extension(FileName).drop_front());
10399  // We cannot rely on lookupTypeForExtension solely as that has 'lib'
10400  // marked as an object.
10401  return (Ext != "lib" &&
10402  types::lookupTypeForExtension(Ext) == types::TY_Object);
10403 }
10404 
10405 bool clang::driver::isStaticArchiveFile(const StringRef &FileName) {
10406  if (!llvm::sys::path::has_extension(FileName))
10407  // Any file with no extension should not be considered an Archive.
10408  return false;
10409  llvm::file_magic Magic;
10410  llvm::identify_magic(FileName, Magic);
10411  // Only .lib and archive files are to be considered.
10412  return (Magic == llvm::file_magic::archive);
10413 }
10414 
10415 bool clang::driver::willEmitRemarks(const ArgList &Args) {
10416  // -fsave-optimization-record enables it.
10417  if (Args.hasFlag(options::OPT_fsave_optimization_record,
10418  options::OPT_fno_save_optimization_record, false))
10419  return true;
10420 
10421  // -fsave-optimization-record=<format> enables it as well.
10422  if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
10423  options::OPT_fno_save_optimization_record, false))
10424  return true;
10425 
10426  // -foptimization-record-file alone enables it too.
10427  if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
10428  options::OPT_fno_save_optimization_record, false))
10429  return true;
10430 
10431  // -foptimization-record-passes alone enables it too.
10432  if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
10433  options::OPT_fno_save_optimization_record, false))
10434  return true;
10435  return false;
10436 }
10437 
10438 llvm::StringRef clang::driver::getDriverMode(StringRef ProgName,
10439  ArrayRef<const char *> Args) {
10440  static StringRef OptName =
10441  getDriverOptTable().getOption(options::OPT_driver_mode).getPrefixedName();
10442  llvm::StringRef Opt;
10443  for (StringRef Arg : Args) {
10444  if (!Arg.starts_with(OptName))
10445  continue;
10446  Opt = Arg;
10447  }
10448  if (Opt.empty())
10450  return Opt.consume_front(OptName) ? Opt : "";
10451 }
10452 
10453 bool driver::IsClangCL(StringRef DriverMode) { return DriverMode == "cl"; }
10454 
10456  bool ClangCLMode,
10457  llvm::BumpPtrAllocator &Alloc,
10458  llvm::vfs::FileSystem *FS) {
10459  // Parse response files using the GNU syntax, unless we're in CL mode. There
10460  // are two ways to put clang in CL compatibility mode: ProgName is either
10461  // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
10462  // command line parsing can't happen until after response file parsing, so we
10463  // have to manually search for a --driver-mode=cl argument the hard way.
10464  // Finally, our -cc1 tools don't care which tokenization mode we use because
10465  // response files written by clang will tokenize the same way in either mode.
10466  enum { Default, POSIX, Windows } RSPQuoting = Default;
10467  for (const char *F : Args) {
10468  if (strcmp(F, "--rsp-quoting=posix") == 0)
10469  RSPQuoting = POSIX;
10470  else if (strcmp(F, "--rsp-quoting=windows") == 0)
10471  RSPQuoting = Windows;
10472  }
10473 
10474  // Determines whether we want nullptr markers in Args to indicate response
10475  // files end-of-lines. We only use this for the /LINK driver argument with
10476  // clang-cl.exe on Windows.
10477  bool MarkEOLs = ClangCLMode;
10478 
10479  llvm::cl::TokenizerCallback Tokenizer;
10480  if (RSPQuoting == Windows || (RSPQuoting == Default && ClangCLMode))
10481  Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
10482  else
10483  Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
10484 
10485  if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with("-cc1"))
10486  MarkEOLs = false;
10487 
10488  llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
10489  ECtx.setMarkEOLs(MarkEOLs);
10490  if (FS)
10491  ECtx.setVFS(FS);
10492 
10493  if (llvm::Error Err = ECtx.expandResponseFiles(Args))
10494  return Err;
10495 
10496  // If -cc1 came from a response file, remove the EOL sentinels.
10497  auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
10498  [](const char *A) { return A != nullptr; });
10499  if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with("-cc1")) {
10500  // If -cc1 came from a response file, remove the EOL sentinels.
10501  if (MarkEOLs) {
10502  auto newEnd = std::remove(Args.begin(), Args.end(), nullptr);
10503  Args.resize(newEnd - Args.begin());
10504  }
10505  }
10506 
10507  return llvm::Error::success();
10508 }
10509 
10510 static const char *GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S) {
10511  return SavedStrings.insert(S).first->getKeyData();
10512 }
10513 
10514 /// Apply a list of edits to the input argument lists.
10515 ///
10516 /// The input string is a space separated list of edits to perform,
10517 /// they are applied in order to the input argument lists. Edits
10518 /// should be one of the following forms:
10519 ///
10520 /// '#': Silence information about the changes to the command line arguments.
10521 ///
10522 /// '^': Add FOO as a new argument at the beginning of the command line.
10523 ///
10524 /// '+': Add FOO as a new argument at the end of the command line.
10525 ///
10526 /// 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command
10527 /// line.
10528 ///
10529 /// 'xOPTION': Removes all instances of the literal argument OPTION.
10530 ///
10531 /// 'XOPTION': Removes all instances of the literal argument OPTION,
10532 /// and the following argument.
10533 ///
10534 /// 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
10535 /// at the end of the command line.
10536 ///
10537 /// \param OS - The stream to write edit information to.
10538 /// \param Args - The vector of command line arguments.
10539 /// \param Edit - The override command to perform.
10540 /// \param SavedStrings - Set to use for storing string representations.
10541 static void applyOneOverrideOption(raw_ostream &OS,
10543  StringRef Edit,
10544  llvm::StringSet<> &SavedStrings) {
10545  // This does not need to be efficient.
10546 
10547  if (Edit[0] == '^') {
10548  const char *Str = GetStableCStr(SavedStrings, Edit.substr(1));
10549  OS << "### Adding argument " << Str << " at beginning\n";
10550  Args.insert(Args.begin() + 1, Str);
10551  } else if (Edit[0] == '+') {
10552  const char *Str = GetStableCStr(SavedStrings, Edit.substr(1));
10553  OS << "### Adding argument " << Str << " at end\n";
10554  Args.push_back(Str);
10555  } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.ends_with("/") &&
10556  Edit.slice(2, Edit.size() - 1).contains('/')) {
10557  StringRef MatchPattern = Edit.substr(2).split('/').first;
10558  StringRef ReplPattern = Edit.substr(2).split('/').second;
10559  ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
10560 
10561  for (unsigned i = 1, e = Args.size(); i != e; ++i) {
10562  // Ignore end-of-line response file markers
10563  if (Args[i] == nullptr)
10564  continue;
10565  std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
10566 
10567  if (Repl != Args[i]) {
10568  OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n";
10569  Args[i] = GetStableCStr(SavedStrings, Repl);
10570  }
10571  }
10572  } else if (Edit[0] == 'x' || Edit[0] == 'X') {
10573  auto Option = Edit.substr(1);
10574  for (unsigned i = 1; i < Args.size();) {
10575  if (Option == Args[i]) {
10576  OS << "### Deleting argument " << Args[i] << '\n';
10577  Args.erase(Args.begin() + i);
10578  if (Edit[0] == 'X') {
10579  if (i < Args.size()) {
10580  OS << "### Deleting argument " << Args[i] << '\n';
10581  Args.erase(Args.begin() + i);
10582  } else
10583  OS << "### Invalid X edit, end of command line!\n";
10584  }
10585  } else
10586  ++i;
10587  }
10588  } else if (Edit[0] == 'O') {
10589  for (unsigned i = 1; i < Args.size();) {
10590  const char *A = Args[i];
10591  // Ignore end-of-line response file markers
10592  if (A == nullptr)
10593  continue;
10594  if (A[0] == '-' && A[1] == 'O' &&
10595  (A[2] == '\0' || (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' ||
10596  ('0' <= A[2] && A[2] <= '9'))))) {
10597  OS << "### Deleting argument " << Args[i] << '\n';
10598  Args.erase(Args.begin() + i);
10599  } else
10600  ++i;
10601  }
10602  OS << "### Adding argument " << Edit << " at end\n";
10603  Args.push_back(GetStableCStr(SavedStrings, '-' + Edit.str()));
10604  } else {
10605  OS << "### Unrecognized edit: " << Edit << "\n";
10606  }
10607 }
10608 
10610  const char *OverrideStr,
10611  llvm::StringSet<> &SavedStrings,
10612  raw_ostream *OS) {
10613  if (!OS)
10614  OS = &llvm::nulls();
10615 
10616  if (OverrideStr[0] == '#') {
10617  ++OverrideStr;
10618  OS = &llvm::nulls();
10619  }
10620 
10621  *OS << "### CCC_OVERRIDE_OPTIONS: " << OverrideStr << "\n";
10622 
10623  // This does not need to be efficient.
10624 
10625  const char *S = OverrideStr;
10626  while (*S) {
10627  const char *End = ::strchr(S, ' ');
10628  if (!End)
10629  End = S + strlen(S);
10630  if (End != S)
10631  applyOneOverrideOption(*OS, Args, std::string(S, End), SavedStrings);
10632  S = End;
10633  if (*S != '\0')
10634  ++S;
10635  }
10636 }
clang::driver::toolchains::AIX AIX
Definition: AIX.cpp:22
#define V(N, I)
Definition: ASTContext.h:3299
int Id
Definition: ASTDiff.cpp:190
StringRef P
static char ID
Definition: Arena.cpp:183
static void CollectForEachInputs(InputInfoList &InputInfos, const Action *SourceAction, const ToolChain *TC, StringRef BoundArch, Action::OffloadKind TargetDeviceOffloadKind, const std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, const ForEachWrappingAction *FEA)
Definition: Driver.cpp:8781
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
Definition: Driver.cpp:7749
static bool addSYCLDefaultTriple(Compilation &C, SmallVectorImpl< llvm::Triple > &SYCLTriples)
Definition: Driver.cpp:844
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
Definition: Driver.cpp:10541
static bool hasOffloadSections(Compilation &C, const StringRef &File, DerivedArgList &Args)
Definition: Driver.cpp:3491
static bool HasPreprocessOutput(const Action &JA)
Definition: Driver.cpp:9388
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple, bool SuppressError=false)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
Definition: Driver.cpp:7705
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
Definition: Driver.cpp:1951
static Arg * MakeInputArg(DerivedArgList &Args, const OptTable &Opts, StringRef Value, bool Claim=true)
Definition: Driver.cpp:426
static SmallVector< std::string, 4 > getOffloadSections(Compilation &C, const StringRef &File)
Definition: Driver.cpp:3405
static bool hasFPGABinary(Compilation &C, std::string Object, types::ID Type)
Definition: Driver.cpp:3377
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef DarwinArchName="")
Compute target triple from args.
Definition: Driver.cpp:566
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
Definition: Driver.cpp:8823
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
Definition: Driver.cpp:9359
static bool ContainsOffloadDepsAction(const Action *A)
Check whether the given input tree contains any clang-offload-dependency actions.
Definition: Driver.cpp:3727
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
Definition: Driver.cpp:2824
static bool hasSYCLDefaultSection(Compilation &C, const StringRef &File)
Definition: Driver.cpp:3471
static SmallVector< const char *, 16 > getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj=false)
Definition: Driver.cpp:3508
static std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
Definition: Driver.cpp:8768
static bool runBundler(const SmallVectorImpl< StringRef > &InputArgs, Compilation &C)
Definition: Driver.cpp:3350
static const char * getDefaultSYCLArch(Compilation &C)
Definition: Driver.cpp:838
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
Definition: Driver.cpp:2513
static bool optionMatches(const std::string &Option, const std::string &OptCheck)
Definition: Driver.cpp:3499
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
Definition: Driver.cpp:2919
static bool IsSYCLDeviceLibObj(std::string ObjFilePath, bool isMSVCEnv)
Definition: Driver.cpp:3658
static bool isValidSYCLTriple(llvm::Triple T)
Definition: Driver.cpp:816
static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args, OptSpecifier OptEq, OptSpecifier OptNeg)
Definition: Driver.cpp:749
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
Definition: Driver.cpp:9450
static void appendOneArg(InputArgList &Args, const Arg *Opt, const Arg *BaseArg)
Definition: Driver.cpp:1342
static const char BugReporMsg[]
Definition: Driver.cpp:2059
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
Definition: Driver.cpp:9850
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
Definition: Driver.cpp:10510
static std::optional< llvm::Triple > getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args)
Definition: Driver.cpp:155
@ OtherSibAction
Definition: Driver.cpp:2818
@ TopLevelAction
Definition: Driver.cpp:2816
@ HeadSibAction
Definition: Driver.cpp:2817
static std::optional< llvm::Triple > getOffloadTargetTriple(const Driver &D, const ArgList &Args)
Definition: Driver.cpp:117
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
Definition: Driver.cpp:3091
static std::optional< llvm::Triple > getNVIDIAOffloadTargetTriple(const Driver &D, const ArgList &Args, const llvm::Triple &HostTriple)
Definition: Driver.cpp:137
bool IsStatic
Definition: Format.cpp:2988
StringRef Filename
Definition: Format.cpp:2976
CompileCommand Cmd
LangStandard::Kind Std
#define X(type, name)
Definition: Value.h:143
llvm::MachO::FileType FileType
Definition: MachO.h:45
llvm::MachO::Target Target
Definition: MachO.h:50
SourceLocation Loc
Definition: SemaObjC.cpp:755
const char * Data
SourceLocation End
StateNode * Previous
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
__SIZE_TYPE__ size_t
The result of parsing/analyzing an expression, statement etc.
Definition: Ownership.h:153
RAII class that determines when any errors have occurred between the time the instance was created an...
Definition: Diagnostic.h:1083
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Definition: Diagnostic.h:1094
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:193
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1553
bool hasErrorOccurred() const
Definition: Diagnostic.h:849
Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const
Based on the way the client configured the DiagnosticsEngine object, classify the specified diagnosti...
Definition: Diagnostic.h:937
ExtractAPIAction sets up the output file and creates the ExtractAPIVisitor.
Encodes a location in the source.
Exposes information about the current target.
Definition: TargetInfo.h:218
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:1256
The base class of the type hierarchy.
Definition: Type.h:1813
Action - Represent an abstract compilation step to perform.
Definition: Action.h:49
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
Definition: Action.h:209
size_type size() const
Definition: Action.h:165
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
Definition: Action.h:182
types::ID getType() const
Definition: Action.h:160
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
Definition: Action.h:177
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
Definition: Action.cpp:122
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
Definition: Action.cpp:76
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
Definition: Action.cpp:165
ActionClass getKind() const
Definition: Action.h:159
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
Definition: Action.cpp:181
OffloadKind getOffloadingDeviceKind() const
Definition: Action.h:222
input_iterator input_begin()
Definition: Action.h:167
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
Definition: Action.cpp:99
const ToolChain * getOffloadingToolChain() const
Definition: Action.h:224
input_range inputs()
Definition: Action.h:169
const char * getClassName() const
Definition: Action.h:157
ActionList & getInputs()
Definition: Action.h:162
const char * getOffloadingArch() const
Definition: Action.h:223
unsigned getOffloadingHostActiveKinds() const
Definition: Action.h:218
bool isOffloading(OffloadKind OKind) const
Definition: Action.h:236
Command - An executable path/name and argument vector to execute.
Definition: Job.h:107
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
Definition: Job.h:232
StringRef getDiagForErrorCode(int ErrorCode) const
Get the custom driver diagnostic message for a particular error code if such was stored.
Definition: Job.cpp:175
virtual int Execute(ArrayRef< std::optional< StringRef >> Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Definition: Job.cpp:348
const llvm::opt::ArgStringList & getArguments() const
Definition: Job.h:265
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
Definition: Job.h:229
void replaceArguments(llvm::opt::ArgStringList List)
Definition: Job.h:257
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
A class to find a viable CUDA installation.
Definition: Cuda.h:28
std::string getLibDeviceFile(StringRef Gpu) const
Get libdevice file for given architecture.
Definition: Cuda.h:75
bool isValid() const
Check whether we detected a valid Cuda install.
Definition: Cuda.h:57
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:77
llvm::Triple MakeSYCLDeviceTriple(StringRef TargetArch="spir64") const
MakeSYCLDeviceTriple - Returns the SYCL device triple for the specified subarch.
Definition: Driver.cpp:2408
std::string SysRoot
sysroot, if present
Definition: Driver.h:182
SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
Definition: Driver.h:212
std::string UserConfigDir
User directory for config files.
Definition: Driver.h:172
void addSYCLDeviceTraitsMacroArg(const llvm::opt::ArgList &Args, StringRef Macro) const
SYCLDeviceTraitMacroArg - Add the given macro to the vector of args to be added to the device compila...
Definition: Driver.h:977
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
Definition: Driver.cpp:8051
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
Definition: Driver.cpp:2927
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, types::ID Type=types::TY_Nothing, bool NeedUniqueDirectory=false) const
Creates a temp file.
Definition: Driver.cpp:9399
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, Action *HostAction) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
Definition: Driver.cpp:7864
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
Definition: Driver.cpp:2399
bool offloadDeviceOnly() const
Definition: Driver.h:439
bool isSaveTempsEnabled() const
Definition: Driver.h:431
llvm::DenseSet< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain *TC, bool SuppressError=false) const
Returns the set of bound architectures active for this offload kind.
Definition: Driver.cpp:7760
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
Definition: Driver.cpp:8246
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
Definition: Driver.cpp:8804
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
Definition: Driver.cpp:9798
void PrintSYCLToolHelp(const Compilation &C) const
PrintSYCLToolHelp - Print help text from offline compiler tools.
Definition: Driver.cpp:2425
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
Definition: Driver.h:271
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
Definition: Driver.cpp:2911
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
Definition: Driver.cpp:9462
llvm::vfs::FileSystem & getVFS() const
Definition: Driver.h:405
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
Definition: Driver.cpp:791
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
Definition: Driver.cpp:9968
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
Definition: Driver.h:231
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
Definition: Driver.cpp:9350
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
Definition: Driver.h:224
std::string DyldPrefix
Dynamic loader prefix, if present.
Definition: Driver.h:185
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
Definition: Driver.cpp:10285
std::string DriverTitle
Driver title to use with help.
Definition: Driver.h:188
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
Definition: Driver.h:235
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
Definition: Driver.cpp:3106
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
Definition: Driver.h:266
void addIntegrationFiles(StringRef IntHeaderName, StringRef IntFooterName, StringRef FileName) const
addIntegrationFiles - Add the integration files that will be populated by the device compilation and ...
Definition: Driver.h:937
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
Definition: Driver.cpp:2313
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:146
std::string SystemConfigDir
System directory for config files.
Definition: Driver.h:169
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
Definition: Driver.h:163
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
Definition: Driver.cpp:10297
std::string Name
The name the driver was invoked as.
Definition: Driver.h:153
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
Definition: Driver.cpp:370
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
Definition: Driver.cpp:9979
std::string ClangExecutable
The original path to the clang executable.
Definition: Driver.h:160
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
Definition: Driver.cpp:7275
bool offloadHostOnly() const
Definition: Driver.h:438
void addSYCLUniqueID(StringRef UniqueID, StringRef FileName) const
setSYCLUniqueID - set the Unique ID that is used for all FE invocations when performing compilations ...
Definition: Driver.h:967
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
Definition: Driver.cpp:2067
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
Definition: Driver.h:728
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
Definition: Driver.cpp:2477
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
Definition: Driver.cpp:10271
LTOKind getLTOMode(bool IsOffload=false) const
Get the specific kind of LTO being performed.
Definition: Driver.h:739
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
Definition: Driver.cpp:3015
bool getUseNewOffloadingDriver() const
getUseNewOffloadingDriver - use the new offload driver for OpenMP.
Definition: Driver.h:917
bool HandleImmediateArgs(const Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
Definition: Driver.cpp:2607
std::pair< types::ID, const llvm::opt::Arg * > InputTy
An input type and its arguments.
Definition: Driver.h:209
bool IsFPGAHWMode() const
Definition: Driver.h:750
DiagnosticsEngine & getDiags() const
Definition: Driver.h:403
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError)
ParseArgStrings - Parse the given list of strings into an ArgList.
Definition: Driver.cpp:275
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
Definition: Driver.cpp:866
std::string GetUniquePath(StringRef BaseName, StringRef Ext) const
GetUniquePath = Return the pathname of a unique file to use as part of compilation.
Definition: Driver.cpp:9956
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
Definition: Driver.cpp:9858
bool isSaveTempsObj() const
Definition: Driver.h:432
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
Definition: Driver.cpp:2520
const llvm::opt::OptTable & getOpts() const
Definition: Driver.h:401
std::string ResourceDir
The path to the compiler resource directory.
Definition: Driver.h:166
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
Definition: Driver.cpp:10256
bool isUsingLTO(bool IsOffload=false) const
Returns true if we are performing any kind of LTO.
Definition: Driver.h:734
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
Definition: Driver.cpp:9945
std::string Dir
The path the driver executable was in, as invoked from the command line.
Definition: Driver.h:157
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
Definition: Driver.h:142
@ OMPRT_OMP
The LLVM OpenMP runtime.
Definition: Driver.h:132
@ OMPRT_Unknown
An unknown OpenMP runtime.
Definition: Driver.h:128
@ OMPRT_GOMP
The GNU OpenMP runtime.
Definition: Driver.h:137
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
Definition: Driver.cpp:201
static std::string GetResourcesPath(StringRef BinaryPath, StringRef CustomResourceDir="")
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
Definition: Driver.cpp:173
std::string getTargetTriple() const
Definition: Driver.h:422
bool getCheckInputsExist() const
Definition: Driver.h:407
bool CCCIsCC() const
Whether the driver should follow gcc like behavior.
Definition: Driver.h:221
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
Definition: Driver.cpp:9900
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Definition: Driver.h:228
bool IsFPGAEmulationMode() const
Definition: Driver.h:752
prefix_list PrefixDirs
Definition: Driver.h:179
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
Definition: Driver.cpp:1559
void setOffloadCompileMode(DeviceMode ModeValue)
Definition: Driver.h:756
bool embedBitcodeInObject() const
Definition: Driver.h:435
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
Definition: Driver.h:194
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
Definition: Driver.h:218
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Definition: Driver.h:215
static constexpr const char * COL_SYM_AND_PROPS
Definition: Action.h:840
void addExtractColumnTform(StringRef ColumnName, bool WithColTitle=true)
Definition: Action.cpp:541
static constexpr const char * COL_CODE
Definition: Action.h:838
void addRenameColumnTform(StringRef From, StringRef To)
Definition: Action.cpp:558
static constexpr const char * COL_ZERO
Definition: Action.h:839
void addReplaceColumnTform(StringRef From, StringRef To)
Definition: Action.cpp:547
Wrap all jobs performed between TFormInput (excluded) and Job (included) behind a llvm-foreach call.
Definition: Action.h:964
void addSerialAction(const Action *A)
Definition: Action.h:975
const llvm::SmallSetVector< const Action *, 2 > & getSerialActions() const
Definition: Action.h:976
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
Definition: Multilib.cpp:136
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
Definition: Multilib.h:32
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
Definition: Multilib.h:61
std::vector< std::string > flags_list
Definition: Multilib.h:34
Type used to communicate device actions.
Definition: Action.h:286
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
Definition: Action.cpp:333
const ActionList & getActions() const
Get each of the individual arrays.
Definition: Action.h:322
Type used to communicate host actions.
Definition: Action.h:332
An offload action combines host or/and device actions according to the programming model implementati...
Definition: Action.h:280
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Definition: Action.h:761
ArrayRef< DependentActionInfo > getDependentActionsInfo() const
Return the information about all depending actions.
Definition: Action.h:767
const ToolChain * getHostTC() const
Definition: Action.h:771
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Definition: Action.h:656
void setOffloadKind(OffloadKind SetKind)
Definition: Action.h:703
Set a ToolChain's effective triple.
Definition: ToolChain.h:839
void getSYCLDeviceLibPath(llvm::SmallVector< llvm::SmallString< 128 >, 4 > &DeviceLibPaths) const
Definition: SYCL.cpp:34
void setRTSetsSpecConstants(bool Val)
Definition: Action.h:807
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:92
virtual std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, types::ID InputType=types::TY_INVALID) const
ComputeEffectiveClangTriple - Return the Clang triple to use for this target, which may take into acc...
Definition: ToolChain.cpp:1128
const Driver & getDriver() const
Definition: ToolChain.h:269
path_list & getFilePaths()
Definition: ToolChain.h:311
static llvm::Triple getOpenMPTriple(StringRef TripleStr)
Definition: ToolChain.h:822
virtual RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:1159
virtual Tool * SelectTool(const JobAction &JA) const
Choose a tool to use to handle the action JA.
Definition: ToolChain.cpp:928
path_list & getLibraryPaths()
Definition: ToolChain.h:308
virtual bool isThreadModelSupported(const StringRef Model) const
isThreadModelSupported() - Does this target support a thread model?
Definition: ToolChain.cpp:1067
const MultilibSet & getMultilibs() const
Definition: ToolChain.h:317
llvm::Triple::ArchType getArch() const
Definition: ToolChain.h:285
const llvm::Triple & getTriple() const
Definition: ToolChain.h:271
llvm::vfs::FileSystem & getVFS() const
Definition: ToolChain.cpp:142
Multilib::flags_list getMultilibFlags(const llvm::opt::ArgList &) const
Get flags suitable for multilib selection, based on the provided clang command line arguments.
Definition: ToolChain.cpp:259
virtual void printVerboseInfo(raw_ostream &OS) const
Dispatch to the specific toolchain for verbose printing.
Definition: ToolChain.h:432
static ParsedClangName getTargetAndModeFromProgramName(StringRef ProgName)
Return any implicit target and/or mode flag for an invocation of the compiler driver as ProgName.
Definition: ToolChain.cpp:399
virtual std::string getThreadModel() const
getThreadModel() - Which thread model does this target use?
Definition: ToolChain.h:638
virtual types::ID LookupTypeForExtension(StringRef Ext) const
LookupTypeForExtension - Return the default language type to use for the given extension.
Definition: ToolChain.cpp:1025
virtual std::string getCompilerRTPath() const
Definition: ToolChain.cpp:695
virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
Definition: ToolChain.cpp:751
virtual Expected< SmallVector< std::string > > getSystemGPUArchs(const llvm::opt::ArgList &Args) const
getSystemGPUArchs - Use a tool to detect the user's availible GPUs.
Definition: ToolChain.cpp:1434
std::string getTripleString() const
Definition: ToolChain.h:294
StringRef getDefaultUniversalArchName() const
Provide the default architecture name (as expected by -arch) for this toolchain.
Definition: ToolChain.cpp:423
virtual const llvm::Triple * getAuxTriple() const
Get the toolchain's aux triple, if it has one.
Definition: ToolChain.h:278
path_list & getProgramPaths()
Definition: ToolChain.h:314
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:1221
std::optional< std::string > getRuntimePath() const
Definition: ToolChain.cpp:874
const llvm::SmallVector< Multilib > & getSelectedMultilibs() const
Definition: ToolChain.h:319
StringRef getArchName() const
Definition: ToolChain.h:286
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
virtual bool isDsymutilJob() const
Definition: Tool.h:59
virtual bool hasGoodDiagnostics() const
Does this tool have "good" standardized diagnostics, or should the driver add an additional "command ...
Definition: Tool.h:63
virtual bool isLinkJob() const
Definition: Tool.h:58
const char * getShortName() const
Definition: Tool.h:50
static bool handlesTarget(const llvm::Triple &Triple)
Definition: BareMetal.cpp:235
static std::optional< std::string > parseTargetProfile(StringRef TargetProfile)
Definition: HLSL.cpp:223
static void fixTripleArch(const Driver &D, llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Definition: MinGW.cpp:841
CudaInstallationDetector CudaInstallation
Definition: Cuda.h:203
static bool hasGCCToolchain(const Driver &D, const llvm::opt::ArgList &Args)
void TranslateBackendTargetArgs(const llvm::Triple &Triple, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, StringRef Device="") const
Definition: SYCL.cpp:1598
const char * getPhaseName(ID Id)
Definition: Phases.cpp:15
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
Definition: Phases.h:17
constexpr char NvidiaGPU[]
Definition: SYCL.h:122
constexpr char AmdGPU[]
Definition: SYCL.h:123
constexpr char IntelGPU[]
Definition: SYCL.h:121
bool shouldDoPerObjectFileLinking(const Compilation &C)
Definition: SYCL.cpp:154
SmallVector< std::string, 8 > getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple, bool IsSpirvAOT)
Definition: SYCL.cpp:209
void constructLLVMForeachCommand(Compilation &C, const JobAction &JA, std::unique_ptr< Command > InputCommand, const InputInfoList &InputFiles, const InputInfo &Output, const Tool *T, StringRef Increment, StringRef Ext="out", StringRef ParallelJobs="")
Definition: SYCL.cpp:65
llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str)
Definition: Darwin.cpp:42
void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str, const llvm::opt::ArgList &Args)
StringRef getRISCVArch(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
Definition: RISCV.cpp:251
llvm::SmallString< 256 > getCXX20NamedModuleOutputPath(const llvm::opt::ArgList &Args, const char *BaseInput)
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
Definition: Types.cpp:397
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
Definition: Types.cpp:56
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
Definition: Types.cpp:269
bool isLLVMIR(ID Id)
Is this LLVM IR.
Definition: Types.cpp:256
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
Definition: Types.cpp:52
bool isFPGA(ID Id)
isFPGA - Is this FPGA input.
Definition: Types.cpp:293
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
Definition: Types.cpp:412
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
Definition: Types.cpp:318
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
Definition: Types.cpp:428
ID getPrecompiledType(ID Id)
getPrecompiledType - Get the ID of the type for this input when it has been precompiled,...
Definition: Types.cpp:73
bool isHIP(ID Id)
isHIP - Is this a HIP input.
Definition: Types.cpp:281
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
Definition: Types.cpp:129
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
Definition: Types.cpp:117
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
Definition: Types.cpp:122
bool isArchive(ID Id)
isArchive - Is this an archive input.
Definition: Types.cpp:306
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
Definition: Types.cpp:83
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
Definition: Types.cpp:444
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
Definition: Types.cpp:322
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
Definition: Types.cpp:163
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
Definition: Driver.h:68
@ HeaderMode_System
Definition: Driver.h:72
@ HeaderMode_None
Definition: Driver.h:69
@ HeaderMode_Default
Definition: Driver.h:70
@ HeaderMode_User
Definition: Driver.h:71
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
Definition: Driver.h:58
@ LTOK_Unknown
Definition: Driver.h:62
bool isSYCLNativeCPU(const llvm::opt::ArgList &Args)
Definition: SYCL.h:238
bool isStaticArchiveFile(const StringRef &FileName)
Definition: Driver.cpp:10405
bool isObjectFile(std::string FileName)
Definition: Driver.cpp:10391
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
Definition: Driver.cpp:10609
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
Definition: Driver.cpp:10438
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
Definition: Driver.cpp:10455
const llvm::opt::OptTable & getDriverOptTable()
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
Definition: Driver.cpp:10453
@ EmitLLVM
Emit a .ll file.
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
Definition: Interp.h:218
std::string toString(const til::SExpr *E)
ASTEdit remove(RangeSelector S)
Removes the source selected by S.
The JSON file list parser is used to communicate input to InstallAPI.
CudaArch
Definition: Cuda.h:54
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
Definition: TargetID.cpp:105
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
Definition: TargetID.cpp:54
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
Definition: TargetID.cpp:145
CudaArch StringToCudaArch(llvm::StringRef S)
Definition: Cuda.cpp:169
static bool IsAMDGpuArch(CudaArch A)
Definition: Cuda.h:144
static bool IsNVIDIAGpuArch(CudaArch A)
Definition: Cuda.h:140
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
BackendAction
Definition: BackendUtil.h:35
const FunctionProtoType * T
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
Definition: TargetID.cpp:130
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition: JsonSupport.h:21
const char * CudaArchToString(CudaArch A)
Definition: Cuda.cpp:151
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Definition: Version.cpp:96
Visibility
Describes the different kinds of visibility that a declaration may have.
Definition: Visibility.h:34
Definition: Format.h:5433
float __ovld __cnfn normalize(float)
Returns a vector in the same direction as p but with a length of 1.
#define true
Definition: stdbool.h:25
#define false
Definition: stdbool.h:26
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
Definition: Driver.h:545
llvm::SmallVector< std::string, 4 > TemporaryFiles
Definition: Driver.h:546
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
Definition: ToolChain.h:73
std::string ModeSuffix
Driver mode part of the executable name, as g++.
Definition: ToolChain.h:70
std::string TargetPrefix
Target part of the executable name, as i686-linux-android.
Definition: ToolChain.h:67