17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/Option/ArgList.h" 19 #include "llvm/Support/FileSystem.h" 20 #include "llvm/Support/Path.h" 21 #include "llvm/Support/VirtualFileSystem.h" 26 using namespace clang;
31 return llvm::StringSwitch<StringRef>(Cpu)
41 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
42 StringRef Val = A->getValue();
43 if (!Val.equals_lower(
"64b") && !Val.equals_lower(
"128b"))
44 D.
Diag(diag::err_drv_unsupported_option_argument)
45 << A->getOption().getName() << Val;
51 std::vector<StringRef> &Features,
57 StringRef HVXFeature, HVXLength;
61 if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx,
62 options::OPT_mhexagon_hvx,
63 options::OPT_mhexagon_hvx_EQ)) {
64 if (A->getOption().matches(options::OPT_mno_hexagon_hvx))
66 if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ)) {
68 HVXFeature = Cpu = A->getValue();
69 HVXFeature = Args.MakeArgString(llvm::Twine(
"+hvx") + HVXFeature.lower());
70 }
else if (A->getOption().matches(options::OPT_mhexagon_hvx)) {
72 HVXFeature = Args.MakeArgString(llvm::Twine(
"+hvx") + Cpu);
74 Features.push_back(HVXFeature);
78 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
81 D.
Diag(diag::err_drv_invalid_hvx_length);
82 else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ))
83 HVXLength = A->getValue();
89 if (!HVXLength.empty()) {
91 Args.MakeArgString(llvm::Twine(
"+hvx-length") + HVXLength.lower());
92 Features.push_back(HVXFeature);
98 std::vector<StringRef> &Features) {
100 options::OPT_m_hexagon_Features_Group);
102 bool UseLongCalls =
false;
103 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
104 options::OPT_mno_long_calls)) {
105 if (A->getOption().matches(options::OPT_mlong_calls))
109 Features.push_back(UseLongCalls ?
"+long-calls" :
"-long-calls");
114 if (HexagonToolChain::isAutoHVXEnabled(Args) && !HasHVX)
115 D.
Diag(diag::warn_drv_vectorize_needs_hvx);
120 ArgStringList &CmdArgs)
const {
127 const char *LinkingOutput)
const {
131 const Driver &D = HTC.getDriver();
132 ArgStringList CmdArgs;
134 CmdArgs.push_back(
"-march=hexagon");
136 RenderExtraToolArgs(JA, CmdArgs);
138 const char *AsName =
"hexagon-llvm-mc";
139 CmdArgs.push_back(
"-filetype=obj");
140 CmdArgs.push_back(Args.MakeArgString(
145 CmdArgs.push_back(
"-o");
148 assert(Output.
isNothing() &&
"Unexpected output");
149 CmdArgs.push_back(
"-fsyntax-only");
153 CmdArgs.push_back(Args.MakeArgString(
"-gpsize=" + Twine(G.getValue())));
156 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
166 for (
const auto &II : Inputs) {
169 D.
Diag(clang::diag::err_drv_no_linker_llvm_support)
170 << HTC.getTripleString();
171 else if (II.getType() == types::TY_AST)
172 D.
Diag(clang::diag::err_drv_no_ast_support)
173 << HTC.getTripleString();
174 else if (II.getType() == types::TY_ModuleFile)
175 D.
Diag(diag::err_drv_no_module_support)
176 << HTC.getTripleString();
179 CmdArgs.push_back(II.getFilename());
183 II.getInputArg().render(Args, CmdArgs);
186 auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
187 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
191 ArgStringList &CmdArgs)
const {
198 const ArgList &Args, ArgStringList &CmdArgs,
199 const char *LinkingOutput) {
206 bool IsStatic = Args.hasArg(options::OPT_static);
207 bool IsShared = Args.hasArg(options::OPT_shared);
208 bool IsPIE = Args.hasArg(options::OPT_pie);
209 bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
210 bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
211 bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
213 bool UseShared = IsShared && !
IsStatic;
218 Args.ClaimAllArgs(options::OPT_g_Group);
219 Args.ClaimAllArgs(options::OPT_emit_llvm);
220 Args.ClaimAllArgs(options::OPT_w);
222 Args.ClaimAllArgs(options::OPT_static_libgcc);
227 if (Args.hasArg(options::OPT_s))
228 CmdArgs.push_back(
"-s");
230 if (Args.hasArg(options::OPT_r))
231 CmdArgs.push_back(
"-r");
234 CmdArgs.push_back(Opt.c_str());
236 CmdArgs.push_back(
"-march=hexagon");
238 CmdArgs.push_back(Args.MakeArgString(
"-mcpu=hexagon" + CpuVer));
241 CmdArgs.push_back(
"-shared");
243 CmdArgs.push_back(
"-call_shared");
247 CmdArgs.push_back(
"-static");
249 if (IsPIE && !IsShared)
250 CmdArgs.push_back(
"-pie");
253 CmdArgs.push_back(Args.MakeArgString(
"-G" + Twine(G.getValue())));
254 UseG0 = G.getValue() == 0;
260 CmdArgs.push_back(
"-o");
266 std::vector<std::string> OsLibs;
267 bool HasStandalone =
false;
269 for (
const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
271 OsLibs.emplace_back(A->getValue());
272 HasStandalone = HasStandalone || (OsLibs.back() ==
"standalone");
274 if (OsLibs.empty()) {
275 OsLibs.push_back(
"standalone");
276 HasStandalone =
true;
282 const std::string MCpuSuffix =
"/" + CpuVer.str();
283 const std::string MCpuG0Suffix = MCpuSuffix +
"/G0";
284 const std::string RootDir =
286 const std::string StartSubDir =
287 "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
289 auto Find = [&HTC] (
const std::string &RootDir,
const std::string &SubDir,
290 const char *Name) -> std::string {
291 std::string RelName = SubDir + Name;
293 if (llvm::sys::fs::exists(P))
295 return RootDir + RelName;
298 if (IncStdLib && IncStartFiles) {
301 std::string Crt0SA = Find(RootDir, StartSubDir,
"/crt0_standalone.o");
302 CmdArgs.push_back(Args.MakeArgString(Crt0SA));
304 std::string Crt0 = Find(RootDir, StartSubDir,
"/crt0.o");
305 CmdArgs.push_back(Args.MakeArgString(Crt0));
307 std::string Init = UseShared
308 ? Find(RootDir, StartSubDir +
"/pic",
"/initS.o")
309 : Find(RootDir, StartSubDir,
"/init.o");
310 CmdArgs.push_back(Args.MakeArgString(Init));
317 for (
const auto &LibPath : LibPaths)
318 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
323 Args.AddAllArgs(CmdArgs,
324 {options::OPT_T_Group, options::OPT_e, options::OPT_s,
325 options::OPT_t, options::OPT_u_Group});
332 if (IncStdLib && IncDefLibs) {
336 CmdArgs.push_back(
"-lm");
339 CmdArgs.push_back(
"--start-group");
342 for (StringRef Lib : OsLibs)
343 CmdArgs.push_back(Args.MakeArgString(
"-l" + Lib));
344 CmdArgs.push_back(
"-lc");
346 CmdArgs.push_back(
"-lgcc");
348 CmdArgs.push_back(
"--end-group");
354 if (IncStdLib && IncStartFiles) {
355 std::string Fini = UseShared
356 ? Find(RootDir, StartSubDir +
"/pic",
"/finiS.o")
357 : Find(RootDir, StartSubDir,
"/fini.o");
358 CmdArgs.push_back(Args.MakeArgString(Fini));
366 const char *LinkingOutput)
const {
369 ArgStringList CmdArgs;
373 const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
374 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
380 std::string HexagonToolChain::getHexagonTargetDir(
381 const std::string &InstalledDir,
383 std::string InstallRelDir;
384 const Driver &D = getDriver();
387 for (
auto &I : PrefixDirs)
391 if (getVFS().exists(InstallRelDir = InstalledDir +
"/../target"))
392 return InstallRelDir;
398 const ArgList &Args) {
400 if (Arg *A = Args.getLastArg(options::OPT_G)) {
402 }
else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
403 options::OPT_fPIC)) {
408 if (!Gn.getAsInteger(10, G))
414 void HexagonToolChain::getHexagonLibraryPaths(
const ArgList &Args,
416 const Driver &D = getDriver();
421 for (Arg *A : Args.filtered(options::OPT_L))
422 for (
const char *
Value : A->getValues())
423 LibPaths.push_back(
Value);
428 std::vector<std::string> RootDirs;
430 std::back_inserter(RootDirs));
434 if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
435 RootDirs.push_back(TargetDir);
437 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
439 bool HasG0 = Args.hasArg(options::OPT_shared);
440 if (
auto G = getSmallDataThreshold(Args))
441 HasG0 = G.getValue() == 0;
443 const std::string CpuVer = GetTargetCPUVersion(Args).str();
444 for (
auto &Dir : RootDirs) {
445 std::string LibDir = Dir +
"/hexagon/lib";
446 std::string LibDirCpu = LibDir +
'/' + CpuVer;
449 LibPaths.push_back(LibDirCpu +
"/G0/pic");
450 LibPaths.push_back(LibDirCpu +
"/G0");
452 LibPaths.push_back(LibDirCpu);
453 LibPaths.push_back(LibDir);
457 HexagonToolChain::HexagonToolChain(
const Driver &D,
const llvm::Triple &Triple,
458 const llvm::opt::ArgList &Args)
459 :
Linux(D, Triple, Args) {
465 const std::string BinDir(TargetDir +
"/bin");
466 if (D.
getVFS().exists(BinDir))
489 const llvm::opt::ArgList &DriverArgs)
const {
491 Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
495 if (A->getOption().matches(options::OPT_O0))
497 if (A->getOption().matches(options::OPT_Ofast) ||
498 A->getOption().matches(options::OPT_O4))
500 assert(A->getNumValues() != 0);
501 StringRef S(A->getValue());
502 if (S ==
"s" || S ==
"z" || S.empty())
508 if (S.getAsInteger(10, OptLevel))
514 ArgStringList &CC1Args,
516 if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
517 CC1Args.push_back(
"-target-feature");
518 CC1Args.push_back(
"+reserved-r19");
521 CC1Args.push_back(
"-mllvm");
522 CC1Args.push_back(
"-hexagon-autohvx");
527 ArgStringList &CC1Args)
const {
528 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
529 DriverArgs.hasArg(options::OPT_nostdlibinc))
540 const llvm::opt::ArgList &DriverArgs,
541 llvm::opt::ArgStringList &CC1Args)
const {
545 DriverArgs, CC1Args);
550 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
554 StringRef
Value = A->getValue();
555 if (Value !=
"libstdc++")
556 getDriver().
Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
562 if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
563 options::OPT_fno_vectorize))
564 return A->getOption().matches(options::OPT_fvectorize);
577 Arg *CpuArg =
nullptr;
578 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
581 StringRef CPU = CpuArg ? CpuArg->getValue() :
GetDefaultCPU();
582 if (CPU.startswith(
"hexagon"))
583 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.