From 73779bb2093310bf129017f2f504ec93b1ca4a1d Mon Sep 17 00:00:00 2001 From: Balint Cristian Date: Fri, 22 Sep 2023 10:43:17 +0300 Subject: [PATCH] [clang] Enable descriptions for --print-supported-extensions (#66715) Enables summary descriptions along with the names of the feature. Descriptions here are simply looked up via the available llvm tablegen data. --- .../test/Driver/print-supported-extensions.c | 6 + clang/tools/driver/cc1_main.cpp | 14 +- llvm/include/llvm/MC/MCSubtargetInfo.h | 6 + llvm/include/llvm/Support/RISCVISAInfo.h | 3 +- .../llvm/TargetParser/AArch64TargetParser.h | 3 +- .../llvm/TargetParser/ARMTargetParser.h | 3 +- llvm/lib/Support/RISCVISAInfo.cpp | 28 +- llvm/lib/TargetParser/AArch64TargetParser.cpp | 15 +- llvm/lib/TargetParser/ARMTargetParser.cpp | 15 +- llvm/unittests/Support/RISCVISAInfoTest.cpp | 244 +++++++++--------- .../TargetParser/TargetParserTest.cpp | 21 +- 11 files changed, 212 insertions(+), 146 deletions(-) diff --git a/clang/test/Driver/print-supported-extensions.c b/clang/test/Driver/print-supported-extensions.c index 8daf4d8a34b8a6..17894fc0f7ee0b 100644 --- a/clang/test/Driver/print-supported-extensions.c +++ b/clang/test/Driver/print-supported-extensions.c @@ -4,14 +4,20 @@ // RUN: %if aarch64-registered-target %{ %clang --target=aarch64-linux-gnu \ // RUN: --print-supported-extensions 2>&1 | FileCheck %s --check-prefix AARCH64 %} // AARCH64: All available -march extensions for AArch64 +// AARCH64: Name Description +// AARCH64: aes Enable AES support (FEAT_AES, FEAT_PMULL) // RUN: %if riscv-registered-target %{ %clang --target=riscv64-linux-gnu \ // RUN: --print-supported-extensions 2>&1 | FileCheck %s --check-prefix RISCV %} // RISCV: All available -march extensions for RISC-V +// RISCV: Name Version Description +// RISCV: i 2.1 // RUN: %if arm-registered-target %{ %clang --target=arm-linux-gnu \ // RUN: --print-supported-extensions 2>&1 | FileCheck %s --check-prefix ARM %} // ARM: All available -march extensions for ARM +// ARM: Name Description +// ARM: crc Enable support for CRC instructions // RUN: %if x86-registered-target %{ not %clang --target=x86_64-linux-gnu \ // RUN: --print-supported-extensions 2>&1 | FileCheck %s --check-prefix X86 %} diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp index f0d7b5c3889dc1..e9d2c6aad371db 100644 --- a/clang/tools/driver/cc1_main.cpp +++ b/clang/tools/driver/cc1_main.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Config/llvm-config.h" #include "llvm/LinkAllPasses.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" @@ -198,13 +199,20 @@ static int PrintSupportedExtensions(std::string TargetStr) { std::unique_ptr TheTargetMachine( TheTarget->createTargetMachine(TargetStr, "", "", Options, std::nullopt)); const llvm::Triple &MachineTriple = TheTargetMachine->getTargetTriple(); + const llvm::MCSubtargetInfo *MCInfo = TheTargetMachine->getMCSubtargetInfo(); + const llvm::ArrayRef Features = + MCInfo->getAllProcessorFeatures(); + + llvm::StringMap DescMap; + for (const llvm::SubtargetFeatureKV &feature : Features) + DescMap.insert({feature.Key, feature.Desc}); if (MachineTriple.isRISCV()) - llvm::riscvExtensionsHelp(); + llvm::riscvExtensionsHelp(DescMap); else if (MachineTriple.isAArch64()) - llvm::AArch64::PrintSupportedExtensions(); + llvm::AArch64::PrintSupportedExtensions(DescMap); else if (MachineTriple.isARM()) - llvm::ARM::PrintSupportedExtensions(); + llvm::ARM::PrintSupportedExtensions(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/MC/MCSubtargetInfo.h b/llvm/include/llvm/MC/MCSubtargetInfo.h index c1533ac8d0059f..f172a799aa3331 100644 --- a/llvm/include/llvm/MC/MCSubtargetInfo.h +++ b/llvm/include/llvm/MC/MCSubtargetInfo.h @@ -230,10 +230,16 @@ class MCSubtargetInfo { return Found != ProcDesc.end() && StringRef(Found->Key) == CPU; } + /// Return processor descriptions. ArrayRef getAllProcessorDescriptions() const { return ProcDesc; } + /// Return processor features. + ArrayRef getAllProcessorFeatures() const { + return ProcFeatures; + } + virtual unsigned getHwMode() const { return 0; } /// Return the cache size in bytes for the given level of cache. diff --git a/llvm/include/llvm/Support/RISCVISAInfo.h b/llvm/include/llvm/Support/RISCVISAInfo.h index 9092fe5c272a99..09c4edd6df60e9 100644 --- a/llvm/include/llvm/Support/RISCVISAInfo.h +++ b/llvm/include/llvm/Support/RISCVISAInfo.h @@ -9,6 +9,7 @@ #ifndef LLVM_SUPPORT_RISCVISAINFO_H #define LLVM_SUPPORT_RISCVISAINFO_H +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -22,7 +23,7 @@ struct RISCVExtensionInfo { unsigned MinorVersion; }; -void riscvExtensionsHelp(); +void riscvExtensionsHelp(StringMap DescMap); class RISCVISAInfo { public: diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h index 190f482044083c..b9845473bf8b33 100644 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -16,6 +16,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Bitset.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/VersionTuple.h" #include @@ -663,7 +664,7 @@ bool isX18ReservedByDefault(const Triple &TT); // themselves, they are sequential (0, 1, 2, 3, ...). uint64_t getCpuSupportsMask(ArrayRef FeatureStrs); -void PrintSupportedExtensions(); +void PrintSupportedExtensions(StringMap DescMap); } // namespace AArch64 } // namespace llvm diff --git a/llvm/include/llvm/TargetParser/ARMTargetParser.h b/llvm/include/llvm/TargetParser/ARMTargetParser.h index 37a358d1fa415c..b893eab1902f81 100644 --- a/llvm/include/llvm/TargetParser/ARMTargetParser.h +++ b/llvm/include/llvm/TargetParser/ARMTargetParser.h @@ -14,6 +14,7 @@ #ifndef LLVM_TARGETPARSER_ARMTARGETPARSER_H #define LLVM_TARGETPARSER_ARMTARGETPARSER_H +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ARMBuildAttributes.h" #include "llvm/TargetParser/ARMTargetParserCommon.h" @@ -259,7 +260,7 @@ StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU); /// string then the triple's arch name is used. StringRef getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch = {}); -void PrintSupportedExtensions(); +void PrintSupportedExtensions(StringMap DescMap); } // namespace ARM } // namespace llvm diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index a3045657e63b72..c4f50b7773b75d 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -210,24 +210,36 @@ static void verifyTables() { #endif } -void llvm::riscvExtensionsHelp() { +static void PrintExtension(const std::string Name, const std::string Version, + const std::string Description) { + outs() << " " + << format(Description.empty() ? "%-20s%s\n" : "%-20s%-10s%s\n", + Name.c_str(), Version.c_str(), Description.c_str()); +} + +void llvm::riscvExtensionsHelp(StringMap DescMap) { + outs() << "All available -march extensions for RISC-V\n\n"; - outs() << '\t' << left_justify("Name", 20) << "Version\n"; + PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description")); 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); + for (const auto &E : ExtMap) { + std::string Version = std::to_string(E.second.MajorVersion) + "." + + std::to_string(E.second.MinorVersion); + PrintExtension(E.first, Version, DescMap[E.first].str()); + } 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); + for (const auto &E : ExtMap) { + std::string Version = std::to_string(E.second.MajorVersion) + "." + + std::to_string(E.second.MinorVersion); + PrintExtension(E.first, Version, DescMap["experimental-" + E.first].str()); + } outs() << "\nUse -march to specify the target's extension.\n" "For example, clang -march=rv32i_v1p0\n"; diff --git a/llvm/lib/TargetParser/AArch64TargetParser.cpp b/llvm/lib/TargetParser/AArch64TargetParser.cpp index 166cf880ad4a89..a3f9dfa4a283ed 100644 --- a/llvm/lib/TargetParser/AArch64TargetParser.cpp +++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/TargetParser/AArch64TargetParser.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/ARMTargetParserCommon.h" #include "llvm/TargetParser/Triple.h" @@ -135,11 +136,17 @@ std::optional AArch64::parseCpu(StringRef Name) { return {}; } -void AArch64::PrintSupportedExtensions() { - outs() << "All available -march extensions for AArch64\n\n"; +void AArch64::PrintSupportedExtensions(StringMap DescMap) { + outs() << "All available -march extensions for AArch64\n\n" + << " " << left_justify("Name", 20) + << (DescMap.empty() ? "\n" : "Description\n"); for (const auto &Ext : Extensions) { // Extensions without a feature cannot be used with -march. - if (!Ext.Feature.empty()) - outs() << '\t' << Ext.Name << "\n"; + if (!Ext.Feature.empty()) { + std::string Description = DescMap[Ext.Name].str(); + outs() << " " + << format(Description.empty() ? "%s\n" : "%-20s%s\n", + Ext.Name.str().c_str(), Description.c_str()); + } } } diff --git a/llvm/lib/TargetParser/ARMTargetParser.cpp b/llvm/lib/TargetParser/ARMTargetParser.cpp index 7bf7914e9c5316..c84928eeb07b14 100644 --- a/llvm/lib/TargetParser/ARMTargetParser.cpp +++ b/llvm/lib/TargetParser/ARMTargetParser.cpp @@ -13,6 +13,7 @@ #include "llvm/TargetParser/ARMTargetParser.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/ARMTargetParserCommon.h" #include "llvm/TargetParser/Triple.h" @@ -600,11 +601,17 @@ StringRef ARM::getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch) { llvm_unreachable("invalid arch name"); } -void ARM::PrintSupportedExtensions() { - outs() << "All available -march extensions for ARM\n\n"; +void ARM::PrintSupportedExtensions(StringMap DescMap) { + outs() << "All available -march extensions for ARM\n\n" + << " " << left_justify("Name", 20) + << (DescMap.empty() ? "\n" : "Description\n"); for (const auto &Ext : ARCHExtNames) { // Extensions without a feature cannot be used with -march. - if (!Ext.Feature.empty()) - outs() << '\t' << Ext.Name << "\n"; + if (!Ext.Feature.empty()) { + std::string Description = DescMap[Ext.Name].str(); + outs() << " " + << format(Description.empty() ? "%s\n" : "%-20s%s\n", + Ext.Name.str().c_str(), Description.c_str()); + } } } diff --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp index a285baa57a2a6f..e893e0d6f91685 100644 --- a/llvm/unittests/Support/RISCVISAInfoTest.cpp +++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringMap.h" #include "llvm/Support/RISCVISAInfo.h" #include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" @@ -631,134 +632,137 @@ 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 2.0 - zicsr 2.0 - zifencei 2.0 - zihintntl 1.0 - zihintpause 2.0 - zihpm 2.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 + Name Version Description + i 2.1 This is a long dummy description + 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 2.0 + zicsr 2.0 + zifencei 2.0 + zihintntl 1.0 + zihintpause 2.0 + zihpm 2.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 + zicfilp 0.2 This is a long dummy description + 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)"; + StringMap DummyMap; + DummyMap["i"] = "This is a long dummy description"; + DummyMap["experimental-zicfilp"] = "This is a long dummy description"; + outs().flush(); testing::internal::CaptureStdout(); - - llvm::riscvExtensionsHelp(); + riscvExtensionsHelp(DummyMap); outs().flush(); std::string CapturedOutput = testing::internal::GetCapturedStdout(); diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index 8223f9f575135d..f8ef18efe5a086 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -8,6 +8,7 @@ #include "llvm/TargetParser/TargetParser.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/ARMBuildAttributes.h" #include "llvm/Support/FormatVariadic.h" @@ -1012,11 +1013,17 @@ TEST(TargetParserTest, getARMCPUForArch) { TEST(TargetParserTest, ARMPrintSupportedExtensions) { std::string expected = "All available -march extensions for ARM\n\n" - "\tcrc\n\tcrypto\n\tsha2"; + " Name Description\n" + " crc This is a long dummy description\n" + " crypto\n" + " sha2\n"; + + StringMap DummyMap; + DummyMap["crc"] = "This is a long dummy description"; outs().flush(); testing::internal::CaptureStdout(); - ARM::PrintSupportedExtensions(); + ARM::PrintSupportedExtensions(DummyMap); outs().flush(); std::string captured = testing::internal::GetCapturedStdout(); @@ -1932,11 +1939,17 @@ TEST(TargetParserTest, AArch64ArchExtFeature) { TEST(TargetParserTest, AArch64PrintSupportedExtensions) { std::string expected = "All available -march extensions for AArch64\n\n" - "\taes\n\tb16b16\n\tbf16"; + " Name Description\n" + " aes This is a long dummy description\n" + " b16b16\n" + " bf16\n"; + + StringMap DummyMap; + DummyMap["aes"] = "This is a long dummy description"; outs().flush(); testing::internal::CaptureStdout(); - AArch64::PrintSupportedExtensions(); + AArch64::PrintSupportedExtensions(DummyMap); outs().flush(); std::string captured = testing::internal::GetCapturedStdout();