From fc51e3821787f1ae8dcb344d4def0ef342ae473b Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 18 Apr 2024 16:47:31 -0700 Subject: [PATCH 1/6] [RISCV][TableGen] Generate RISCVTargetParser.inc from the new RISCVExtension tblgen information. Instead of using RISCVISAInfo's extension information, use the extension found in tblgen after #89326. We still need to use RISCVISAInfo code to get the sorting rules for the ISA string. The ISA string we generate now is not quite the same extension we had before. No implied extensions are included in the generate string unless they are explicitly listed in RISCVProcessors.td. This primarily affects Zicsr being implied by F, V implying Zve*, and Zvl*b implying a smaller Zvl*b. All of these implication should be picked up when the string is used by the frontend. The benefit is that we get a more manageable ISA string for humans to deal with. This is a step towards generating RISCVISAInfo's extension list from tblgen. --- llvm/utils/TableGen/RISCVTargetDefEmitter.cpp | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp index 62916bd62c011..4f840b4227e45 100644 --- a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp +++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp @@ -17,34 +17,34 @@ using namespace llvm; -using ISAInfoTy = llvm::Expected>; - // We can generate march string from target features as what has been described // in RISC-V ISA specification (version 20191213) 'Chapter 27. ISA Extension // Naming Conventions'. // // This is almost the same as RISCVFeatures::parseFeatureBits, except that we // get feature name from feature records instead of feature bits. -static std::string getMArch(const Record &Rec) { - std::vector FeatureVector; +static void printMArch(raw_ostream &OS, const Record &Rec) { + std::map, + RISCVISAInfo::ExtensionComparator> + Extensions; unsigned XLen = 32; // Convert features to FeatureVector. for (auto *Feature : Rec.getValueAsListOfDefs("Features")) { StringRef FeatureName = Feature->getValueAsString("Name"); - if (llvm::RISCVISAInfo::isSupportedExtensionFeature(FeatureName)) - FeatureVector.push_back((Twine("+") + FeatureName).str()); - else if (FeatureName == "64bit") + if (Feature->isSubClassOf("RISCVExtension")) { + unsigned Major = Feature->getValueAsInt("MajorVersion"); + unsigned Minor = Feature->getValueAsInt("MinorVersion"); + Extensions.try_emplace(FeatureName.str(), Major, Minor); + } else if (FeatureName == "64bit") XLen = 64; } - ISAInfoTy ISAInfo = llvm::RISCVISAInfo::parseFeatures(XLen, FeatureVector); - if (!ISAInfo) - report_fatal_error("Invalid features"); + OS << "rv" << XLen; - // RISCVISAInfo::toString will generate a march string with all the extensions - // we have added to it. - return (*ISAInfo)->toString(); + ListSeparator LS("_"); + for (auto const &Ext : Extensions) + OS << LS << Ext.first << Ext.second.first << 'p' << Ext.second.second; } static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) { @@ -54,12 +54,6 @@ static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) { // Iterate on all definition records. for (const Record *Rec : RK.getAllDerivedDefinitions("RISCVProcessorModel")) { - std::string MArch = Rec->getValueAsString("DefaultMarch").str(); - - // Compute MArch from features if we don't specify it. - if (MArch.empty()) - MArch = getMArch(*Rec); - bool FastScalarUnalignedAccess = any_of(Rec->getValueAsListOfDefs("Features"), [&](auto &Feature) { return Feature->getValueAsString("Name") == "unaligned-scalar-mem"; @@ -75,7 +69,16 @@ static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) { OS << "PROC(" << Rec->getName() << ", " << "{\"" << Rec->getValueAsString("Name") << "\"}, " - << "{\"" << MArch << "\"}, " << FastUnalignedAccess << ")\n"; + << "{\""; + + StringRef MArch = Rec->getValueAsString("DefaultMarch"); + + // Compute MArch from features if we don't specify it. + if (MArch.empty()) + printMArch(OS, *Rec); + else + OS << MArch; + OS << "\"}, " << FastUnalignedAccess << ")\n"; } OS << "\n#undef PROC\n"; OS << "\n"; From 815a63b99de61b8b1fde5a8c831f63d8810134db Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 18 Apr 2024 17:10:50 -0700 Subject: [PATCH 2/6] fixup! clang-format --- llvm/utils/TableGen/RISCVTargetDefEmitter.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp index 4f840b4227e45..9862a610bab4d 100644 --- a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp +++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp @@ -67,9 +67,8 @@ static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) { bool FastUnalignedAccess = FastScalarUnalignedAccess && FastVectorUnalignedAccess; - OS << "PROC(" << Rec->getName() << ", " - << "{\"" << Rec->getValueAsString("Name") << "\"}, " - << "{\""; + OS << "PROC(" << Rec->getName() << ", {\"" << Rec->getValueAsString("Name") + << "\"}, {\""; StringRef MArch = Rec->getValueAsString("DefaultMarch"); From 378531b67272efe877689fe899dd29fdc99d7b86 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 19 Apr 2024 15:17:27 -0700 Subject: [PATCH 3/6] fixup! Infer 32-bit Xlen from '32bit' feature. --- llvm/utils/TableGen/RISCVTargetDefEmitter.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp index 9862a610bab4d..d6a6e8b60c105 100644 --- a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp +++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp @@ -27,7 +27,7 @@ static void printMArch(raw_ostream &OS, const Record &Rec) { std::map, RISCVISAInfo::ExtensionComparator> Extensions; - unsigned XLen = 32; + unsigned XLen = 0; // Convert features to FeatureVector. for (auto *Feature : Rec.getValueAsListOfDefs("Features")) { @@ -36,10 +36,17 @@ static void printMArch(raw_ostream &OS, const Record &Rec) { unsigned Major = Feature->getValueAsInt("MajorVersion"); unsigned Minor = Feature->getValueAsInt("MinorVersion"); Extensions.try_emplace(FeatureName.str(), Major, Minor); - } else if (FeatureName == "64bit") + } else if (FeatureName == "64bit") { + assert(XLen == 0 && "Already determined XLen"); XLen = 64; + } else if (FeatureName == "32bit") { + assert(XLen == 0 && "Already determined XLen"); + XLen = 32; + } } + assert(XLen != 0 && "Unable to determine XLen"); + OS << "rv" << XLen; ListSeparator LS("_"); From df505d84b3782ac1043c78db8157264da416269f Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 19 Apr 2024 16:29:03 -0700 Subject: [PATCH 4/6] fixup! Add unit test --- llvm/test/TableGen/riscv-target-def.td | 96 ++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 llvm/test/TableGen/riscv-target-def.td diff --git a/llvm/test/TableGen/riscv-target-def.td b/llvm/test/TableGen/riscv-target-def.td new file mode 100644 index 0000000000000..f2ea3c6d4686a --- /dev/null +++ b/llvm/test/TableGen/riscv-target-def.td @@ -0,0 +1,96 @@ +// RUN: llvm-tblgen -gen-riscv-target-def -I %p/../../include %s | FileCheck %s + +include "llvm/Target/Target.td" + +class RISCVExtension implies = [], + string value = "true"> + : SubtargetFeature { + int MajorVersion = major; + int MinorVersion = minor; + bit Experimental = false; +} + +def FeatureStdExtI + : RISCVExtension<"i", 2, 1, "HasStdExtI", + "'I' (Base Integer Instruction Set)">; + +def FeatureStdExtZicsr + : RISCVExtension<"zicsr", 2, 0, "HasStdExtZicsr", + "'zicsr' (CSRs)">; + +def FeatureStdExtZifencei + : RISCVExtension<"zifencei", 2, 0, "HasStdExtZifencei", + "'Zifencei' (fence.i)">; + +def Feature32Bit + : SubtargetFeature<"32bit", "IsRV32", "true", "Implements RV32">; +def Feature64Bit + : SubtargetFeature<"64bit", "IsRV64", "true", "Implements RV64">; + +// Dummy feature that isn't an extension. +def FeatureDummy + : SubtargetFeature<"dummy", "Dummy", "true", "Dummy">; + +class RISCVProcessorModel f, + list tunef = [], + string default_march = ""> + : ProcessorModel { + string DefaultMarch = default_march; +} + +class RISCVTuneProcessorModel tunef = [], + list f = []> + : ProcessorModel; + +def GENERIC_RV32 : RISCVProcessorModel<"generic-rv32", + NoSchedModel, + [Feature32Bit, + FeatureStdExtI]>; +def GENERIC_RV64 : RISCVProcessorModel<"generic-rv64", + NoSchedModel, + [Feature64Bit, + FeatureStdExtI]>; +def GENERIC : RISCVTuneProcessorModel<"generic", NoSchedModel>; + + +def ROCKET_RV32 : RISCVProcessorModel<"rocket-rv32", + NoSchedModel, + [Feature32Bit, + FeatureStdExtI, + FeatureStdExtZifencei, + FeatureStdExtZicsr, + FeatureDummy]>; +def ROCKET_RV64 : RISCVProcessorModel<"rocket-rv64", + NoSchedModel, + [Feature64Bit, + FeatureStdExtI, + FeatureStdExtZifencei, + FeatureStdExtZicsr, + FeatureDummy]>; +def ROCKET : RISCVTuneProcessorModel<"rocket", + NoSchedModel>; + +// CHECK: #ifndef PROC +// CHECK: #define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGNED_ACCESS) +// CHECK: #endif + +// CHECK: PROC(GENERIC_RV32, {"generic-rv32"}, {"rv32i2p1"}, 0) +// CHECK: PROC(GENERIC_RV64, {"generic-rv64"}, {"rv64i2p1"}, 0) +// CHECK: PROC(ROCKET_RV32, {"rocket-rv32"}, {"rv32i2p1_zicsr2p0_zifencei2p0"}, 0) +// CHECK: PROC(ROCKET_RV64, {"rocket-rv64"}, {"rv64i2p1_zicsr2p0_zifencei2p0"}, 0) + +// CHECK: #undef PROC + +// CHECK: #ifndef TUNE_PROC +// CHECK: #define TUNE_PROC(ENUM, NAME) +// CHECK: #endif + +// CHECK: TUNE_PROC(GENERIC, "generic") +// CHECK: TUNE_PROC(ROCKET, "rocket") + +// CHECK: #undef TUNE_PROC From 75d26c40c1014a1beece6f8737c0c65d60a7b198 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sat, 20 Apr 2024 19:11:44 -0700 Subject: [PATCH 5/6] fixup! indentation --- llvm/test/TableGen/riscv-target-def.td | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/test/TableGen/riscv-target-def.td b/llvm/test/TableGen/riscv-target-def.td index f2ea3c6d4686a..ab589b31192f3 100644 --- a/llvm/test/TableGen/riscv-target-def.td +++ b/llvm/test/TableGen/riscv-target-def.td @@ -5,7 +5,7 @@ include "llvm/Target/Target.td" class RISCVExtension implies = [], string value = "true"> - : SubtargetFeature { + : SubtargetFeature { int MajorVersion = major; int MinorVersion = minor; bit Experimental = false; @@ -37,7 +37,7 @@ class RISCVProcessorModel f, list tunef = [], string default_march = ""> - : ProcessorModel { + : ProcessorModel { string DefaultMarch = default_march; } @@ -45,7 +45,7 @@ class RISCVTuneProcessorModel tunef = [], list f = []> - : ProcessorModel; + : ProcessorModel; def GENERIC_RV32 : RISCVProcessorModel<"generic-rv32", NoSchedModel, From 0135a83f4608bc19302fd54bf5db31de00ff76e5 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 22 Apr 2024 12:34:30 -0700 Subject: [PATCH 6/6] fixup! Use RISCVISAInfo::ExtensionVersion. --- llvm/utils/TableGen/RISCVTargetDefEmitter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp index d6a6e8b60c105..653e5c5fdb421 100644 --- a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp +++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp @@ -24,7 +24,7 @@ using namespace llvm; // This is almost the same as RISCVFeatures::parseFeatureBits, except that we // get feature name from feature records instead of feature bits. static void printMArch(raw_ostream &OS, const Record &Rec) { - std::map, + std::map Extensions; unsigned XLen = 0; @@ -35,7 +35,7 @@ static void printMArch(raw_ostream &OS, const Record &Rec) { if (Feature->isSubClassOf("RISCVExtension")) { unsigned Major = Feature->getValueAsInt("MajorVersion"); unsigned Minor = Feature->getValueAsInt("MinorVersion"); - Extensions.try_emplace(FeatureName.str(), Major, Minor); + Extensions[FeatureName.str()] = {Major, Minor}; } else if (FeatureName == "64bit") { assert(XLen == 0 && "Already determined XLen"); XLen = 64; @@ -51,7 +51,7 @@ static void printMArch(raw_ostream &OS, const Record &Rec) { ListSeparator LS("_"); for (auto const &Ext : Extensions) - OS << LS << Ext.first << Ext.second.first << 'p' << Ext.second.second; + OS << LS << Ext.first << Ext.second.Major << 'p' << Ext.second.Minor; } static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) {