[clang] [llvm] [RISCV] Add ability to list extensions enabled for a target (PR #98207)

Michael Maitland via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 10 06:27:09 PDT 2024


https://github.com/michaelmaitland updated https://github.com/llvm/llvm-project/pull/98207

>From 9db0919439f197408e9cb8314bd407beb18d075b Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Tue, 9 Jul 2024 10:44:05 -0700
Subject: [PATCH 1/4] [RISCV] Add ability to list extensions enabled for a
 target

bb83a3d introduced `--print-enabled-extensions` command line option for
AArch64. This patch introduces RISC-V support for this option.
---
 clang/include/clang/Driver/Options.td         |  2 +-
 clang/lib/Driver/Driver.cpp                   |  1 +
 clang/tools/driver/cc1_main.cpp               | 12 ++++--
 llvm/include/llvm/TargetParser/RISCVISAInfo.h |  6 ++-
 llvm/lib/TargetParser/RISCVISAInfo.cpp        | 42 ++++++++++++++++++-
 .../TargetParser/RISCVISAInfoTest.cpp         | 30 ++++++++++++-
 6 files changed, 85 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index fae865571001c..b128f4a80ef99 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5730,7 +5730,7 @@ def print_supported_extensions : Flag<["-", "--"], "print-supported-extensions">
 def print_enabled_extensions : Flag<["-", "--"], "print-enabled-extensions">,
   Visibility<[ClangOption, CC1Option, CLOption]>,
   HelpText<"Print the extensions enabled by the given target and -march/-mcpu options."
-           " (AArch64 only)">,
+           " (AArch64 and RISC-V only)">,
   MarshallingInfoFlag<FrontendOpts<"PrintEnabledExtensions">>;
 def : Flag<["-"], "mcpu=help">, Alias<print_supported_cpus>;
 def : Flag<["-"], "mtune=help">, Alias<print_supported_cpus>;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 021c5b8a33dba..28c3b52483e51 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4367,6 +4367,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
         return;
       }
       if (Opt == options::OPT_print_enabled_extensions &&
+          !C.getDefaultToolChain().getTriple().isRISCV() &&
           !C.getDefaultToolChain().getTriple().isAArch64()) {
         C.getDriver().Diag(diag::err_opt_not_valid_on_target)
             << "--print-enabled-extensions";
diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp
index 3c0599c2e5149..441093dbf9f39 100644
--- a/clang/tools/driver/cc1_main.cpp
+++ b/clang/tools/driver/cc1_main.cpp
@@ -147,7 +147,7 @@ static int PrintSupportedExtensions(std::string TargetStr) {
     DescMap.insert({feature.Key, feature.Desc});
 
   if (MachineTriple.isRISCV())
-    llvm::riscvExtensionsHelp(DescMap);
+    llvm::printSupportedExtensions(DescMap);
   else if (MachineTriple.isAArch64())
     llvm::AArch64::PrintSupportedExtensions();
   else if (MachineTriple.isARM())
@@ -190,13 +190,19 @@ static int PrintEnabledExtensions(const TargetOptions& TargetOpts) {
   for (const llvm::SubtargetFeatureKV &feature : Features)
     EnabledFeatureNames.insert(feature.Key);
 
-  if (!MachineTriple.isAArch64()) {
+  if (MachineTriple.isAArch64())
+    llvm::AArch64::printEnabledExtensions(EnabledFeatureNames);
+  else if (MachineTriple.isRISCV()) {
+    llvm::StringMap<llvm::StringRef> DescMap;
+    for (const llvm::SubtargetFeatureKV &feature : Features)
+      DescMap.insert({feature.Key, feature.Desc});
+    llvm::printEnabledExtensions(MachineTriple.isArch64Bit(), EnabledFeatureNames, DescMap);
+  } else {
     // The option was already checked in Driver::HandleImmediateArgs,
     // so we do not expect to get here if we are not a supported architecture.
     assert(0 && "Unhandled triple for --print-enabled-extensions option.");
     return 1;
   }
-  llvm::AArch64::printEnabledExtensions(EnabledFeatureNames);
 
   return 0;
 }
diff --git a/llvm/include/llvm/TargetParser/RISCVISAInfo.h b/llvm/include/llvm/TargetParser/RISCVISAInfo.h
index 5d3f3e113e96d..e70ef52268feb 100644
--- a/llvm/include/llvm/TargetParser/RISCVISAInfo.h
+++ b/llvm/include/llvm/TargetParser/RISCVISAInfo.h
@@ -15,11 +15,15 @@
 #include "llvm/Support/RISCVISAUtils.h"
 
 #include <map>
+#include <set>
 #include <string>
 #include <vector>
 
 namespace llvm {
-void riscvExtensionsHelp(StringMap<StringRef> DescMap);
+void printSupportedExtensions(StringMap<StringRef> &DescMap);
+void printEnabledExtensions(bool IsRV64,
+                            std::set<StringRef> &EnabledFeatureNames,
+                            StringMap<StringRef> &DescMap);
 
 class RISCVISAInfo {
 public:
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 0229b5a140f91..c48ec23246579 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -80,8 +80,7 @@ static void PrintExtension(StringRef Name, StringRef Version,
          << Description << "\n";
 }
 
-void llvm::riscvExtensionsHelp(StringMap<StringRef> DescMap) {
-
+void llvm::printSupportedExtensions(StringMap<StringRef> &DescMap) {
   outs() << "All available -march extensions for RISC-V\n\n";
   PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description"));
 
@@ -116,6 +115,45 @@ void llvm::riscvExtensionsHelp(StringMap<StringRef> DescMap) {
             "For example, clang -march=rv32i_v1p0\n";
 }
 
+void llvm::printEnabledExtensions(bool IsRV64,
+                                  std::set<StringRef> &EnabledFeatureNames,
+                                  StringMap<StringRef> &DescMap) {
+  outs() << "Extensions enabled for the given RISC-V target\n\n";
+  PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description"));
+
+  RISCVISAUtils::OrderedExtensionMap FullExtMap;
+  RISCVISAUtils::OrderedExtensionMap ExtMap;
+  for (const auto &E : SupportedExtensions)
+    if (EnabledFeatureNames.find(E.Name) != EnabledFeatureNames.end()) {
+      FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
+      ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
+    }
+  for (const auto &E : ExtMap) {
+    std::string Version =
+        std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);
+    PrintExtension(E.first, Version, DescMap[E.first]);
+  }
+
+  outs() << "\nExperimental extensions\n";
+  ExtMap.clear();
+  for (const auto &E : SupportedExperimentalExtensions) {
+    StringRef Name(E.Name);
+    if (EnabledFeatureNames.find("experimental-" + Name.str()) !=
+        EnabledFeatureNames.end()) {
+      FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
+      ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
+    }
+  }
+  for (const auto &E : ExtMap) {
+    std::string Version =
+        std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);
+    PrintExtension(E.first, Version, DescMap["experimental-" + E.first]);
+  }
+
+  unsigned XLen = IsRV64 ? 64 : 32;
+  outs() << "\nISA String: " << RISCVISAInfo(XLen, FullExtMap).toString();
+}
+
 static bool stripExperimentalPrefix(StringRef &Ext) {
   return Ext.consume_front("experimental-");
 }
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 50a8d7b6b1211..fc9a4cec98e54 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1060,7 +1060,7 @@ For example, clang -march=rv32i_v1p0)";
 
   outs().flush();
   testing::internal::CaptureStdout();
-  riscvExtensionsHelp(DummyMap);
+  printSupportedExtensions(DummyMap);
   outs().flush();
 
   std::string CapturedOutput = testing::internal::GetCapturedStdout();
@@ -1068,3 +1068,31 @@ For example, clang -march=rv32i_v1p0)";
                 return Captured.find(Expected) != std::string::npos;
               }(CapturedOutput, ExpectedOutput));
 }
