michaelplatings updated this revision to Diff 529013.
michaelplatings added a comment.
Rebase
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D142933/new/
https://reviews.llvm.org/D142933
Files:
clang/include/clang/Driver/Options.td
clang/include/clang/Driver/ToolChain.h
clang/lib/Driver/Driver.cpp
clang/lib/Driver/ToolChain.cpp
clang/lib/Driver/ToolChains/Arch/ARM.cpp
clang/lib/Driver/ToolChains/Arch/ARM.h
clang/test/Driver/print-multi-selection-flags.c
Index: clang/test/Driver/print-multi-selection-flags.c
===================================================================
--- /dev/null
+++ clang/test/Driver/print-multi-selection-flags.c
@@ -0,0 +1,51 @@
+// RUN: %clang -print-multi-selection-flags-experimental --target=aarch64-linux -fc++-abi=itanium -fsanitize=address | FileCheck --check-prefix=CHECK-LINUX %s
+// CHECK-LINUX: --target=aarch64-unknown-linux
+// CHECK-LINUX: -fc++-abi=itanium
+// CHECK-LINUX: -fexceptions
+// CHECK-LINUX: -frtti
+// CHECK-LINUX: -fsanitize=address
+
+// RUN: %clang -print-multi-selection-flags-experimental --target=aarch64-fuchsia -fsanitize=hwaddress | FileCheck --check-prefix=CHECK-FUCHSIA %s
+// CHECK-FUCHSIA: --target=aarch64-unknown-fuchsia
+// CHECK-FUCHSIA: -fsanitize=hwaddress
+
+// RUN: %clang -print-multi-selection-flags-experimental --target=arm-none-eabi -mfloat-abi=soft -fno-exceptions -fno-rtti | FileCheck --check-prefix=CHECK-ARMV4T %s
+// CHECK-ARMV4T: --target=armv4t-none-unknown-eabi
+// CHECK-ARMV4T: -fno-exceptions
+// CHECK-ARMV4T: -fno-rtti
+// CHECK-ARMV4T: -mfloat-abi=soft
+// CHECK-ARMV4T: -mfpu=none
+
+// RUN: %clang -print-multi-selection-flags-experimental --target=armv7em-none-eabi -mfloat-abi=softfp | FileCheck --check-prefix=CHECK-SOFTFP %s
+// CHECK-SOFTFP: --target=thumbv7em-none-unknown-eabi
+// CHECK-SOFTFP: -mfloat-abi=softfp
+// CHECK-SOFTFP: -mfpu=fpv4-sp-d16
+
+// RUN: %clang -print-multi-selection-flags-experimental --target=arm-none-eabihf -march=armv7em -mfpu=fpv5-d16 | FileCheck --check-prefix=CHECK-HARD %s
+// CHECK-HARD: --target=thumbv7em-none-unknown-eabihf
+// CHECK-HARD: -mfloat-abi=hard
+// CHECK-HARD: -mfpu=fpv5-d16
+
+// RUN: %clang -print-multi-selection-flags-experimental --target=arm-none-eabi -mfloat-abi=soft -march=armv8-m.main+nofp | FileCheck --check-prefix=CHECK-V8MMAIN-NOFP %s
+// CHECK-V8MMAIN-NOFP: --target=thumbv8m.main-none-unknown-eabi
+// CHECK-V8MMAIN-NOFP: -mfloat-abi=soft
+// CHECK-V8MMAIN-NOFP: -mfpu=none
+
+// RUN: %clang -print-multi-selection-flags-experimental --target=arm-none-eabi -mfloat-abi=hard -march=armv8.1m.main+mve.fp | FileCheck --check-prefix=CHECK-MVE %s
+// CHECK-MVE: --target=thumbv8.1m.main-none-unknown-eabihf
+// CHECK-MVE: -march=thumbv8.1m.main{{.*}}+mve{{.*}}+mve.fp{{.*}}
+// CHECK-MVE: -mfloat-abi=hard
+// CHECK-MVE: -mfpu=fp-armv8-fullfp16-sp-d16
+
+// RUN: %clang -print-multi-selection-flags-experimental --target=arm-none-eabi -march=armv8.1m.main+mve+nofp | FileCheck --check-prefix=CHECK-MVENOFP %s
+// CHECK-MVENOFP: -march=thumbv8.1m.main{{.*}}+mve{{.*}}
+// CHECK-MVENOFP-NOT: -march=thumbv8.1m.main{{.*}}+mve.fp{{.*}}
+// CHECK-MVENOFP: -mfpu=none
+
+// RUN: %clang -print-multi-selection-flags-experimental --target=aarch64-none-elf -march=armv8-a+lse | FileCheck --check-prefix=CHECK-LSE %s
+// CHECK-LSE: -march=aarch64{{.*}}+lse{{.*}}
+
+// RUN: %clang -print-multi-selection-flags-experimental --target=aarch64-none-elf -march=armv8.5-a+sve+sve2 | FileCheck --check-prefix=CHECK-SVE2 %s
+// RUN: %clang -print-multi-selection-flags-experimental --target=aarch64-none-elf -march=armv9-a | FileCheck --check-prefix=CHECK-SVE2 %s
+// CHECK-SVE2: --target=aarch64-none-unknown-elf
+// CHECK-SVE2: -march=aarch64{{.*}}+simd{{.*}}+sve{{.*}}+sve2{{.*}}
Index: clang/lib/Driver/ToolChains/Arch/ARM.h
===================================================================
--- clang/lib/Driver/ToolChains/Arch/ARM.h
+++ clang/lib/Driver/ToolChains/Arch/ARM.h
@@ -63,9 +63,11 @@
void getARMArchCPUFromArgs(const llvm::opt::ArgList &Args,
llvm::StringRef &Arch, llvm::StringRef &CPU,
bool FromAs = false);
-void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
- const llvm::opt::ArgList &Args,
- std::vector<llvm::StringRef> &Features, bool ForAS);
+llvm::ARM::FPUKind getARMTargetFeatures(const Driver &D,
+ const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
+ std::vector<llvm::StringRef> &Features,
+ bool ForAS);
int getARMSubArchVersionNumber(const llvm::Triple &Triple);
bool isARMMProfile(const llvm::Triple &Triple);
bool isARMAProfile(const llvm::Triple &Triple);
Index: clang/lib/Driver/ToolChains/Arch/ARM.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -463,9 +463,11 @@
(NoMVE == F.rend() || std::distance(MVE, NoMVE) > 0);
}
-void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args,
- std::vector<StringRef> &Features, bool ForAS) {
+llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D,
+ const llvm::Triple &Triple,
+ const ArgList &Args,
+ std::vector<StringRef> &Features,
+ bool ForAS) {
bool KernelOrKext =
Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
arm::FloatABI ABI = arm::getARMFloatABI(D, Triple, Args);
@@ -661,6 +663,7 @@
Features.insert(Features.end(),
{"-dotprod", "-fp16fml", "-bf16", "-mve", "-mve.fp"});
HasFPRegs = false;
+ FPUKind = llvm::ARM::FK_NONE;
} else if (FPUKind == llvm::ARM::FK_NONE ||
ArchArgFPUKind == llvm::ARM::FK_NONE ||
CPUArgFPUKind == llvm::ARM::FK_NONE) {
@@ -671,6 +674,7 @@
Features.insert(Features.end(),
{"-dotprod", "-fp16fml", "-bf16", "-mve.fp"});
HasFPRegs = hasIntegerMVE(Features);
+ FPUKind = llvm::ARM::FK_NONE;
}
if (!HasFPRegs)
Features.emplace_back("-fpregs");
@@ -931,6 +935,8 @@
Features.push_back("+no-bti-at-return-twice");
checkARMFloatABI(D, Args, HasFPRegs);
+
+ return FPUKind;
}
std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {
Index: clang/lib/Driver/ToolChain.cpp
===================================================================
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -7,8 +7,10 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/ToolChain.h"
+#include "ToolChains/Arch/AArch64.h"
#include "ToolChains/Arch/ARM.h"
#include "ToolChains/Clang.h"
+#include "ToolChains/CommonArgs.h"
#include "ToolChains/Flang.h"
#include "ToolChains/InterfaceStubs.h"
#include "clang/Basic/ObjCRuntime.h"
@@ -39,6 +41,7 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/TargetParser/AArch64TargetParser.h"
#include "llvm/TargetParser/TargetParser.h"
#include "llvm/TargetParser/Triple.h"
#include <cassert>
@@ -171,6 +174,138 @@
return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux();
}
+static void getAArch64MultiSelectionFlags(const Driver &D,
+ const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
+ Multilib::flags_list &Result) {
+ std::vector<StringRef> Features;
+ tools::aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, false);
+ const auto UnifiedFeatures = tools::unifyTargetFeatures(Features);
+ llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
+ UnifiedFeatures.end());
+ std::vector<std::string> MArch;
+ for (const auto &Ext : AArch64::Extensions)
+ if (FeatureSet.find(Ext.Feature) != FeatureSet.end())
+ MArch.push_back(Ext.Name.str());
+ for (const auto &Ext : AArch64::Extensions)
+ if (FeatureSet.find(Ext.NegFeature) != FeatureSet.end())
+ MArch.push_back(("no" + Ext.Name).str());
+ MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str());
+ Result.push_back(llvm::join(MArch, "+"));
+}
+
+static void getARMMultiSelectionFlags(const Driver &D,
+ const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
+ Multilib::flags_list &Result) {
+ std::vector<StringRef> Features;
+ llvm::ARM::FPUKind FPUKind =
+ tools::arm::getARMTargetFeatures(D, Triple, Args, Features, false);
+ const auto UnifiedFeatures = tools::unifyTargetFeatures(Features);
+ llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
+ UnifiedFeatures.end());
+ std::vector<std::string> MArch;
+ for (const auto &Ext : ARM::ARCHExtNames)
+ if (FeatureSet.find(Ext.Feature) != FeatureSet.end())
+ MArch.push_back(Ext.Name.str());
+ for (const auto &Ext : ARM::ARCHExtNames)
+ if (FeatureSet.find(Ext.NegFeature) != FeatureSet.end())
+ MArch.push_back(("no" + Ext.Name).str());
+ MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str());
+ Result.push_back(llvm::join(MArch, "+"));
+
+ switch (FPUKind) {
+#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
+ case llvm::ARM::KIND: \
+ Result.push_back("-mfpu=" NAME); \
+ break;
+#include "llvm/TargetParser/ARMTargetParser.def"
+ default:
+ llvm_unreachable("Invalid FPUKind");
+ }
+
+ switch (arm::getARMFloatABI(D, Triple, Args)) {
+ case arm::FloatABI::Soft:
+ Result.push_back("-mfloat-abi=soft");
+ break;
+ case arm::FloatABI::SoftFP:
+ Result.push_back("-mfloat-abi=softfp");
+ break;
+ case arm::FloatABI::Hard:
+ Result.push_back("-mfloat-abi=hard");
+ break;
+ case arm::FloatABI::Invalid:
+ llvm_unreachable("Invalid float ABI");
+ }
+}
+
+Multilib::flags_list
+ToolChain::getMultiSelectionFlags(const llvm::opt::ArgList &Args) const {
+ using namespace clang::driver::options;
+
+ std::vector<std::string> Result;
+ const llvm::Triple Triple(ComputeEffectiveClangTriple(Args));
+ Result.push_back("--target=" + Triple.str());
+
+ // Enumerate boolean flags we care about for the purposes of multilib here.
+ // There must be a smarter way to do it but this gets us started.
+ const struct HasFlag {
+ ID Pos, Neg;
+ bool Default;
+ } HasFlagList[] = {
+ {OPT_fexceptions, OPT_fno_exceptions, true},
+ {OPT_frtti, OPT_fno_rtti, true},
+ };
+
+ // Options we care about that have a single last-wins value.
+ static const ID GetLastArgValue[] = {
+ OPT_fcxx_abi_EQ,
+ };
+
+ for (const HasFlag &HF : HasFlagList) {
+ ID Option = Args.hasFlag(HF.Pos, HF.Neg, HF.Default) ? HF.Pos : HF.Neg;
+ Result.push_back(
+ "-" + clang::driver::getDriverOptTable().getOptionName(Option).str());
+ }
+
+ for (ID Option : GetLastArgValue) {
+ StringRef Value = Args.getLastArgValue(Option);
+ if (!Value.empty()) {
+ Result.push_back(
+ "-" +
+ (clang::driver::getDriverOptTable().getOptionName(Option) + Value)
+ .str());
+ }
+ }
+
+ const SanitizerArgs SanArgs(getSanitizerArgs(Args));
+ if (SanArgs.needsAsanRt())
+ Result.push_back("-fsanitize=address");
+ if (SanArgs.needsHwasanRt())
+ Result.push_back("-fsanitize=hwaddress");
+
+ switch (Triple.getArch()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
+ case llvm::Triple::aarch64_be:
+ getAArch64MultiSelectionFlags(D, Triple, Args, Result);
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ getARMMultiSelectionFlags(D, Triple, Args, Result);
+ break;
+ default:
+ break;
+ }
+
+ // Sort and remove duplicates
+ std::sort(Result.begin(), Result.end());
+ Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
+ return Result;
+}
+
SanitizerArgs
ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const {
SanitizerArgs SanArgs(*this, JobArgs, !SanitizerArgsChecked);
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -2217,6 +2217,17 @@
return false;
}
+ if (C.getArgs().hasArg(options::OPT_print_multi_selection_flags)) {
+ Multilib::flags_list ArgFlags = TC.getMultiSelectionFlags(C.getArgs());
+ llvm::StringSet<> ExpandedFlags = TC.getMultilibs().expandFlags(ArgFlags);
+ std::set<llvm::StringRef> SortedFlags;
+ for (const auto &FlagEntry : ExpandedFlags)
+ SortedFlags.insert(FlagEntry.getKey());
+ for (auto Flag : SortedFlags)
+ llvm::outs() << Flag << '\n';
+ return false;
+ }
+
if (C.getArgs().hasArg(options::OPT_print_multi_directory)) {
const Multilib &Multilib = TC.getMultilib();
if (Multilib.gccSuffix().empty())
Index: clang/include/clang/Driver/ToolChain.h
===================================================================
--- clang/include/clang/Driver/ToolChain.h
+++ clang/include/clang/Driver/ToolChain.h
@@ -285,6 +285,18 @@
const Multilib &getMultilib() const { return SelectedMultilib; }
+ /// Get flags suitable for multilib selection, based on the provided clang
+ /// command line arguments. The command line arguments aren't suitable to be
+ /// used directly for multilib selection because they are not normalized and
+ /// normalization is a complex process. The result of this function is similar
+ /// to clang command line arguments except that the list of arguments is
+ /// incomplete. Only certain command line arguments are processed. If more
+ /// command line arguments are needed for multilib selection then this
+ /// function should be extended.
+ /// To allow users to find out what flags are returned, clang accepts a
+ /// -print-multi-selection-flags-experimental argument.
+ Multilib::flags_list getMultiSelectionFlags(const llvm::opt::ArgList &) const;
+
SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const;
const XRayArgs& getXRayArgs() const;
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -4258,6 +4258,8 @@
"library (\"libgcc.a\" or \"libclang_rt.builtins.*.a\")">;
def print_multi_directory : Flag<["-", "--"], "print-multi-directory">;
def print_multi_lib : Flag<["-", "--"], "print-multi-lib">;
+def print_multi_selection_flags : Flag<["-", "--"], "print-multi-selection-flags-experimental">,
+ HelpText<"Print the flags used for selecting multilibs (experimental)">;
def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">,
Flags<[Unsupported]>;
def print_target_triple : Flag<["-", "--"], "print-target-triple">,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits