clang  12.0.0git
Hexagon.cpp
Go to the documentation of this file.
1 //===--- Hexagon.cpp - Hexagon ToolChain Implementations --------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Hexagon.h"
10 #include "CommonArgs.h"
11 #include "InputInfo.h"
13 #include "clang/Driver/Driver.h"
15 #include "clang/Driver/Options.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include "llvm/Option/ArgList.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/VirtualFileSystem.h"
21 
22 using namespace clang::driver;
23 using namespace clang::driver::tools;
24 using namespace clang::driver::toolchains;
25 using namespace clang;
26 using namespace llvm::opt;
27 
28 // Default hvx-length for various versions.
29 static StringRef getDefaultHvxLength(StringRef Cpu) {
30  return llvm::StringSwitch<StringRef>(Cpu)
31  .Case("v60", "64b")
32  .Case("v62", "64b")
33  .Case("v65", "64b")
34  .Default("128b");
35 }
36 
37 static void handleHVXWarnings(const Driver &D, const ArgList &Args) {
38  // Handle the unsupported values passed to mhvx-length.
39  if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
40  StringRef Val = A->getValue();
41  if (!Val.equals_lower("64b") && !Val.equals_lower("128b"))
42  D.Diag(diag::err_drv_unsupported_option_argument)
43  << A->getOption().getName() << Val;
44  }
45 }
46 
47 // Handle hvx target features explicitly.
48 static void handleHVXTargetFeatures(const Driver &D, const ArgList &Args,
49  std::vector<StringRef> &Features,
50  StringRef Cpu, bool &HasHVX) {
51  // Handle HVX warnings.
52  handleHVXWarnings(D, Args);
53 
54  // Add the +hvx* features based on commandline flags.
55  StringRef HVXFeature, HVXLength;
56 
57  // Handle -mhvx, -mhvx=, -mno-hvx.
58  if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx,
59  options::OPT_mhexagon_hvx,
60  options::OPT_mhexagon_hvx_EQ)) {
61  if (A->getOption().matches(options::OPT_mno_hexagon_hvx))
62  return;
63  if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ)) {
64  HasHVX = true;
65  HVXFeature = Cpu = A->getValue();
66  HVXFeature = Args.MakeArgString(llvm::Twine("+hvx") + HVXFeature.lower());
67  } else if (A->getOption().matches(options::OPT_mhexagon_hvx)) {
68  HasHVX = true;
69  HVXFeature = Args.MakeArgString(llvm::Twine("+hvx") + Cpu);
70  }
71  Features.push_back(HVXFeature);
72  }
73 
74  // Handle -mhvx-length=.
75  if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
76  // These flags are valid only if HVX in enabled.
77  if (!HasHVX)
78  D.Diag(diag::err_drv_invalid_hvx_length);
79  else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ))
80  HVXLength = A->getValue();
81  }
82  // Default hvx-length based on Cpu.
83  else if (HasHVX)
84  HVXLength = getDefaultHvxLength(Cpu);
85 
86  if (!HVXLength.empty()) {
87  HVXFeature =
88  Args.MakeArgString(llvm::Twine("+hvx-length") + HVXLength.lower());
89  Features.push_back(HVXFeature);
90  }
91 }
92 
93 // Hexagon target features.
94 void hexagon::getHexagonTargetFeatures(const Driver &D, const ArgList &Args,
95  std::vector<StringRef> &Features) {
96  handleTargetFeaturesGroup(Args, Features,
97  options::OPT_m_hexagon_Features_Group);
98 
99  bool UseLongCalls = false;
100  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
101  options::OPT_mno_long_calls)) {
102  if (A->getOption().matches(options::OPT_mlong_calls))
103  UseLongCalls = true;
104  }
105 
106  Features.push_back(UseLongCalls ? "+long-calls" : "-long-calls");
107 
108  bool HasHVX = false;
110  // 't' in Cpu denotes tiny-core micro-architecture. For now, the co-processors
111  // have no dependency on micro-architecture.
112  const bool TinyCore = Cpu.contains('t');
113 
114  if (TinyCore)
115  Cpu = Cpu.take_front(Cpu.size() - 1);
116 
117  handleHVXTargetFeatures(D, Args, Features, Cpu, HasHVX);
118 
119  if (HexagonToolChain::isAutoHVXEnabled(Args) && !HasHVX)
120  D.Diag(diag::warn_drv_vectorize_needs_hvx);
121 }
122 
123 // Hexagon tools start.
125  ArgStringList &CmdArgs) const {
126 }
127 
129  const InputInfo &Output,
130  const InputInfoList &Inputs,
131  const ArgList &Args,
132  const char *LinkingOutput) const {
133  claimNoWarnArgs(Args);
134 
135  auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
136  const Driver &D = HTC.getDriver();
137  ArgStringList CmdArgs;
138 
139  CmdArgs.push_back("--arch=hexagon");
140 
141  RenderExtraToolArgs(JA, CmdArgs);
142 
143  const char *AsName = "llvm-mc";
144  CmdArgs.push_back("-filetype=obj");
145  CmdArgs.push_back(Args.MakeArgString(
146  "-mcpu=hexagon" +
148 
149  if (Output.isFilename()) {
150  CmdArgs.push_back("-o");
151  CmdArgs.push_back(Output.getFilename());
152  } else {
153  assert(Output.isNothing() && "Unexpected output");
154  CmdArgs.push_back("-fsyntax-only");
155  }
156 
158  CmdArgs.push_back(Args.MakeArgString("-gpsize=" + Twine(G.getValue())));
159  }
160 
161  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
162 
163  // Only pass -x if gcc will understand it; otherwise hope gcc
164  // understands the suffix correctly. The main use case this would go
165  // wrong in is for linker inputs if they happened to have an odd
166  // suffix; really the only way to get this to happen is a command
167  // like '-x foobar a.c' which will treat a.c like a linker input.
168  //
169  // FIXME: For the linker case specifically, can we safely convert
170  // inputs into '-Wl,' options?
171  for (const auto &II : Inputs) {
172  // Don't try to pass LLVM or AST inputs to a generic gcc.
173  if (types::isLLVMIR(II.getType()))
174  D.Diag(clang::diag::err_drv_no_linker_llvm_support)
175  << HTC.getTripleString();
176  else if (II.getType() == types::TY_AST)
177  D.Diag(clang::diag::err_drv_no_ast_support)
178  << HTC.getTripleString();
179  else if (II.getType() == types::TY_ModuleFile)
180  D.Diag(diag::err_drv_no_module_support)
181  << HTC.getTripleString();
182 
183  if (II.isFilename())
184  CmdArgs.push_back(II.getFilename());
185  else
186  // Don't render as input, we need gcc to do the translations.
187  // FIXME: What is this?
188  II.getInputArg().render(Args, CmdArgs);
189  }
190 
191  auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
192  C.addCommand(std::make_unique<Command>(JA, *this,
194  Exec, CmdArgs, Inputs, Output));
195 }
196 
198  ArgStringList &CmdArgs) const {
199 }
200 
201 static void
203  const toolchains::HexagonToolChain &HTC,
204  const InputInfo &Output, const InputInfoList &Inputs,
205  const ArgList &Args, ArgStringList &CmdArgs,
206  const char *LinkingOutput) {
207 
208  const Driver &D = HTC.getDriver();
209 
210  //----------------------------------------------------------------------------
211  //
212  //----------------------------------------------------------------------------
213  bool IsStatic = Args.hasArg(options::OPT_static);
214  bool IsShared = Args.hasArg(options::OPT_shared);
215  bool IsPIE = Args.hasArg(options::OPT_pie);
216  bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
217  bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
218  bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
219  bool UseG0 = false;
220  const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
221  bool UseLLD = (llvm::sys::path::filename(Exec).equals_lower("ld.lld") ||
222  llvm::sys::path::stem(Exec).equals_lower("ld.lld"));
223  bool UseShared = IsShared && !IsStatic;
224  StringRef CpuVer = toolchains::HexagonToolChain::GetTargetCPUVersion(Args);
225 
226  //----------------------------------------------------------------------------
227  // Silence warnings for various options
228  //----------------------------------------------------------------------------
229  Args.ClaimAllArgs(options::OPT_g_Group);
230  Args.ClaimAllArgs(options::OPT_emit_llvm);
231  Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
232  // handled somewhere else.
233  Args.ClaimAllArgs(options::OPT_static_libgcc);
234 
235  //----------------------------------------------------------------------------
236  //
237  //----------------------------------------------------------------------------
238  if (Args.hasArg(options::OPT_s))
239  CmdArgs.push_back("-s");
240 
241  if (Args.hasArg(options::OPT_r))
242  CmdArgs.push_back("-r");
243 
244  for (const auto &Opt : HTC.ExtraOpts)
245  CmdArgs.push_back(Opt.c_str());
246 
247  if (!UseLLD) {
248  CmdArgs.push_back("-march=hexagon");
249  CmdArgs.push_back(Args.MakeArgString("-mcpu=hexagon" + CpuVer));
250  }
251 
252  if (IsShared) {
253  CmdArgs.push_back("-shared");
254  // The following should be the default, but doing as hexagon-gcc does.
255  CmdArgs.push_back("-call_shared");
256  }
257 
258  if (IsStatic)
259  CmdArgs.push_back("-static");
260 
261  if (IsPIE && !IsShared)
262  CmdArgs.push_back("-pie");
263 
265  CmdArgs.push_back(Args.MakeArgString("-G" + Twine(G.getValue())));
266  UseG0 = G.getValue() == 0;
267  }
268 
269  CmdArgs.push_back("-o");
270  CmdArgs.push_back(Output.getFilename());
271 
272  if (HTC.getTriple().isMusl()) {
273  if (!Args.hasArg(options::OPT_shared, options::OPT_static))
274  CmdArgs.push_back("-dynamic-linker=/lib/ld-musl-hexagon.so.1");
275 
276  if (!Args.hasArg(options::OPT_shared, options::OPT_nostartfiles,
277  options::OPT_nostdlib))
278  CmdArgs.push_back(Args.MakeArgString(D.SysRoot + "/usr/lib/crt1.o"));
279  else if (Args.hasArg(options::OPT_shared) &&
280  !Args.hasArg(options::OPT_nostartfiles, options::OPT_nostdlib))
281  CmdArgs.push_back(Args.MakeArgString(D.SysRoot + "/usr/lib/crti.o"));
282 
283  CmdArgs.push_back(
284  Args.MakeArgString(StringRef("-L") + D.SysRoot + "/usr/lib"));
285  Args.AddAllArgs(CmdArgs,
286  {options::OPT_T_Group, options::OPT_e, options::OPT_s,
287  options::OPT_t, options::OPT_u_Group});
288  AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
289 
290  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
291  CmdArgs.push_back("-lclang_rt.builtins-hexagon");
292  CmdArgs.push_back("-lc");
293  }
294  if (D.CCCIsCXX()) {
295  if (HTC.ShouldLinkCXXStdlib(Args))
296  HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
297  }
298  return;
299  }
300 
301  //----------------------------------------------------------------------------
302  // moslib
303  //----------------------------------------------------------------------------
304  std::vector<std::string> OsLibs;
305  bool HasStandalone = false;
306  for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
307  A->claim();
308  OsLibs.emplace_back(A->getValue());
309  HasStandalone = HasStandalone || (OsLibs.back() == "standalone");
310  }
311  if (OsLibs.empty()) {
312  OsLibs.push_back("standalone");
313  HasStandalone = true;
314  }
315 
316  //----------------------------------------------------------------------------
317  // Start Files
318  //----------------------------------------------------------------------------
319  const std::string MCpuSuffix = "/" + CpuVer.str();
320  const std::string MCpuG0Suffix = MCpuSuffix + "/G0";
321  const std::string RootDir =
323  const std::string StartSubDir =
324  "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
325 
326  auto Find = [&HTC] (const std::string &RootDir, const std::string &SubDir,
327  const char *Name) -> std::string {
328  std::string RelName = SubDir + Name;
329  std::string P = HTC.GetFilePath(RelName.c_str());
330  if (llvm::sys::fs::exists(P))
331  return P;
332  return RootDir + RelName;
333  };
334 
335  if (IncStdLib && IncStartFiles) {
336  if (!IsShared) {
337  if (HasStandalone) {
338  std::string Crt0SA = Find(RootDir, StartSubDir, "/crt0_standalone.o");
339  CmdArgs.push_back(Args.MakeArgString(Crt0SA));
340  }
341  std::string Crt0 = Find(RootDir, StartSubDir, "/crt0.o");
342  CmdArgs.push_back(Args.MakeArgString(Crt0));
343  }
344  std::string Init = UseShared
345  ? Find(RootDir, StartSubDir + "/pic", "/initS.o")
346  : Find(RootDir, StartSubDir, "/init.o");
347  CmdArgs.push_back(Args.MakeArgString(Init));
348  }
349 
350  //----------------------------------------------------------------------------
351  // Library Search Paths
352  //----------------------------------------------------------------------------
353  const ToolChain::path_list &LibPaths = HTC.getFilePaths();
354  for (const auto &LibPath : LibPaths)
355  CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
356 
357  //----------------------------------------------------------------------------
358  //
359  //----------------------------------------------------------------------------
360  Args.AddAllArgs(CmdArgs,
361  {options::OPT_T_Group, options::OPT_e, options::OPT_s,
362  options::OPT_t, options::OPT_u_Group});
363 
364  AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
365 
366  //----------------------------------------------------------------------------
367  // Libraries
368  //----------------------------------------------------------------------------
369  if (IncStdLib && IncDefLibs) {
370  if (D.CCCIsCXX()) {
371  if (HTC.ShouldLinkCXXStdlib(Args))
372  HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
373  CmdArgs.push_back("-lm");
374  }
375 
376  CmdArgs.push_back("--start-group");
377 
378  if (!IsShared) {
379  for (StringRef Lib : OsLibs)
380  CmdArgs.push_back(Args.MakeArgString("-l" + Lib));
381  CmdArgs.push_back("-lc");
382  }
383  CmdArgs.push_back("-lgcc");
384 
385  CmdArgs.push_back("--end-group");
386  }
387 
388  //----------------------------------------------------------------------------
389  // End files
390  //----------------------------------------------------------------------------
391  if (IncStdLib && IncStartFiles) {
392  std::string Fini = UseShared
393  ? Find(RootDir, StartSubDir + "/pic", "/finiS.o")
394  : Find(RootDir, StartSubDir, "/fini.o");
395  CmdArgs.push_back(Args.MakeArgString(Fini));
396  }
397 }
398 
400  const InputInfo &Output,
401  const InputInfoList &Inputs,
402  const ArgList &Args,
403  const char *LinkingOutput) const {
404  auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
405 
406  ArgStringList CmdArgs;
407  constructHexagonLinkArgs(C, JA, HTC, Output, Inputs, Args, CmdArgs,
408  LinkingOutput);
409 
410  const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
411  C.addCommand(std::make_unique<Command>(JA, *this,
413  Exec, CmdArgs, Inputs, Output));
414 }
415 // Hexagon tools end.
416 
417 /// Hexagon Toolchain
418 
419 std::string HexagonToolChain::getHexagonTargetDir(
420  const std::string &InstalledDir,
421  const SmallVectorImpl<std::string> &PrefixDirs) const {
422  std::string InstallRelDir;
423  const Driver &D = getDriver();
424 
425  // Locate the rest of the toolchain ...
426  for (auto &I : PrefixDirs)
427  if (D.getVFS().exists(I))
428  return I;
429 
430  if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
431  return InstallRelDir;
432 
433  return InstalledDir;
434 }
435 
436 Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
437  const ArgList &Args) {
438  StringRef Gn = "";
439  if (Arg *A = Args.getLastArg(options::OPT_G)) {
440  Gn = A->getValue();
441  } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
442  options::OPT_fPIC)) {
443  Gn = "0";
444  }
445 
446  unsigned G;
447  if (!Gn.getAsInteger(10, G))
448  return G;
449 
450  return None;
451 }
452 
453 void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
454  ToolChain::path_list &LibPaths) const {
455  const Driver &D = getDriver();
456 
457  //----------------------------------------------------------------------------
458  // -L Args
459  //----------------------------------------------------------------------------
460  for (Arg *A : Args.filtered(options::OPT_L))
461  for (const char *Value : A->getValues())
462  LibPaths.push_back(Value);
463 
464  //----------------------------------------------------------------------------
465  // Other standard paths
466  //----------------------------------------------------------------------------
467  std::vector<std::string> RootDirs;
468  std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
469  std::back_inserter(RootDirs));
470 
471  std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
472  D.PrefixDirs);
473  if (llvm::find(RootDirs, TargetDir) == RootDirs.end())
474  RootDirs.push_back(TargetDir);
475 
476  bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
477  // Assume G0 with -shared.
478  bool HasG0 = Args.hasArg(options::OPT_shared);
479  if (auto G = getSmallDataThreshold(Args))
480  HasG0 = G.getValue() == 0;
481 
482  const std::string CpuVer = GetTargetCPUVersion(Args).str();
483  for (auto &Dir : RootDirs) {
484  std::string LibDir = Dir + "/hexagon/lib";
485  std::string LibDirCpu = LibDir + '/' + CpuVer;
486  if (HasG0) {
487  if (HasPIC)
488  LibPaths.push_back(LibDirCpu + "/G0/pic");
489  LibPaths.push_back(LibDirCpu + "/G0");
490  }
491  LibPaths.push_back(LibDirCpu);
492  LibPaths.push_back(LibDir);
493  }
494 }
495 
496 HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
497  const llvm::opt::ArgList &Args)
498  : Linux(D, Triple, Args) {
499  const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
500  D.PrefixDirs);
501 
502  // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
503  // program paths
504  const std::string BinDir(TargetDir + "/bin");
505  if (D.getVFS().exists(BinDir))
506  getProgramPaths().push_back(BinDir);
507 
508  ToolChain::path_list &LibPaths = getFilePaths();
509 
510  // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
511  // 'elf' OS type, so the Linux paths are not appropriate. When we actually
512  // support 'linux' we'll need to fix this up
513  LibPaths.clear();
514  getHexagonLibraryPaths(Args, LibPaths);
515 }
516 
518 
519 void HexagonToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
520  ArgStringList &CmdArgs) const {
522  switch (Type) {
524  CmdArgs.push_back("-lc++");
525  CmdArgs.push_back("-lc++abi");
526  CmdArgs.push_back("-lunwind");
527  break;
528 
530  CmdArgs.push_back("-lstdc++");
531  break;
532  }
533 }
534 
536  return new tools::hexagon::Assembler(*this);
537 }
538 
540  return new tools::hexagon::Linker(*this);
541 }
542 
544  const llvm::opt::ArgList &DriverArgs) const {
545  // Copied in large part from lib/Frontend/CompilerInvocation.cpp.
546  Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
547  if (!A)
548  return 0;
549 
550  if (A->getOption().matches(options::OPT_O0))
551  return 0;
552  if (A->getOption().matches(options::OPT_Ofast) ||
553  A->getOption().matches(options::OPT_O4))
554  return 3;
555  assert(A->getNumValues() != 0);
556  StringRef S(A->getValue());
557  if (S == "s" || S == "z" || S.empty())
558  return 2;
559  if (S == "g")
560  return 1;
561 
562  unsigned OptLevel;
563  if (S.getAsInteger(10, OptLevel))
564  return 0;
565  return OptLevel;
566 }
567 
568 void HexagonToolChain::addClangTargetOptions(const ArgList &DriverArgs,
569  ArgStringList &CC1Args,
570  Action::OffloadKind) const {
571 
572  bool UseInitArrayDefault = getTriple().isMusl();
573 
574  if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
575  options::OPT_fno_use_init_array,
576  UseInitArrayDefault))
577  CC1Args.push_back("-fno-use-init-array");
578 
579  if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
580  CC1Args.push_back("-target-feature");
581  CC1Args.push_back("+reserved-r19");
582  }
583  if (isAutoHVXEnabled(DriverArgs)) {
584  CC1Args.push_back("-mllvm");
585  CC1Args.push_back("-hexagon-autohvx");
586  }
587 }
588 
589 void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
590  ArgStringList &CC1Args) const {
591  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
592  DriverArgs.hasArg(options::OPT_nostdlibinc))
593  return;
594 
595  const Driver &D = getDriver();
596  if (!D.SysRoot.empty()) {
598  if (getTriple().isMusl())
599  llvm::sys::path::append(P, "usr/include");
600  else
601  llvm::sys::path::append(P, "include");
602  addExternCSystemInclude(DriverArgs, CC1Args, P.str());
603  return;
604  }
605 
606  std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
607  D.PrefixDirs);
608  addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
609 }
610 
612  const llvm::opt::ArgList &DriverArgs,
613  llvm::opt::ArgStringList &CC1Args) const {
614  const Driver &D = getDriver();
615  if (!D.SysRoot.empty() && getTriple().isMusl())
616  addLibStdCXXIncludePaths(D.SysRoot + "/usr/include/c++/v1", "", "", "", "",
617  "", DriverArgs, CC1Args);
618  else if (getTriple().isMusl())
619  addLibStdCXXIncludePaths("/usr/include/c++/v1", "", "", "", "", "",
620  DriverArgs, CC1Args);
621  else {
622  std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
623  addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++/v1", "", "", "",
624  "", DriverArgs, CC1Args);
625  }
626 }
628  const llvm::opt::ArgList &DriverArgs,
629  llvm::opt::ArgStringList &CC1Args) const {
630  const Driver &D = getDriver();
631  std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
632  addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++", "", "", "", "",
633  DriverArgs, CC1Args);
634 }
635 
637 HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
638  Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
639  if (!A) {
640  if (getTriple().isMusl())
641  return ToolChain::CST_Libcxx;
642  else
644  }
645  StringRef Value = A->getValue();
646  if (Value != "libstdc++" && Value != "libc++")
647  getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
648 
649  if (Value == "libstdc++")
651  else if (Value == "libc++")
652  return ToolChain::CST_Libcxx;
653  else
655 }
656 
657 bool HexagonToolChain::isAutoHVXEnabled(const llvm::opt::ArgList &Args) {
658  if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
659  options::OPT_fno_vectorize))
660  return A->getOption().matches(options::OPT_fvectorize);
661  return false;
662 }
663 
664 //
665 // Returns the default CPU for Hexagon. This is the default compilation target
666 // if no Hexagon processor is selected at the command-line.
667 //
669  return "hexagonv60";
670 }
671 
672 const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
673  Arg *CpuArg = nullptr;
674  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
675  CpuArg = A;
676 
677  StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
678  if (CPU.startswith("hexagon"))
679  return CPU.substr(sizeof("hexagon") - 1);
680  return CPU;
681 }
bool IsStatic
Definition: Format.cpp:2091
static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory with extern "C" semantics to CC1 arguments.
Definition: ToolChain.cpp:954
void handleTargetFeaturesGroup(const llvm::opt::ArgList &Args, std::vector< StringRef > &Features, llvm::opt::OptSpecifier Group)
Iterate Args and convert -mxxx to +xxx and -mno-xxx to -xxx and append it to Features.
prefix_list PrefixDirs
Definition: Driver.h:145
StringRef P
The base class of the type hierarchy.
Definition: Type.h:1478
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:109
const char * getFilename() const
Definition: InputInfo.h:83
virtual void RenderExtraToolArgs(const JobAction &JA, llvm::opt::ArgStringList &CmdArgs) const
Definition: Hexagon.cpp:197
path_list & getProgramPaths()
Definition: ToolChain.h:246
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
std::string GetFilePath(const char *Name) const
Definition: ToolChain.cpp:548
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override
Add options that need to be passed to cc1 for this target.
Definition: Hexagon.cpp:568
path_list & getFilePaths()
Definition: ToolChain.h:243
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:59
static void constructHexagonLinkArgs(Compilation &C, const JobAction &JA, const toolchains::HexagonToolChain &HTC, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, ArgStringList &CmdArgs, const char *LinkingOutput)
Definition: Hexagon.cpp:202
void addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Definition: Hexagon.cpp:627
llvm::vfs::FileSystem & getVFS() const
Definition: Driver.h:319
void getHexagonLibraryPaths(const llvm::opt::ArgList &Args, ToolChain::path_list &LibPaths) const
Definition: Hexagon.cpp:453
void addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Definition: Hexagon.cpp:611
void RenderExtraToolArgs(const JobAction &JA, llvm::opt::ArgStringList &CmdArgs) const
Definition: Hexagon.cpp:124
static void handleHVXTargetFeatures(const Driver &D, const ArgList &Args, std::vector< StringRef > &Features, StringRef Cpu, bool &HasHVX)
Definition: Hexagon.cpp:48
static const StringRef GetTargetCPUVersion(const llvm::opt::ArgList &Args)
Definition: Hexagon.cpp:672
std::string getHexagonTargetDir(const std::string &InstalledDir, const SmallVectorImpl< std::string > &PrefixDirs) const
Hexagon Toolchain.
Definition: Hexagon.cpp:419
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
Definition: Hexagon.cpp:589
const Driver & getDriver() const
Definition: ToolChain.h:205
std::string InstalledDir
The path to the installed clang directory, if any.
Definition: Driver.h:129
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Definition: Driver.h:173
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
AddCXXStdlibLibArgs - Add the system specific linker arguments to use for the given C++ standard libr...
Definition: Hexagon.cpp:519
unsigned getOptimizationLevel(const llvm::opt::ArgList &DriverArgs) const
Definition: Hexagon.cpp:543
Tool * buildAssembler() const override
Definition: Hexagon.cpp:535
CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override
Definition: Hexagon.cpp:637
bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const
Returns if the C++ standard library should be linked in.
Definition: ToolChain.cpp:1002
Dataflow Directional Tag Classes.
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
std::string SysRoot
sysroot, if present
Definition: Driver.h:148
void getHexagonTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, std::vector< StringRef > &Features)
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
void claimNoWarnArgs(const llvm::opt::ArgList &Args)
const char * getInstalledDir() const
Get the path to where the clang executable was installed.
Definition: Driver.h:338
std::string GetLinkerPath(bool *LinkerIsLLD=nullptr, bool *LinkerIsLLDDarwinNew=nullptr) const
Returns the linker path, respecting the -fuse-ld= argument to determine the linker suffix or name.
Definition: ToolChain.cpp:556
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
const llvm::Triple & getTriple() const
Definition: ToolChain.h:207
static bool isAutoHVXEnabled(const llvm::opt::ArgList &Args)
Definition: Hexagon.cpp:657
static Optional< unsigned > getSmallDataThreshold(const llvm::opt::ArgList &Args)
Definition: Hexagon.cpp:436
static StringRef getDefaultHvxLength(StringRef Cpu)
Definition: Hexagon.cpp:29
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition: Hexagon.cpp:128
bool isNothing() const
Definition: InputInfo.h:74
static constexpr ResponseFileSupport AtFileCurCP()
Definition: Job.h:91
bool isFilename() const
Definition: InputInfo.h:75
static const StringRef GetDefaultCPU()
Definition: Hexagon.cpp:668
bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple, StringRef TargetMultiarchTriple, Twine IncludeSuffix, const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Helper to add the variant paths of a libstdc++ installation.
Definition: Gnu.cpp:2973
static void handleHVXWarnings(const Driver &D, const ArgList &Args)
Definition: Hexagon.cpp:37
std::vector< std::string > ExtraOpts
Definition: Linux.h:51
bool isLLVMIR(ID Id)
Is this LLVM IR.
Definition: Types.cpp:181
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition: Hexagon.cpp:399