+
+TEST(TargetParserTest, RISCVPrintEnabledExtensions) {
+  // clang-format off
+  std::string ExpectedOutput =
+R"(Extensions enabled for the given RISC-V target
+
+    Name                 Version   Description
+    i                    2.1       'I' (Base Integer Instruction Set)
+
+Experimental extensions
+    ztso                 0.1       'Ztso' (Memory Model - Total Store Order)
+
+ISA String: rv64i2p1_ztso0p1)";
+  // clang-format on
+
+  StringMap<StringRef> DescMap;
+  DescMap["i"] = "'I' (Base Integer Instruction Set)";
+  DescMap["experimental-ztso"] = "'Ztso' (Memory Model - Total Store Order)";
+  std::set<StringRef> EnabledExtensions = {"i", "experimental-ztso"};
+
+  outs().flush();
+  testing::internal::CaptureStdout();
+  llvm::printEnabledExtensions(/*IsRV64=*/true, EnabledExtensions, DescMap);
+  outs().flush();
+  std::string CapturedOutput = testing::internal::GetCapturedStdout();
+
+  EXPECT_EQ(CapturedOutput, ExpectedOutput);
+}

>From aab0d379f8934cad16f5f824fe41ad976f3436f8 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Tue, 9 Jul 2024 12:53:43 -0700
Subject: [PATCH 2/4] fixup! format and use RISCV namespace

