17#include "llvm/Option/ArgList.h"
18#include "llvm/Support/FileSystem.h"
19#include "llvm/Support/Path.h"
20#include "llvm/Support/VirtualFileSystem.h"
30 return llvm::StringSwitch<StringRef>(HvxVer)
39 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
40 StringRef Val = A->getValue();
41 if (!Val.equals_insensitive(
"64b") && !Val.equals_insensitive(
"128b"))
42 D.
Diag(diag::err_drv_unsupported_option_argument)
43 << A->getSpelling() << Val;
49 std::vector<StringRef> &Features,
50 StringRef Cpu,
bool &HasHVX) {
54 auto makeFeature = [&Args](Twine T,
bool Enable) -> StringRef {
55 const std::string &S = T.str();
57 Opt.consume_back(
"=");
58 if (Opt.starts_with(
"mno-"))
59 Opt = Opt.drop_front(4);
60 else if (Opt.starts_with(
"m"))
61 Opt = Opt.drop_front(1);
62 return Args.MakeArgString(Twine(Enable ?
"+" :
"-") + Twine(Opt));
65 auto withMinus = [](StringRef S) -> std::string {
69 std::optional<std::string> HvxVer =
71 HasHVX = HvxVer.has_value();
73 Features.push_back(makeFeature(Twine(
"hvx") + *HvxVer,
true));
75 if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx)) {
77 Features.push_back(makeFeature(A->getOption().getName(),
false));
85 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
88 D.
Diag(diag::err_drv_needs_hvx) << withMinus(A->getOption().getName());
89 else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ))
90 HvxLen = A->getValue();
94 StringRef L = makeFeature(Twine(
"hvx-length") + HvxLen.lower(),
true);
95 Features.push_back(L);
98 unsigned HvxVerNum = 0;
101 StringRef HvxVerRef(*HvxVer);
102 if (HvxVerRef.size() <= 1 ||
103 HvxVerRef.drop_front(1).getAsInteger(10, HvxVerNum))
108 auto checkFlagHvxVersion =
109 [&](
auto FlagOn,
auto FlagOff,
110 unsigned MinVerNum) -> std::optional<StringRef> {
116 Arg *A = Args.getLastArg(FlagOn, FlagOff);
120 StringRef OptName = A->getOption().getName();
121 if (A->getOption().matches(FlagOff))
122 return makeFeature(OptName,
false);
125 D.
Diag(diag::err_drv_needs_hvx) << withMinus(OptName);
128 if (HvxVerNum < MinVerNum) {
129 D.
Diag(diag::err_drv_needs_hvx_version)
130 << withMinus(OptName) << (
"v" + std::to_string(HvxVerNum));
133 return makeFeature(OptName,
true);
136 if (
auto F = checkFlagHvxVersion(options::OPT_mhexagon_hvx_qfloat,
137 options::OPT_mno_hexagon_hvx_qfloat, 68)) {
138 Features.push_back(*F);
140 if (
auto F = checkFlagHvxVersion(options::OPT_mhexagon_hvx_ieee_fp,
141 options::OPT_mno_hexagon_hvx_ieee_fp, 68)) {
142 Features.push_back(*F);
148 const llvm::Triple &Triple,
150 std::vector<StringRef> &Features) {
152 options::OPT_m_hexagon_Features_Group);
154 bool UseLongCalls =
false;
155 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
156 options::OPT_mno_long_calls)) {
157 if (A->getOption().matches(options::OPT_mlong_calls))
161 Features.push_back(UseLongCalls ?
"+long-calls" :
"-long-calls");
167 const bool TinyCore = Cpu.contains(
't');
170 Cpu = Cpu.take_front(Cpu.size() - 1);
175 D.
Diag(diag::warn_drv_needs_hvx) <<
"auto-vectorization";
180 ArgStringList &CmdArgs)
const {
187 const char *LinkingOutput)
const {
191 const Driver &D = HTC.getDriver();
192 ArgStringList CmdArgs;
194 CmdArgs.push_back(
"--arch=hexagon");
198 const char *AsName =
"llvm-mc";
199 CmdArgs.push_back(
"-filetype=obj");
200 CmdArgs.push_back(Args.MakeArgString(
208 CmdArgs.push_back(
"-o");
211 CmdArgs.push_back(
"-fsyntax-only");
214 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_ieee_fp,
215 options::OPT_mno_hexagon_hvx_ieee_fp)) {
216 if (A->getOption().matches(options::OPT_mhexagon_hvx_ieee_fp))
217 CmdArgs.push_back(
"-mhvx-ieee-fp");
221 CmdArgs.push_back(Args.MakeArgString(
"-gpsize=" + Twine(*G)));
224 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
234 for (
const auto &II : Inputs) {
237 D.
Diag(clang::diag::err_drv_no_linker_llvm_support)
238 << HTC.getTripleString();
239 else if (II.getType() == types::TY_AST)
240 D.
Diag(clang::diag::err_drv_no_ast_support)
241 << HTC.getTripleString();
242 else if (II.getType() == types::TY_ModuleFile)
243 D.
Diag(diag::err_drv_no_module_support)
244 << HTC.getTripleString();
247 CmdArgs.push_back(II.getFilename());
251 II.getInputArg().render(Args, CmdArgs);
254 auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
255 C.addCommand(std::make_unique<Command>(JA, *
this,
257 Exec, CmdArgs, Inputs, Output));
261 ArgStringList &CmdArgs)
const {
268 const ArgList &Args, ArgStringList &CmdArgs,
269 const char *LinkingOutput) {
276 bool IsStatic = Args.hasArg(options::OPT_static);
277 bool IsShared = Args.hasArg(options::OPT_shared);
278 bool IsPIE = Args.hasFlag(options::OPT_pie, options::OPT_no_pie,
280 bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
281 bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
282 bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
284 const char *Exec = Args.MakeArgString(HTC.
GetLinkerPath(&UseLLD));
285 UseLLD = UseLLD || llvm::sys::path::filename(Exec).ends_with(
"ld.lld") ||
286 llvm::sys::path::stem(Exec).ends_with(
"ld.lld");
287 bool UseShared = IsShared && !IsStatic;
296 Args.ClaimAllArgs(options::OPT_g_Group);
297 Args.ClaimAllArgs(options::OPT_emit_llvm);
298 Args.ClaimAllArgs(options::OPT_w);
300 Args.ClaimAllArgs(options::OPT_static_libgcc);
302 CmdArgs.push_back(
"--eh-frame-hdr");
306 if (Args.hasArg(options::OPT_s))
307 CmdArgs.push_back(
"-s");
309 if (Args.hasArg(options::OPT_r))
310 CmdArgs.push_back(
"-r");
313 CmdArgs.push_back(Opt.c_str());
316 CmdArgs.push_back(
"-march=hexagon");
317 CmdArgs.push_back(Args.MakeArgString(
"-mcpu=hexagon" + CpuVer));
321 CmdArgs.push_back(
"-shared");
323 CmdArgs.push_back(
"-call_shared");
327 CmdArgs.push_back(
"-static");
329 if (IsPIE && !IsShared && !Args.hasArg(options::OPT_r))
330 CmdArgs.push_back(
"-pie");
333 CmdArgs.push_back(Args.MakeArgString(
"-G" + Twine(*G)));
335 CmdArgs.push_back(
"-o");
339 if (!Args.hasArg(options::OPT_shared, options::OPT_static))
340 CmdArgs.push_back(
"-dynamic-linker=/lib/ld-musl-hexagon.so.1");
342 if (!Args.hasArg(options::OPT_shared, options::OPT_nostartfiles,
343 options::OPT_nostdlib))
344 CmdArgs.push_back(Args.MakeArgString(D.
SysRoot +
"/usr/lib/crt1.o"));
345 else if (Args.hasArg(options::OPT_shared) &&
346 !Args.hasArg(options::OPT_nostartfiles, options::OPT_nostdlib))
347 CmdArgs.push_back(Args.MakeArgString(D.
SysRoot +
"/usr/lib/crti.o"));
352 Args.MakeArgString(StringRef(
"-L") + D.
SysRoot +
"/usr/lib" +
356 Args.MakeArgString(StringRef(
"-L") + D.
SysRoot +
"/usr/lib"));
357 Args.addAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_s,
358 options::OPT_t, options::OPT_u_Group});
367 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
368 if (NeedsSanitizerDeps) {
372 CmdArgs.push_back(
"-lunwind");
377 if (!Args.hasArg(options::OPT_nolibc))
378 CmdArgs.push_back(
"-lc");
379 CmdArgs.push_back(
"-lclang_rt.builtins-hexagon");
386 for (
const auto &LibPath : LibPaths)
387 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
388 Args.ClaimAllArgs(options::OPT_L);
395 std::vector<std::string> OsLibs;
396 bool HasStandalone =
false;
397 for (
const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
399 OsLibs.emplace_back(A->getValue());
400 HasStandalone = HasStandalone || (OsLibs.back() ==
"standalone");
402 if (OsLibs.empty()) {
403 OsLibs.push_back(
"standalone");
404 HasStandalone =
true;
413 if (IncStdLib && IncStartFiles) {
417 llvm::sys::path::append(Crt0SA,
"crt0_standalone.o");
418 CmdArgs.push_back(Args.MakeArgString(Crt0SA));
421 llvm::sys::path::append(Crt0,
"crt0.o");
422 CmdArgs.push_back(Args.MakeArgString(Crt0));
425 llvm::sys::path::append(
Init, UseShared ?
"initS.o" :
"init.o");
426 CmdArgs.push_back(Args.MakeArgString(
Init));
433 for (
const auto &LibPath : LibPaths)
434 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
435 Args.ClaimAllArgs(options::OPT_L);
440 Args.addAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_s,
441 options::OPT_t, options::OPT_u_Group});
452 if (IncStdLib && IncDefLibs) {
456 CmdArgs.push_back(
"-lm");
459 CmdArgs.push_back(
"--start-group");
462 for (StringRef Lib : OsLibs)
463 CmdArgs.push_back(Args.MakeArgString(
"-l" + Lib));
464 if (!Args.hasArg(options::OPT_nolibc))
465 CmdArgs.push_back(
"-lc");
467 CmdArgs.push_back(
"-lgcc");
469 CmdArgs.push_back(
"--end-group");
475 if (IncStdLib && IncStartFiles) {
477 llvm::sys::path::append(Fini, UseShared ?
"finiS.o" :
"fini.o");
478 CmdArgs.push_back(Args.MakeArgString(Fini));
486 const char *LinkingOutput)
const {
489 ArgStringList CmdArgs;
493 const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
494 C.addCommand(std::make_unique<Command>(JA, *
this,
496 Exec, CmdArgs, Inputs, Output));
503 const std::string &InstalledDir,
505 std::string InstallRelDir;
509 for (
auto &I : PrefixDirs)
510 if (D.getVFS().exists(I))
514 llvm::sys::path::append(Dir,
"..",
"target");
515 return std::string(Dir);
521 if (!D.SysRoot.empty())
531 llvm::sys::path::append(Dir,
"hexagon");
543 llvm::sys::path::append(Dir,
"usr",
"lib");
545 if (!IsLinuxMusl || !
getVFS().exists(Dir)) {
547 llvm::sys::path::append(Dir,
"lib");
550 llvm::sys::path::append(Dir, CpuVer);
553 llvm::sys::path::append(Dir,
"G0");
554 bool IsStatic = Args.hasArg(options::OPT_static);
555 bool IsShared = Args.hasArg(options::OPT_shared);
556 if (IsShared && !IsStatic)
557 llvm::sys::path::append(Dir,
"pic");
565 llvm::sys::path::append(Dir,
"usr",
"include");
567 if (!IsLinuxMusl || !
getVFS().exists(Dir)) {
569 llvm::sys::path::append(Dir,
"include");
573std::optional<unsigned>
576 if (Arg *A = Args.getLastArg(options::OPT_G)) {
578 }
else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
579 options::OPT_fPIC)) {
584 if (!Gn.getAsInteger(10, G))
592 llvm::sys::path::append(Dir,
"usr",
"lib");
596 return std::string(Dir);
606 for (Arg *A : Args.filtered(options::OPT_L))
607 llvm::append_range(LibPaths, A->getValues());
612 std::vector<std::string> RootDirs;
613 std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
614 std::back_inserter(RootDirs));
617 if (!llvm::is_contained(RootDirs, SysRoot))
618 RootDirs.push_back(SysRoot);
620 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
622 bool HasG0 = Args.hasArg(options::OPT_shared);
627 for (
auto &Dir : RootDirs) {
628 std::string LibDir = Dir +
"/lib";
629 std::string LibDirCpu = LibDir +
'/' + CpuVer;
632 LibPaths.push_back(LibDirCpu +
"/G0/pic");
633 LibPaths.push_back(LibDirCpu +
"/G0");
635 LibPaths.push_back(LibDirCpu);
636 LibPaths.push_back(LibDir);
641 const llvm::opt::ArgList &Args)
642 :
Linux(D, Triple, Args) {
654 .
flag(
"-fsanitize=memory")
657 .
flag(
"-fsanitize=address")
672 llvm::sys::path::append(SanLibPath,
"usr",
"lib");
674 LibPaths.insert(LibPaths.begin(), std::string(SanLibPath));
683 ArgStringList &CmdArgs)
const {
687 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
689 getDriver().
Diag(diag::err_drv_unsupported_unwind_for_platform)
690 << A->getValue() <<
getTriple().normalize();
697 CmdArgs.push_back(
"-lc++");
698 if (Args.hasArg(options::OPT_fexperimental_library))
699 CmdArgs.push_back(
"-lc++experimental");
700 CmdArgs.push_back(
"-lc++abi");
702 CmdArgs.push_back(
"-lunwind");
706 CmdArgs.push_back(
"-lstdc++");
720 const llvm::opt::ArgList &DriverArgs)
const {
722 Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
726 if (A->getOption().matches(options::OPT_O0))
728 if (A->getOption().matches(options::OPT_Ofast) ||
729 A->getOption().matches(options::OPT_O4))
731 assert(A->getNumValues() != 0);
732 StringRef S(A->getValue());
733 if (S ==
"s" || S ==
"z" || S.empty())
739 if (S.getAsInteger(10, OptLevel))
745 ArgStringList &CC1Args,
748 bool UseInitArrayDefault =
getTriple().isMusl();
750 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
751 options::OPT_fno_use_init_array,
752 UseInitArrayDefault))
753 CC1Args.push_back(
"-fno-use-init-array");
755 if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
756 CC1Args.push_back(
"-target-feature");
757 CC1Args.push_back(
"+reserved-r19");
760 CC1Args.push_back(
"-mllvm");
761 CC1Args.push_back(
"-hexagon-autohvx");
766 ArgStringList &CC1Args)
const {
767 if (DriverArgs.hasArg(options::OPT_nostdinc))
771 const bool UseBuiltins = !DriverArgs.hasArg(options::OPT_nobuiltininc);
774 llvm::sys::path::append(ResourceDirInclude,
"include");
777 if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
784 llvm::sys::path::append(LocalIncludeDir,
"usr",
"local",
"include");
793 const llvm::opt::ArgList &DriverArgs,
794 llvm::opt::ArgStringList &CC1Args)
const {
797 llvm::sys::path::append(Dir,
"c++",
"v1");
802 const llvm::opt::ArgList &DriverArgs,
803 llvm::opt::ArgStringList &CC1Args)
const {
806 llvm::sys::path::append(Dir,
"c++");
812 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
819 StringRef
Value = A->getValue();
820 if (
Value !=
"libstdc++" &&
Value !=
"libc++")
821 getDriver().
Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
823 if (
Value ==
"libstdc++")
825 else if (
Value ==
"libc++")
832 if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
833 options::OPT_fno_vectorize))
834 return A->getOption().matches(options::OPT_fvectorize);
845 Arg *CpuArg =
nullptr;
846 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
849 StringRef CPU = CpuArg ? CpuArg->getValue() :
GetDefaultCPU();
850 CPU.consume_front(
"hexagon");
854std::optional<std::string>
858 Arg *HvxEnablingArg =
859 Args.getLastArg(options::OPT_mhexagon_hvx, options::OPT_mhexagon_hvx_EQ,
860 options::OPT_mno_hexagon_hvx);
861 if (!HvxEnablingArg ||
862 HvxEnablingArg->getOption().matches(options::OPT_mno_hexagon_hvx))
867 if (!Cpu.empty() && (Cpu.back() ==
'T' || Cpu.back() ==
't'))
868 HvxVer = Cpu.drop_back(1).str();
872 if (HvxEnablingArg->getOption().matches(options::OPT_mhexagon_hvx_EQ))
873 HvxVer = StringRef(HvxEnablingArg->getValue()).lower();
static StringRef getTriple(const Command &Job)
The base class of the type hierarchy.
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
DiagnosticBuilder Diag(unsigned DiagID) const
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
LTOKind getLTOMode() const
Get the specific kind of LTO being performed.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
This corresponds to a single GCC multilib, or a segment of one controlled by a command line flag.
MultilibBuilder & flag(StringRef Flag, bool Disallow=false)
Add a flag to the flags list Flag must be a flag accepted by the driver.
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
std::vector< std::string > flags_list
bool isLLVMIR(ID Id)
Is this LLVM IR.
SmallVector< InputInfo, 4 > InputInfoList
The JSON file list parser is used to communicate input to InstallAPI.
float __ovld __cnfn normalize(float)
Returns a vector in the same direction as p but with a length of 1.
static constexpr ResponseFileSupport AtFileCurCP()