18 #include "llvm/ADT/StringExtras.h" 19 #include "llvm/Option/ArgList.h" 20 #include "llvm/Support/FileSystem.h" 21 #include "llvm/Support/Path.h" 26 using namespace clang;
31 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(
"-march=hexagon");
135 RenderExtraToolArgs(JA, CmdArgs);
137 const char *AsName =
"hexagon-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(llvm::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);
212 bool UseShared = IsShared && !IsStatic;
217 Args.ClaimAllArgs(options::OPT_g_Group);
218 Args.ClaimAllArgs(options::OPT_emit_llvm);
219 Args.ClaimAllArgs(options::OPT_w);
221 Args.ClaimAllArgs(options::OPT_static_libgcc);
226 if (Args.hasArg(options::OPT_s))
227 CmdArgs.push_back(
"-s");
229 if (Args.hasArg(options::OPT_r))
230 CmdArgs.push_back(
"-r");
233 CmdArgs.push_back(Opt.c_str());
235 CmdArgs.push_back(
"-march=hexagon");
237 CmdArgs.push_back(Args.MakeArgString(
"-mcpu=hexagon" + CpuVer));
240 CmdArgs.push_back(
"-shared");
242 CmdArgs.push_back(
"-call_shared");
246 CmdArgs.push_back(
"-static");
248 if (IsPIE && !IsShared)
249 CmdArgs.push_back(
"-pie");
252 CmdArgs.push_back(Args.MakeArgString(
"-G" + Twine(G.getValue())));
253 UseG0 = G.getValue() == 0;
259 CmdArgs.push_back(
"-o");
265 std::vector<std::string> OsLibs;
266 bool HasStandalone =
false;
268 for (
const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
270 OsLibs.emplace_back(A->getValue());
271 HasStandalone = HasStandalone || (OsLibs.back() ==
"standalone");
273 if (OsLibs.empty()) {
274 OsLibs.push_back(
"standalone");
275 HasStandalone =
true;
281 const std::string MCpuSuffix =
"/" + CpuVer.str();
282 const std::string MCpuG0Suffix = MCpuSuffix +
"/G0";
283 const std::string RootDir =
285 const std::string StartSubDir =
286 "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
288 auto Find = [&HTC] (
const std::string &RootDir,
const std::string &SubDir,
289 const char *Name) -> std::string {
290 std::string RelName = SubDir + Name;
292 if (llvm::sys::fs::exists(P))
294 return RootDir + RelName;
297 if (IncStdLib && IncStartFiles) {
300 std::string Crt0SA = Find(RootDir, StartSubDir,
"/crt0_standalone.o");
301 CmdArgs.push_back(Args.MakeArgString(Crt0SA));
303 std::string Crt0 = Find(RootDir, StartSubDir,
"/crt0.o");
304 CmdArgs.push_back(Args.MakeArgString(Crt0));
306 std::string Init = UseShared
307 ? Find(RootDir, StartSubDir +
"/pic",
"/initS.o")
308 : Find(RootDir, StartSubDir,
"/init.o");
309 CmdArgs.push_back(Args.MakeArgString(Init));
316 for (
const auto &LibPath : LibPaths)
317 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
322 Args.AddAllArgs(CmdArgs,
323 {options::OPT_T_Group, options::OPT_e, options::OPT_s,
324 options::OPT_t, options::OPT_u_Group});
331 if (IncStdLib && IncDefLibs) {
335 CmdArgs.push_back(
"-lm");
338 CmdArgs.push_back(
"--start-group");
341 for (StringRef Lib : OsLibs)
342 CmdArgs.push_back(Args.MakeArgString(
"-l" + Lib));
343 CmdArgs.push_back(
"-lc");
345 CmdArgs.push_back(
"-lgcc");
347 CmdArgs.push_back(
"--end-group");
353 if (IncStdLib && IncStartFiles) {
354 std::string Fini = UseShared
355 ? Find(RootDir, StartSubDir +
"/pic",
"/finiS.o")
356 : Find(RootDir, StartSubDir,
"/fini.o");
357 CmdArgs.push_back(Args.MakeArgString(Fini));
365 const char *LinkingOutput)
const {
368 ArgStringList CmdArgs;
372 std::string
Linker = HTC.GetProgramPath(
"hexagon-link");
373 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Args.MakeArgString(Linker),
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");
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_ffp_contract)) {
519 CC1Args.push_back(
"-ffp-contract=fast");
521 if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
522 CC1Args.push_back(
"-target-feature");
523 CC1Args.push_back(
"+reserved-r19");
526 CC1Args.push_back(
"-mllvm");
527 CC1Args.push_back(
"-hexagon-autohvx");
532 ArgStringList &CC1Args)
const {
533 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
534 DriverArgs.hasArg(options::OPT_nostdlibinc))
545 const llvm::opt::ArgList &DriverArgs,
546 llvm::opt::ArgStringList &CC1Args)
const {
550 DriverArgs, CC1Args);
555 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
559 StringRef
Value = A->getValue();
560 if (Value !=
"libstdc++")
561 getDriver().
Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
567 if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
568 options::OPT_fno_vectorize))
569 return A->getOption().matches(options::OPT_fvectorize);
582 Arg *CpuArg =
nullptr;
583 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
586 StringRef CPU = CpuArg ? CpuArg->getValue() :
GetDefaultCPU();
587 if (CPU.startswith(
"hexagon"))
588 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...
void addCommand(std::unique_ptr< Command > C)
vfs::FileSystem & getVFS() const
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.
Defines the virtual file system interface vfs::FileSystem.
const char * getInstalledDir() const
Get the path to where the clang executable was installed.
bool exists(const Twine &Path)
Check whether a file exists. Provided for convenience.
Compilation - A set of tasks to perform for a single driver invocation.
bool isLLVMIR(ID Id)
Is this LLVM IR.