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" 25 using namespace clang;
30 return llvm::StringSwitch<StringRef>(Cpu)
40 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
41 StringRef Val = A->getValue();
42 if (!Val.equals_lower(
"64b") && !Val.equals_lower(
"128b"))
43 D.
Diag(diag::err_drv_unsupported_option_argument)
44 << A->getOption().getName() << Val;
50 std::vector<StringRef> &Features,
56 StringRef HVXFeature, HVXLength;
60 if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx,
61 options::OPT_mhexagon_hvx,
62 options::OPT_mhexagon_hvx_EQ)) {
63 if (A->getOption().matches(options::OPT_mno_hexagon_hvx))
65 if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ)) {
67 HVXFeature = Cpu = A->getValue();
68 HVXFeature = Args.MakeArgString(llvm::Twine(
"+hvx") + HVXFeature.lower());
69 }
else if (A->getOption().matches(options::OPT_mhexagon_hvx)) {
71 HVXFeature = Args.MakeArgString(llvm::Twine(
"+hvx") + Cpu);
73 Features.push_back(HVXFeature);
77 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
80 D.
Diag(diag::err_drv_invalid_hvx_length);
81 else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ))
82 HVXLength = A->getValue();
88 if (!HVXLength.empty()) {
90 Args.MakeArgString(llvm::Twine(
"+hvx-length") + HVXLength.lower());
91 Features.push_back(HVXFeature);
97 std::vector<StringRef> &Features) {
99 options::OPT_m_hexagon_Features_Group);
101 bool UseLongCalls =
false;
102 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
103 options::OPT_mno_long_calls)) {
104 if (A->getOption().matches(options::OPT_mlong_calls))
108 Features.push_back(UseLongCalls ?
"+long-calls" :
"-long-calls");
113 if (HexagonToolChain::isAutoHVXEnabled(Args) && !HasHVX)
114 D.
Diag(diag::warn_drv_vectorize_needs_hvx);
119 ArgStringList &CmdArgs)
const {
126 const char *LinkingOutput)
const {
130 const Driver &D = HTC.getDriver();
131 ArgStringList CmdArgs;
133 CmdArgs.push_back(
"--arch=hexagon");
135 RenderExtraToolArgs(JA, CmdArgs);
137 const char *AsName =
"llvm-mc";
138 CmdArgs.push_back(
"-filetype=obj");
139 CmdArgs.push_back(Args.MakeArgString(
144 CmdArgs.push_back(
"-o");
147 assert(Output.
isNothing() &&
"Unexpected output");
148 CmdArgs.push_back(
"-fsyntax-only");
152 CmdArgs.push_back(Args.MakeArgString(
"-gpsize=" + Twine(G.getValue())));
155 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
165 for (
const auto &II : Inputs) {
168 D.
Diag(clang::diag::err_drv_no_linker_llvm_support)
169 << HTC.getTripleString();
170 else if (II.getType() == types::TY_AST)
171 D.
Diag(clang::diag::err_drv_no_ast_support)
172 << HTC.getTripleString();
173 else if (II.getType() == types::TY_ModuleFile)
174 D.
Diag(diag::err_drv_no_module_support)
175 << HTC.getTripleString();
178 CmdArgs.push_back(II.getFilename());
182 II.getInputArg().render(Args, CmdArgs);
185 auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
186 C.
addCommand(std::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
190 ArgStringList &CmdArgs)
const {
197 const ArgList &Args, ArgStringList &CmdArgs,
198 const char *LinkingOutput) {
205 bool IsStatic = Args.hasArg(options::OPT_static);
206 bool IsShared = Args.hasArg(options::OPT_shared);
207 bool IsPIE = Args.hasArg(options::OPT_pie);
208 bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
209 bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
210 bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
213 bool UseLLD = (llvm::sys::path::filename(Exec).equals_lower(
"ld.lld") ||
214 llvm::sys::path::stem(Exec).equals_lower(
"ld.lld"));
215 bool UseShared = IsShared && !
IsStatic;
221 Args.ClaimAllArgs(options::OPT_g_Group);
222 Args.ClaimAllArgs(options::OPT_emit_llvm);
223 Args.ClaimAllArgs(options::OPT_w);
225 Args.ClaimAllArgs(options::OPT_static_libgcc);
230 if (Args.hasArg(options::OPT_s))
231 CmdArgs.push_back(
"-s");
233 if (Args.hasArg(options::OPT_r))
234 CmdArgs.push_back(
"-r");
237 CmdArgs.push_back(Opt.c_str());
240 CmdArgs.push_back(
"-march=hexagon");
241 CmdArgs.push_back(Args.MakeArgString(
"-mcpu=hexagon" + CpuVer));
245 CmdArgs.push_back(
"-shared");
247 CmdArgs.push_back(
"-call_shared");
251 CmdArgs.push_back(
"-static");
253 if (IsPIE && !IsShared)
254 CmdArgs.push_back(
"-pie");
257 CmdArgs.push_back(Args.MakeArgString(
"-G" + Twine(G.getValue())));
258 UseG0 = G.getValue() == 0;
264 CmdArgs.push_back(
"-o");
270 std::vector<std::string> OsLibs;
271 bool HasStandalone =
false;
273 for (
const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
275 OsLibs.emplace_back(A->getValue());
276 HasStandalone = HasStandalone || (OsLibs.back() ==
"standalone");
278 if (OsLibs.empty()) {
279 OsLibs.push_back(
"standalone");
280 HasStandalone =
true;
286 const std::string MCpuSuffix =
"/" + CpuVer.str();
287 const std::string MCpuG0Suffix = MCpuSuffix +
"/G0";
288 const std::string RootDir =
290 const std::string StartSubDir =
291 "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
293 auto Find = [&HTC] (
const std::string &RootDir,
const std::string &SubDir,
294 const char *Name) -> std::string {
295 std::string RelName = SubDir + Name;
297 if (llvm::sys::fs::exists(P))
299 return RootDir + RelName;
302 if (IncStdLib && IncStartFiles) {
305 std::string Crt0SA = Find(RootDir, StartSubDir,
"/crt0_standalone.o");
306 CmdArgs.push_back(Args.MakeArgString(Crt0SA));
308 std::string Crt0 = Find(RootDir, StartSubDir,
"/crt0.o");
309 CmdArgs.push_back(Args.MakeArgString(Crt0));
311 std::string Init = UseShared
312 ? Find(RootDir, StartSubDir +
"/pic",
"/initS.o")
313 : Find(RootDir, StartSubDir,
"/init.o");
314 CmdArgs.push_back(Args.MakeArgString(Init));
321 for (
const auto &LibPath : LibPaths)
322 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
327 Args.AddAllArgs(CmdArgs,
328 {options::OPT_T_Group, options::OPT_e, options::OPT_s,
329 options::OPT_t, options::OPT_u_Group});
336 if (IncStdLib && IncDefLibs) {
340 CmdArgs.push_back(
"-lm");
343 CmdArgs.push_back(
"--start-group");
346 for (StringRef Lib : OsLibs)
347 CmdArgs.push_back(Args.MakeArgString(
"-l" + Lib));
348 CmdArgs.push_back(
"-lc");
350 CmdArgs.push_back(
"-lgcc");
352 CmdArgs.push_back(
"--end-group");
358 if (IncStdLib && IncStartFiles) {
359 std::string Fini = UseShared
360 ? Find(RootDir, StartSubDir +
"/pic",
"/finiS.o")
361 : Find(RootDir, StartSubDir,
"/fini.o");
362 CmdArgs.push_back(Args.MakeArgString(Fini));
370 const char *LinkingOutput)
const {
373 ArgStringList CmdArgs;
377 const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
378 C.
addCommand(std::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
384 std::string HexagonToolChain::getHexagonTargetDir(
385 const std::string &InstalledDir,
387 std::string InstallRelDir;
388 const Driver &D = getDriver();
391 for (
auto &I : PrefixDirs)
395 if (getVFS().exists(InstallRelDir = InstalledDir +
"/../target"))
396 return InstallRelDir;
402 const ArgList &Args) {
404 if (Arg *A = Args.getLastArg(options::OPT_G)) {
406 }
else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
407 options::OPT_fPIC)) {
412 if (!Gn.getAsInteger(10, G))
418 void HexagonToolChain::getHexagonLibraryPaths(
const ArgList &Args,
420 const Driver &D = getDriver();
425 for (Arg *A : Args.filtered(options::OPT_L))
426 for (
const char *
Value : A->getValues())
427 LibPaths.push_back(
Value);
432 std::vector<std::string> RootDirs;
434 std::back_inserter(RootDirs));
438 if (llvm::find(RootDirs, TargetDir) == RootDirs.end())
439 RootDirs.push_back(TargetDir);
441 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
443 bool HasG0 = Args.hasArg(options::OPT_shared);
444 if (
auto G = getSmallDataThreshold(Args))
445 HasG0 = G.getValue() == 0;
447 const std::string CpuVer = GetTargetCPUVersion(Args).str();
448 for (
auto &Dir : RootDirs) {
449 std::string LibDir = Dir +
"/hexagon/lib";
450 std::string LibDirCpu = LibDir +
'/' + CpuVer;
453 LibPaths.push_back(LibDirCpu +
"/G0/pic");
454 LibPaths.push_back(LibDirCpu +
"/G0");
456 LibPaths.push_back(LibDirCpu);
457 LibPaths.push_back(LibDir);
461 HexagonToolChain::HexagonToolChain(
const Driver &D,
const llvm::Triple &Triple,
462 const llvm::opt::ArgList &Args)
463 :
Linux(D, Triple, Args) {
469 const std::string BinDir(TargetDir +
"/bin");
470 if (D.
getVFS().exists(BinDir))
493 const llvm::opt::ArgList &DriverArgs)
const {
495 Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
499 if (A->getOption().matches(options::OPT_O0))
501 if (A->getOption().matches(options::OPT_Ofast) ||
502 A->getOption().matches(options::OPT_O4))
504 assert(A->getNumValues() != 0);
505 StringRef S(A->getValue());
506 if (S ==
"s" || S ==
"z" || S.empty())
512 if (S.getAsInteger(10, OptLevel))
518 ArgStringList &CC1Args,
520 if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
521 CC1Args.push_back(
"-target-feature");
522 CC1Args.push_back(
"+reserved-r19");
525 CC1Args.push_back(
"-mllvm");
526 CC1Args.push_back(
"-hexagon-autohvx");
531 ArgStringList &CC1Args)
const {
532 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
533 DriverArgs.hasArg(options::OPT_nostdlibinc))
544 const llvm::opt::ArgList &DriverArgs,
545 llvm::opt::ArgStringList &CC1Args)
const {
549 DriverArgs, CC1Args);
554 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
558 StringRef
Value = A->getValue();
559 if (Value !=
"libstdc++")
560 getDriver().
Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
566 if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
567 options::OPT_fno_vectorize))
568 return A->getOption().matches(options::OPT_fvectorize);
581 Arg *CpuArg =
nullptr;
582 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
585 StringRef CPU = CpuArg ? CpuArg->getValue() :
GetDefaultCPU();
586 if (CPU.startswith(
"hexagon"))
587 return CPU.substr(
sizeof(
"hexagon") - 1);
DiagnosticBuilder Diag(unsigned DiagID) const
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
llvm::vfs::FileSystem & getVFS() const
void addCommand(std::unique_ptr< Command > C)
std::string InstalledDir
The path to the installed clang directory, if any.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Dataflow Directional Tag Classes.
const char * getInstalledDir() const
Get the path to where the clang executable was installed.
Compilation - A set of tasks to perform for a single driver invocation.
bool isLLVMIR(ID Id)
Is this LLVM IR.