[RISCV] Add --print-supported-extensions support

This revision supports --print-supported-extensions,
it prints out all of the extensions and corresponding version supported.

Reviewed By: craig.topper, kito-cheng

Differential Revision: https://reviews.llvm.org/D146054
This commit is contained in:
4vtomat 2023-07-03 19:16:46 -07:00
parent 950f0944c9
commit 4b40ced4e5
7 changed files with 203 additions and 11 deletions

View file

@ -5251,6 +5251,10 @@ def print_supported_cpus : Flag<["-", "--"], "print-supported-cpus">,
HelpText<"Print supported cpu models for the given target (if target is not specified,"
" it will print the supported cpus for the default target)">,
MarshallingInfoFlag<FrontendOpts<"PrintSupportedCPUs">>;
def print_supported_extensions : Flag<["-", "--"], "print-supported-extensions">,
Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Print supported extensions for RISC-V">,
MarshallingInfoFlag<FrontendOpts<"PrintSupportedExtensions">>;
def : Flag<["-"], "mcpu=help">, Alias<print_supported_cpus>;
def : Flag<["-"], "mtune=help">, Alias<print_supported_cpus>;
def time : Flag<["-"], "time">,

View file

@ -283,6 +283,9 @@ public:
/// print the supported cpus for the current target
unsigned PrintSupportedCPUs : 1;
/// Print the supported extensions for the current target.
unsigned PrintSupportedExtensions : 1;
/// Show the -version text.
unsigned ShowVersion : 1;

View file

@ -2103,7 +2103,8 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
if (C.getArgs().hasArg(options::OPT_v) ||
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
C.getArgs().hasArg(options::OPT_print_supported_cpus)) {
C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
C.getArgs().hasArg(options::OPT_print_supported_extensions)) {
PrintVersion(C, llvm::errs());
SuppressMissingInputWarning = true;
}
@ -4273,16 +4274,30 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
}
// If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a custom
// Compile phase that prints out supported cpu models and quits.
if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) {
// Use the -mcpu=? flag as the dummy input to cc1.
Actions.clear();
Action *InputAc = C.MakeAction<InputAction>(*A, types::TY_C);
Actions.push_back(
C.MakeAction<PrecompileJobAction>(InputAc, types::TY_Nothing));
for (auto &I : Inputs)
I.second->claim();
for (auto Opt : {options::OPT_print_supported_cpus,
options::OPT_print_supported_extensions}) {
// If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a
// custom Compile phase that prints out supported cpu models and quits.
//
// If --print-supported-extensions is specified, call the helper function
// RISCVMarchHelp in RISCVISAInfo.cpp that prints out supported extensions
// and quits.
if (Arg *A = Args.getLastArg(Opt)) {
if (Opt == options::OPT_print_supported_extensions &&
!C.getDefaultToolChain().getTriple().isRISCV()) {
C.getDriver().Diag(diag::err_opt_not_valid_on_target)
<< "--print-supported-extensions";
return;
}
// Use the -mcpu=? flag as the dummy input to cc1.
Actions.clear();
Action *InputAc = C.MakeAction<InputAction>(*A, types::TY_C);
Actions.push_back(
C.MakeAction<PrecompileJobAction>(InputAc, types::TY_Nothing));
for (auto &I : Inputs)
I.second->claim();
}
}
// Call validator for dxil when -Vd not in Args.

View file

@ -38,6 +38,7 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/RISCVISAInfo.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/TimeProfiler.h"
@ -221,6 +222,10 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
if (Clang->getFrontendOpts().PrintSupportedCPUs)
return PrintSupportedCPUs(Clang->getTargetOpts().Triple);
// --print-supported-extensions takes priority over the actual compilation.
if (Clang->getFrontendOpts().PrintSupportedExtensions)
return llvm::riscvExtensionsHelp(), 0;
// Infer the builtin include path if unspecified.
if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
Clang->getHeaderSearchOpts().ResourceDir.empty())

View file

