Skip to content

Commit eee5d2d

Browse files
[RISCV] Add ability to list extensions enabled for a target (#98207)
bb83a3d introduced `--print-enabled-extensions` command line option for AArch64. This patch introduces RISC-V support for this option. This patch adds documentation for this option. `riscvExtensionsHelp` is renamed to `printSupportedExtensions` to by synonymous with AArch64 and so it is clear what that function does.
1 parent 9f5756a commit eee5d2d

File tree

7 files changed

+94
-8
lines changed

7 files changed

+94
-8
lines changed

clang/docs/CommandGuide/clang.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,12 @@ number of cross compilers, or may only support a native target.
393393
allowed to generate instructions that are valid on i486 and later processors,
394394
but which may not exist on earlier ones.
395395

396+
.. option:: --print-enabled-extensions
397+
398+
Prints the list of extensions that are enabled for the target specified by the
399+
combination of `--target`, `-march`, and `-mcpu` values. Currently, this
400+
option is only supported on AArch64 and RISC-V. On RISC-V, this option also
401+
prints out the ISA string of enabled extensions.
396402

397403
Code Generation Options
398404
~~~~~~~~~~~~~~~~~~~~~~~

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5731,7 +5731,7 @@ def print_supported_extensions : Flag<["-", "--"], "print-supported-extensions">
57315731
def print_enabled_extensions : Flag<["-", "--"], "print-enabled-extensions">,
57325732
Visibility<[ClangOption, CC1Option, CLOption]>,
57335733
HelpText<"Print the extensions enabled by the given target and -march/-mcpu options."
5734-
" (AArch64 only)">,
5734+
" (AArch64 and RISC-V only)">,
57355735
MarshallingInfoFlag<FrontendOpts<"PrintEnabledExtensions">>;
57365736
def : Flag<["-"], "mcpu=help">, Alias<print_supported_cpus>;
57375737
def : Flag<["-"], "mtune=help">, Alias<print_supported_cpus>;

clang/lib/Driver/Driver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4367,6 +4367,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
43674367
return;
43684368
}
43694369
if (Opt == options::OPT_print_enabled_extensions &&
4370+
!C.getDefaultToolChain().getTriple().isRISCV() &&
43704371
!C.getDefaultToolChain().getTriple().isAArch64()) {
43714372
C.getDriver().Diag(diag::err_opt_not_valid_on_target)
43724373
<< "--print-enabled-extensions";

clang/tools/driver/cc1_main.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ static int PrintSupportedExtensions(std::string TargetStr) {
147147
DescMap.insert({feature.Key, feature.Desc});
148148

149149
if (MachineTriple.isRISCV())
150-
llvm::riscvExtensionsHelp(DescMap);
150+
llvm::RISCVISAInfo::printSupportedExtensions(DescMap);
151151
else if (MachineTriple.isAArch64())
152152
llvm::AArch64::PrintSupportedExtensions();
153153
else if (MachineTriple.isARM())
@@ -190,13 +190,20 @@ static int PrintEnabledExtensions(const TargetOptions& TargetOpts) {
190190
for (const llvm::SubtargetFeatureKV &feature : Features)
191191
EnabledFeatureNames.insert(feature.Key);
192192

193-
if (!MachineTriple.isAArch64()) {
193+
if (MachineTriple.isAArch64())
194+
llvm::AArch64::printEnabledExtensions(EnabledFeatureNames);
195+
else if (MachineTriple.isRISCV()) {
196+
llvm::StringMap<llvm::StringRef> DescMap;
197+
for (const llvm::SubtargetFeatureKV &feature : Features)
198+
DescMap.insert({feature.Key, feature.Desc});
199+
llvm::RISCVISAInfo::printEnabledExtensions(MachineTriple.isArch64Bit(),
200+
EnabledFeatureNames, DescMap);
201+
} else {
194202
// The option was already checked in Driver::HandleImmediateArgs,
195203
// so we do not expect to get here if we are not a supported architecture.
196204
assert(0 && "Unhandled triple for --print-enabled-extensions option.");
197205
return 1;
198206
}
199-
llvm::AArch64::printEnabledExtensions(EnabledFeatureNames);
200207

201208
return 0;
202209
}

llvm/include/llvm/TargetParser/RISCVISAInfo.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
#include "llvm/Support/RISCVISAUtils.h"
1616

1717
#include <map>
18+
#include <set>
1819
#include <string>
1920
#include <vector>
2021

2122
namespace llvm {
22-
void riscvExtensionsHelp(StringMap<StringRef> DescMap);
2323

2424
class RISCVISAInfo {
2525
public:
@@ -75,6 +75,11 @@ class RISCVISAInfo {
7575
unsigned MinorVersion);
7676
static std::string getTargetFeatureForExtension(StringRef Ext);
7777

78+
static void printSupportedExtensions(StringMap<StringRef> &DescMap);
79+
static void printEnabledExtensions(bool IsRV64,
80+
std::set<StringRef> &EnabledFeatureNames,
81+
StringMap<StringRef> &DescMap);
82+
7883
private:
7984
RISCVISAInfo(unsigned XLen) : XLen(XLen) {}
8085

llvm/lib/TargetParser/RISCVISAInfo.cpp

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ static void PrintExtension(StringRef Name, StringRef Version,
8080
<< Description << "\n";
8181
}
8282

83-
void llvm::riscvExtensionsHelp(StringMap<StringRef> DescMap) {
84-
83+
void RISCVISAInfo::printSupportedExtensions(StringMap<StringRef> &DescMap) {
8584
outs() << "All available -march extensions for RISC-V\n\n";
8685
PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description"));
8786

@@ -116,6 +115,45 @@ void llvm::riscvExtensionsHelp(StringMap<StringRef> DescMap) {
116115
"For example, clang -march=rv32i_v1p0\n";
117116
}
118117

118+
void RISCVISAInfo::printEnabledExtensions(
119+
bool IsRV64, std::set<StringRef> &EnabledFeatureNames,
120+
StringMap<StringRef> &DescMap) {
121+
outs() << "Extensions enabled for the given RISC-V target\n\n";
122+
PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description"));
123+
124+
RISCVISAUtils::OrderedExtensionMap FullExtMap;
125+
RISCVISAUtils::OrderedExtensionMap ExtMap;
126+
for (const auto &E : SupportedExtensions)
127+
if (EnabledFeatureNames.count(E.Name) != 0) {
128+
FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
129+
ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
130+
}
131+
for (const auto &E : ExtMap) {
132+
std::string Version =
133+
std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);
134+
PrintExtension(E.first, Version, DescMap[E.first]);
135+
}
136+
137+
outs() << "\nExperimental extensions\n";
138+
ExtMap.clear();
139+
for (const auto &E : SupportedExperimentalExtensions) {
140+
StringRef Name(E.Name);
141+
if (EnabledFeatureNames.count("experimental-" + Name.str()) != 0) {
142+
FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
143+
ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
144+
}
145+
}
146+
for (const auto &E : ExtMap) {
147+
std::string Version =
148+
std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);
149+
PrintExtension(E.first, Version, DescMap["experimental-" + E.first]);
150+
}
151+
152+
unsigned XLen = IsRV64 ? 64 : 32;
153+
if (auto ISAString = RISCVISAInfo::createFromExtMap(XLen, FullExtMap))
154+
outs() << "\nISA String: " << ISAString.get()->toString();
155+
}
156+
119157
static bool stripExperimentalPrefix(StringRef &Ext) {
120158
return Ext.consume_front("experimental-");
121159
}

llvm/unittests/TargetParser/RISCVISAInfoTest.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1060,11 +1060,40 @@ For example, clang -march=rv32i_v1p0)";
10601060

10611061
outs().flush();
10621062
testing::internal::CaptureStdout();
1063-
riscvExtensionsHelp(DummyMap);
1063+
RISCVISAInfo::printSupportedExtensions(DummyMap);
10641064
outs().flush();
10651065

10661066
std::string CapturedOutput = testing::internal::GetCapturedStdout();
10671067
EXPECT_TRUE([](std::string &Captured, std::string &Expected) {
10681068
return Captured.find(Expected) != std::string::npos;
10691069
}(CapturedOutput, ExpectedOutput));
10701070
}
1071+
1072+
TEST(TargetParserTest, RISCVPrintEnabledExtensions) {
1073+
// clang-format off
1074+
std::string ExpectedOutput =
1075+
R"(Extensions enabled for the given RISC-V target
1076+
1077+
Name Version Description
1078+
i 2.1 'I' (Base Integer Instruction Set)
1079+
1080+
Experimental extensions
1081+
zicfilp 0.4 'Zicfilp' (Landing pad)
1082+
1083+
ISA String: rv64i2p1_zicfilp0p4_zicsr2p0)";
1084+
// clang-format on
1085+
1086+
StringMap<StringRef> DescMap;
1087+
DescMap["i"] = "'I' (Base Integer Instruction Set)";
1088+
DescMap["experimental-zicfilp"] = "'Zicfilp' (Landing pad)";
1089+
std::set<StringRef> EnabledExtensions = {"i", "experimental-zicfilp"};
1090+
1091+
outs().flush();
1092+
testing::internal::CaptureStdout();
1093+
RISCVISAInfo::printEnabledExtensions(/*IsRV64=*/true, EnabledExtensions,
1094+
DescMap);
1095+
outs().flush();
1096+
std::string CapturedOutput = testing::internal::GetCapturedStdout();
1097+
1098+
EXPECT_EQ(CapturedOutput, ExpectedOutput);
1099+
}

0 commit comments

Comments
 (0)