---
 clang/tools/driver/cc1_main.cpp                  | 5 +++--
 llvm/include/llvm/TargetParser/RISCVISAInfo.h    | 9 +++++----
 llvm/lib/TargetParser/RISCVISAInfo.cpp           | 8 ++++----
 llvm/unittests/TargetParser/RISCVISAInfoTest.cpp | 5 +++--
 4 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp
index 441093dbf9f39..c2ccb47a15bc8 100644
--- a/clang/tools/driver/cc1_main.cpp
+++ b/clang/tools/driver/cc1_main.cpp
@@ -147,7 +147,7 @@ static int PrintSupportedExtensions(std::string TargetStr) {
     DescMap.insert({feature.Key, feature.Desc});
 
   if (MachineTriple.isRISCV())
-    llvm::printSupportedExtensions(DescMap);
+    llvm::RISCVISAInfo::printSupportedExtensions(DescMap);
   else if (MachineTriple.isAArch64())
     llvm::AArch64::PrintSupportedExtensions();
   else if (MachineTriple.isARM())
@@ -196,7 +196,8 @@ static int PrintEnabledExtensions(const TargetOptions& TargetOpts) {
     llvm::StringMap<llvm::StringRef> DescMap;
     for (const llvm::SubtargetFeatureKV &feature : Features)
       DescMap.insert({feature.Key, feature.Desc});
-    llvm::printEnabledExtensions(MachineTriple.isArch64Bit(), EnabledFeatureNames, DescMap);
+    llvm::RISCVISAInfo::printEnabledExtensions(MachineTriple.isArch64Bit(),
+                                               EnabledFeatureNames, DescMap);
   } else {
     // The option was already checked in Driver::HandleImmediateArgs,
     // so we do not expect to get here if we are not a supported architecture.
diff --git a/llvm/include/llvm/TargetParser/RISCVISAInfo.h b/llvm/include/llvm/TargetParser/RISCVISAInfo.h
index e70ef52268feb..d7a08013fa6ac 100644
--- a/llvm/include/llvm/TargetParser/RISCVISAInfo.h
+++ b/llvm/include/llvm/TargetParser/RISCVISAInfo.h
@@ -20,10 +20,6 @@
 #include <vector>
 
 namespace llvm {
-void printSupportedExtensions(StringMap<StringRef> &DescMap);
-void printEnabledExtensions(bool IsRV64,
-                            std::set<StringRef> &EnabledFeatureNames,
-                            StringMap<StringRef> &DescMap);
 
 class RISCVISAInfo {
 public:
@@ -79,6 +75,11 @@ class RISCVISAInfo {
                                    unsigned MinorVersion);
   static std::string getTargetFeatureForExtension(StringRef Ext);
 
+  static void printSupportedExtensions(StringMap<StringRef> &DescMap);
+  static void printEnabledExtensions(bool IsRV64,
+                                     std::set<StringRef> &EnabledFeatureNames,
+                                     StringMap<StringRef> &DescMap);
+
 private:
   RISCVISAInfo(unsigned XLen) : XLen(XLen) {}
 
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index c48ec23246579..578251566f2b3 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -80,7 +80,7 @@ static void PrintExtension(StringRef Name, StringRef Version,
          << Description << "\n";
 }
 
-void llvm::printSupportedExtensions(StringMap<StringRef> &DescMap) {
+void RISCVISAInfo::printSupportedExtensions(StringMap<StringRef> &DescMap) {
   outs() << "All available -march extensions for RISC-V\n\n";
   PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description"));
 
@@ -115,9 +115,9 @@ void llvm::printSupportedExtensions(StringMap<StringRef> &DescMap) {
             "For example, clang -march=rv32i_v1p0\n";
 }
 
-void llvm::printEnabledExtensions(bool IsRV64,
-                                  std::set<StringRef> &EnabledFeatureNames,
-                                  StringMap<StringRef> &DescMap) {
+void RISCVISAInfo::printEnabledExtensions(
+    bool IsRV64, std::set<StringRef> &EnabledFeatureNames,
+    StringMap<StringRef> &DescMap) {
   outs() << "Extensions enabled for the given RISC-V target\n\n";
   PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description"));
 
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index fc9a4cec98e54..05df546bb80a0 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1060,7 +1060,7 @@ For example, clang -march=rv32i_v1p0)";
 
   outs().flush();
   testing::internal::CaptureStdout();
-  printSupportedExtensions(DummyMap);
+  RISCVISAInfo::printSupportedExtensions(DummyMap);
   outs().flush();
 
   std::string CapturedOutput = testing::internal::GetCapturedStdout();
@@ -1090,7 +1090,8 @@ ISA String: rv64i2p1_ztso0p1)";
 
   outs().flush();
   testing::internal::CaptureStdout();
-  llvm::printEnabledExtensions(/*IsRV64=*/true, EnabledExtensions, DescMap);
+  RISCVISAInfo::printEnabledExtensions(/*IsRV64=*/true, EnabledExtensions,
+                                        DescMap);
   outs().flush();
   std::string CapturedOutput = testing::internal::GetCapturedStdout();
 

>From 98763df5a35e5e5e7b8fec68ac9a9d4fa62bd3e8 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Tue, 9 Jul 2024 13:17:47 -0700
Subject: [PATCH 3/4] fixup! use std::set::count; use zicfilp as experimental
 extension

---
 llvm/lib/TargetParser/RISCVISAInfo.cpp           |  5 ++---
 llvm/unittests/TargetParser/RISCVISAInfoTest.cpp | 10 +++++-----
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 578251566f2b3..f194e77570047 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -124,7 +124,7 @@ void RISCVISAInfo::printEnabledExtensions(
   RISCVISAUtils::OrderedExtensionMap FullExtMap;
   RISCVISAUtils::OrderedExtensionMap ExtMap;
   for (const auto &E : SupportedExtensions)
-    if (EnabledFeatureNames.find(E.Name) != EnabledFeatureNames.end()) {
+    if (EnabledFeatureNames.count(E.Name) != 0) {
       FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
       ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
     }
@@ -138,8 +138,7 @@ void RISCVISAInfo::printEnabledExtensions(
   ExtMap.clear();
   for (const auto &E : SupportedExperimentalExtensions) {
     StringRef Name(E.Name);
-    if (EnabledFeatureNames.find("experimental-" + Name.str()) !=
-        EnabledFeatureNames.end()) {
+    if (EnabledFeatureNames.count("experimental-" + Name.str()) != 0) {
       FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
       ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
     }
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 05df546bb80a0..2efca0cdc3093 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1078,20 +1078,20 @@ R"(Extensions enabled for the given RISC-V target
     i                    2.1       'I' (Base Integer Instruction Set)
 
 Experimental extensions
-    ztso                 0.1       'Ztso' (Memory Model - Total Store Order)
+    zicfilp              0.4       'Zicfilp' (Landing pad)
 
-ISA String: rv64i2p1_ztso0p1)";
+ISA String: rv64i2p1_zicfilp0p4)";
   // clang-format on
 
   StringMap<StringRef> DescMap;
   DescMap["i"] = "'I' (Base Integer Instruction Set)";
-  DescMap["experimental-ztso"] = "'Ztso' (Memory Model - Total Store Order)";
-  std::set<StringRef> EnabledExtensions = {"i", "experimental-ztso"};
+  DescMap["experimental-zicfilp"] = "'Zicfilp' (Landing pad)";
+  std::set<StringRef> EnabledExtensions = {"i", "experimental-zicfilp"};
 
   outs().flush();
   testing::internal::CaptureStdout();
   RISCVISAInfo::printEnabledExtensions(/*IsRV64=*/true, EnabledExtensions,
-                                        DescMap);
+                                       DescMap);
   outs().flush();
   std::string CapturedOutput = testing::internal::GetCapturedStdout();
 

>From 9dfb0b2d31572e2011af07f73e25453672d073c2 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Wed, 10 Jul 2024 06:10:01 -0700
Subject: [PATCH 4/4] fixup! use createFromExtMap

---
 llvm/lib/TargetParser/RISCVISAInfo.cpp           | 3 ++-
 llvm/unittests/TargetParser/RISCVISAInfoTest.cpp | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index f194e77570047..254a3f8aa95e0 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -150,7 +150,8 @@ void RISCVISAInfo::printEnabledExtensions(
   }
 
   unsigned XLen = IsRV64 ? 64 : 32;
-  outs() << "\nISA String: " << RISCVISAInfo(XLen, FullExtMap).toString();
+  if (auto ISAString = RISCVISAInfo::createFromExtMap(XLen, FullExtMap))
+    outs() << "\nISA String: " << ISAString.get()->toString();
 }
 
 static bool stripExperimentalPrefix(StringRef &Ext) {
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 2efca0cdc3093..889fbec6c6008 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1080,7 +1080,7 @@ R"(Extensions enabled for the given RISC-V target
 Experimental extensions
     zicfilp              0.4       'Zicfilp' (Landing pad)
 
-ISA String: rv64i2p1_zicfilp0p4)";
+ISA String: rv64i2p1_zicfilp0p4_zicsr2p0)";
   // clang-format on
 
   StringMap<StringRef> DescMap;



More information about the llvm-commits mailing list