@ -22,6 +22,8 @@ struct RISCVExtensionInfo {
unsigned MinorVersion;
};
void riscvExtensionsHelp();
class RISCVISAInfo {
public:
RISCVISAInfo(const RISCVISAInfo &) = delete;

View file

@ -210,6 +210,29 @@ static void verifyTables() {
#endif
}
void llvm::riscvExtensionsHelp() {
outs() << "All available -march extensions for RISC-V\n\n";
outs() << '\t' << left_justify("Name", 20) << "Version\n";
RISCVISAInfo::OrderedExtensionMap ExtMap;
for (const auto &E : SupportedExtensions)
ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
for (const auto &E : ExtMap)
outs() << format("\t%-20s%d.%d\n", E.first.c_str(), E.second.MajorVersion,
E.second.MinorVersion);
outs() << "\nExperimental extensions\n";
ExtMap.clear();
for (const auto &E : SupportedExperimentalExtensions)
ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
for (const auto &E : ExtMap)
outs() << format("\t%-20s%d.%d\n", E.first.c_str(), E.second.MajorVersion,
E.second.MinorVersion);
outs() << "\nUse -march to specify the target's extension.\n"
"For example, clang -march=rv32i_v1p0\n";
}
static bool stripExperimentalPrefix(StringRef &Ext) {
return Ext.consume_front("experimental-");
}

View file

@ -626,3 +626,143 @@ TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) {
EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), "");
EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), "");
}
TEST(RiscvExtensionsHelp, CheckExtensions) {
std::string ExpectedOutput =
R"(All available -march extensions for RISC-V
Name Version
i 2.1
e 2.0
m 2.0
a 2.1
f 2.2
d 2.2
c 2.0
v 1.0
h 1.0
zicbom 1.0
zicbop 1.0
zicboz 1.0
zicntr 1.0
zicsr 2.0
zifencei 2.0
zihintntl 1.0
zihintpause 2.0
zihpm 1.0
zmmul 1.0
zawrs 1.0
zfh 1.0
zfhmin 1.0
zfinx 1.0
zdinx 1.0
zca 1.0
zcb 1.0
zcd 1.0
zce 1.0
zcf 1.0
zcmp 1.0
zcmt 1.0
zba 1.0
zbb 1.0
zbc 1.0
zbkb 1.0
zbkc 1.0
zbkx 1.0
zbs 1.0
zk 1.0
zkn 1.0
zknd 1.0
zkne 1.0
zknh 1.0
zkr 1.0
zks 1.0
zksed 1.0
zksh 1.0
zkt 1.0
zve32f 1.0
zve32x 1.0
zve64d 1.0
zve64f 1.0
zve64x 1.0
zvfh 1.0
zvfhmin 1.0
zvl1024b 1.0
zvl128b 1.0
zvl16384b 1.0
zvl2048b 1.0
zvl256b 1.0
zvl32768b 1.0
zvl32b 1.0
zvl4096b 1.0
zvl512b 1.0
zvl64b 1.0
zvl65536b 1.0
zvl8192b 1.0
zhinx 1.0
zhinxmin 1.0
svinval 1.0
svnapot 1.0
svpbmt 1.0
xcvalu 1.0
xcvbi 1.0
xcvbitmanip 1.0
xcvmac 1.0
xcvsimd 1.0
xsfcie 1.0
xsfvcp 1.0
xtheadba 1.0
xtheadbb 1.0
xtheadbs 1.0
xtheadcmo 1.0
xtheadcondmov 1.0
xtheadfmemidx 1.0
xtheadmac 1.0
xtheadmemidx 1.0
xtheadmempair 1.0
xtheadsync 1.0
xtheadvdot 1.0
xventanacondops 1.0
Experimental extensions
zicfilp 0.2
zicond 1.0
zacas 1.0
zfa 0.2
zfbfmin 0.8
ztso 0.1
zvbb 1.0
zvbc 1.0
zvfbfmin 0.8
zvfbfwma 0.8
zvkb 1.0
zvkg 1.0
zvkn 1.0
zvknc 1.0
zvkned 1.0
zvkng 1.0
zvknha 1.0
zvknhb 1.0
zvks 1.0
zvksc 1.0
zvksed 1.0
zvksg 1.0
zvksh 1.0
zvkt 1.0
smaia 1.0
ssaia 1.0
Use -march to specify the target's extension.
For example, clang -march=rv32i_v1p0)";
outs().flush();
testing::internal::CaptureStdout();
llvm::riscvExtensionsHelp();
outs().flush();
std::string CapturedOutput = testing::internal::GetCapturedStdout();
EXPECT_TRUE([](std::string &Captured, std::string &Expected) {
return Captured.find(Expected) != std::string::npos;
}(CapturedOutput, ExpectedOutput));
}