[Flang][Driver] Handle target CPU and features
This patch:
- Adds target-feature and target-cpu to FC1Options.
- Moves getTargetFeatures() from Clang.cpp to CommonArgs.cpp.
- Processes target cpu and features in the flang driver. Right now
features are only added for AArch64/x86 because I only did basic
testing on them but it should generally work for others as well.
Option handling is similar to clang.
- Adds appropriate structures in TargetOptions and passes them to
the target machine.
What's missing:
- Adding the CPU info and the features as attributes in the LLVM IR
module.
- Processing target specific flags, e.g. SVE vector bits for AArch64,
ABI etc.
Differential Revision: https://reviews.llvm.org/D137995
Change-Id: Ib081a74ea98617674845518a5d2754edba596418
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index d8ece4e..1613098 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -292,98 +292,6 @@
}
}
-static void getWebAssemblyTargetFeatures(const ArgList &Args,
- std::vector<StringRef> &Features) {
- handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group);
-}
-
-static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args, ArgStringList &CmdArgs,
- bool ForAS, bool IsAux = false) {
- std::vector<StringRef> Features;
- switch (Triple.getArch()) {
- default:
- break;
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- mips::getMIPSTargetFeatures(D, Triple, Args, Features);
- break;
-
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- arm::getARMTargetFeatures(D, Triple, Args, Features, ForAS);
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppcle:
- case llvm::Triple::ppc64:
- case llvm::Triple::ppc64le:
- ppc::getPPCTargetFeatures(D, Triple, Args, Features);
- break;
- case llvm::Triple::riscv32:
- case llvm::Triple::riscv64:
- riscv::getRISCVTargetFeatures(D, Triple, Args, Features);
- break;
- case llvm::Triple::systemz:
- systemz::getSystemZTargetFeatures(D, Args, Features);
- break;
- case llvm::Triple::aarch64:
- case llvm::Triple::aarch64_32:
- case llvm::Triple::aarch64_be:
- aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, ForAS);
- break;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- x86::getX86TargetFeatures(D, Triple, Args, Features);
- break;
- case llvm::Triple::hexagon:
- hexagon::getHexagonTargetFeatures(D, Args, Features);
- break;
- case llvm::Triple::wasm32:
- case llvm::Triple::wasm64:
- getWebAssemblyTargetFeatures(Args, Features);
- break;
- case llvm::Triple::sparc:
- case llvm::Triple::sparcel:
- case llvm::Triple::sparcv9:
- sparc::getSparcTargetFeatures(D, Args, Features);
- break;
- case llvm::Triple::r600:
- case llvm::Triple::amdgcn:
- amdgpu::getAMDGPUTargetFeatures(D, Triple, Args, Features);
- break;
- case llvm::Triple::nvptx:
- case llvm::Triple::nvptx64:
- NVPTX::getNVPTXTargetFeatures(D, Triple, Args, Features);
- break;
- case llvm::Triple::m68k:
- m68k::getM68kTargetFeatures(D, Triple, Args, Features);
- break;
- case llvm::Triple::msp430:
- msp430::getMSP430TargetFeatures(D, Args, Features);
- break;
- case llvm::Triple::ve:
- ve::getVETargetFeatures(D, Args, Features);
- break;
- case llvm::Triple::csky:
- csky::getCSKYTargetFeatures(D, Triple, Args, CmdArgs, Features);
- break;
- case llvm::Triple::loongarch32:
- case llvm::Triple::loongarch64:
- loongarch::getLoongArchTargetFeatures(D, Triple, Args, Features);
- break;
- }
-
- for (auto Feature : unifyTargetFeatures(Features)) {
- CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature");
- CmdArgs.push_back(Feature.data());
- }
-}
-
static bool
shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
const llvm::Triple &Triple) {
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index cbdb51f..47f0973 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -9,6 +9,8 @@
#include "CommonArgs.h"
#include "Arch/AArch64.h"
#include "Arch/ARM.h"
+#include "Arch/CSKY.h"
+#include "Arch/LoongArch.h"
#include "Arch/M68k.h"
#include "Arch/Mips.h"
#include "Arch/PPC.h"
@@ -19,6 +21,7 @@
#include "Arch/X86.h"
#include "HIPAMD.h"
#include "Hexagon.h"
+#include "MSP430.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/ObjCRuntime.h"
@@ -470,6 +473,96 @@
}
}
+static void getWebAssemblyTargetFeatures(const ArgList &Args,
+ std::vector<StringRef> &Features) {
+ handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group);
+}
+
+void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args, ArgStringList &CmdArgs,
+ bool ForAS, bool IsAux) {
+ std::vector<StringRef> Features;
+ switch (Triple.getArch()) {
+ default:
+ break;
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ mips::getMIPSTargetFeatures(D, Triple, Args, Features);
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ arm::getARMTargetFeatures(D, Triple, Args, Features, ForAS);
+ break;
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppcle:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ ppc::getPPCTargetFeatures(D, Triple, Args, Features);
+ break;
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ riscv::getRISCVTargetFeatures(D, Triple, Args, Features);
+ break;
+ case llvm::Triple::systemz:
+ systemz::getSystemZTargetFeatures(D, Args, Features);
+ break;
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
+ case llvm::Triple::aarch64_be:
+ aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, ForAS);
+ break;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ x86::getX86TargetFeatures(D, Triple, Args, Features);
+ break;
+ case llvm::Triple::hexagon:
+ hexagon::getHexagonTargetFeatures(D, Args, Features);
+ break;
+ case llvm::Triple::wasm32:
+ case llvm::Triple::wasm64:
+ getWebAssemblyTargetFeatures(Args, Features);
+ break;
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcel:
+ case llvm::Triple::sparcv9:
+ sparc::getSparcTargetFeatures(D, Args, Features);
+ break;
+ case llvm::Triple::r600:
+ case llvm::Triple::amdgcn:
+ amdgpu::getAMDGPUTargetFeatures(D, Triple, Args, Features);
+ break;
+ case llvm::Triple::nvptx:
+ case llvm::Triple::nvptx64:
+ NVPTX::getNVPTXTargetFeatures(D, Triple, Args, Features);
+ break;
+ case llvm::Triple::m68k:
+ m68k::getM68kTargetFeatures(D, Triple, Args, Features);
+ break;
+ case llvm::Triple::msp430:
+ msp430::getMSP430TargetFeatures(D, Args, Features);
+ break;
+ case llvm::Triple::ve:
+ ve::getVETargetFeatures(D, Args, Features);
+ break;
+ case llvm::Triple::csky:
+ csky::getCSKYTargetFeatures(D, Triple, Args, CmdArgs, Features);
+ break;
+ case llvm::Triple::loongarch32:
+ case llvm::Triple::loongarch64:
+ loongarch::getLoongArchTargetFeatures(D, Triple, Args, Features);
+ break;
+ }
+
+ for (auto Feature : unifyTargetFeatures(Features)) {
+ CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature");
+ CmdArgs.push_back(Feature.data());
+ }
+}
+
llvm::StringRef tools::getLTOParallelism(const ArgList &Args, const Driver &D) {
Arg *LtoJobsArg = Args.getLastArg(options::OPT_flto_jobs_EQ);
if (!LtoJobsArg)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 1d2284e..d44d921 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -174,6 +174,11 @@
std::string getCPUName(const Driver &D, const llvm::opt::ArgList &Args,
const llvm::Triple &T, bool FromAs = false);
+void getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs, bool ForAS,
+ bool IsAux = false);
+
/// Iterate \p Args and convert -mxxx to +xxx and -mno-xxx to -xxx and
/// append it to \p Features.
///
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 588fabd..b2b08f9 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -80,6 +80,32 @@
}
}
+void Flang::addTargetOptions(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ const ToolChain &TC = getToolChain();
+ const llvm::Triple &Triple = TC.getEffectiveTriple();
+ const Driver &D = TC.getDriver();
+
+ std::string CPU = getCPUName(D, Args, Triple);
+ if (!CPU.empty()) {
+ CmdArgs.push_back("-target-cpu");
+ CmdArgs.push_back(Args.MakeArgString(CPU));
+ }
+
+ // Add the target features.
+ switch (TC.getArch()) {
+ default:
+ break;
+ case llvm::Triple::aarch64:
+ [[fallthrough]];
+ case llvm::Triple::x86_64:
+ getTargetFeatures(D, Triple, Args, CmdArgs, /*ForAs*/ false);
+ break;
+ }
+
+ // TODO: Add target specific flags, ABI, mtune option etc.
+}
+
static void addFloatingPointOptions(const Driver &D, const ArgList &Args,
ArgStringList &CmdArgs) {
StringRef FPContract;
@@ -243,6 +269,9 @@
// Floating point related options
addFloatingPointOptions(D, Args, CmdArgs);
+ // Add target args, features, etc.
+ addTargetOptions(Args, CmdArgs);
+
// Add other compile options
addOtherOptions(Args, CmdArgs);
diff --git a/clang/lib/Driver/ToolChains/Flang.h b/clang/lib/Driver/ToolChains/Flang.h
index de72ac3..4c85c60 100644
--- a/clang/lib/Driver/ToolChains/Flang.h
+++ b/clang/lib/Driver/ToolChains/Flang.h
@@ -48,6 +48,14 @@
void addPicOptions(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
+ /// Extract target options from the driver arguments and add them to
+ /// the command arguments.
+ ///
+ /// \param [in] Args The list of input driver arguments
+ /// \param [out] CmdArgs The list of output command arguments
+ void addTargetOptions(const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs) const;
+
/// Extract other compilation options from the driver arguments and add them
/// to the command arguments.
///