[PATCH] D137517: [TargetSupport] Generate the defs for RISCV CPUs using llvm-tblgen.

Wang Pengcheng via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 7 19:25:10 PST 2022


pcwang-thead added a comment.

A rough implementation just for your reference:

  diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
  index 47e11b9a1eab..f91f969c2b17 100644
  --- a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
  +++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
  @@ -14,6 +14,32 @@
   #include "llvm/TableGen/Record.h"
   
   namespace llvm {
  +struct CPUInfo {
  +  std::string EnumName;
  +  std::string MArch;
  +  std::string Features;
  +};
  +
  +static CPUInfo getCPUInfoFromFeatures(const Record &Record) {
  +  std::string EnumName = Record.getValueAsString("Name").upper();
  +  EnumName = EnumName.replace(EnumName.find_first_of('-'), 1, "_");
  +  std::string MArch;
  +  // FIXME: MArch should be in alphabetical order.
  +  std::string Features;
  +  for (auto *Feature : Record.getValueAsListOfDefs("Features")) {
  +    StringRef FeatureName = Feature->getValueAsString("Name");
  +    if (FeatureName == "32bit") {
  +      MArch += "rv32i";
  +      Features = "FK_NONE";
  +    } else if (FeatureName == "64bit") {
  +      MArch += "rv64i";
  +      Features = "FK_64BIT";
  +    } else
  +      MArch += FeatureName;
  +  }
  +  return {EnumName, MArch, Features};
  +}
  +
   void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) {
     const auto &Map = RK.getDefs();
   
  @@ -26,11 +52,17 @@ void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) {
     for (auto &Def : Map) {
       const auto &Record = Def.second;
       if (Record->isSubClassOf("RISCVProcessorModelPROC") &&
  -        Record->isSubClassOf("ProcessorModel"))
  +        Record->isSubClassOf("ProcessorModel")) {
         OS << "PROC(" << Record->getValueAsString("Enum") << ", "
            << "{\"" << Record->getValueAsString("Name") << "\"}, "
            << Record->getValueAsString("EnumFeatures") << ", "
            << "{\"" << Record->getValueAsString("DefaultMarch") << "\"})\n";
  +      const CPUInfo &Info = getCPUInfoFromFeatures(*Record);
  +      OS << "// PROC(" << Info.EnumName << ", "
  +         << "{\"" << Record->getValueAsString("Name") << "\"}, "
  +         << Info.Features << ", "
  +         << "{\"" << Info.MArch << "\"})\n";
  +    }
     }
     OS << "\n#undef PROC\n";
     OS << "\n";

The generated header would be like:

  #ifndef PROC
  #define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH)
  #endif
  
  PROC(INVALID, {"invalid"}, FK_INVALID, {""})
  PROC(GENERIC_RV32, {"generic-rv32"}, FK_NONE, {""})
  // PROC(GENERIC_RV32, {"generic-rv32"}, FK_NONE, {"rv32i"})
  PROC(GENERIC_RV64, {"generic-rv64"}, FK_64BIT, {""})
  // PROC(GENERIC_RV64, {"generic-rv64"}, FK_64BIT, {"rv64i"})
  PROC(ROCKET_RV32, {"rocket-rv32"}, FK_NONE, {""})
  // PROC(ROCKET_RV32, {"rocket-rv32"}, FK_NONE, {"rv32i"})
  PROC(ROCKET_RV64, {"rocket-rv64"}, FK_64BIT, {""})
  // PROC(ROCKET_RV64, {"rocket-rv64"}, FK_64BIT, {"rv64i"})
  PROC(SIFIVE_E20, {"sifive-e20"}, FK_NONE, {"rv32imc"})
  // PROC(SIFIVE_E20, {"sifive-e20"}, FK_NONE, {"rv32imc"})
  PROC(SIFIVE_E21, {"sifive-e21"}, FK_NONE, {"rv32imac"})
  // PROC(SIFIVE_E21, {"sifive-e21"}, FK_NONE, {"rv32imac"})
  PROC(SIFIVE_E24, {"sifive-e24"}, FK_NONE, {"rv32imafc"})
  // PROC(SIFIVE_E24, {"sifive-e24"}, FK_NONE, {"rv32imafc"})
  PROC(SIFIVE_E31, {"sifive-e31"}, FK_NONE, {"rv32imac"})
  // PROC(SIFIVE_E31, {"sifive-e31"}, FK_NONE, {"rv32imac"})
  PROC(SIFIVE_E34, {"sifive-e34"}, FK_NONE, {"rv32imafc"})
  // PROC(SIFIVE_E34, {"sifive-e34"}, FK_NONE, {"rv32imafc"})
  PROC(SIFIVE_E76, {"sifive-e76"}, FK_NONE, {"rv32imafc"})
  // PROC(SIFIVE_E76, {"sifive-e76"}, FK_NONE, {"rv32imafc"})
  PROC(SIFIVE_S21, {"sifive-s21"}, FK_64BIT, {"rv64imac"})
  // PROC(SIFIVE_S21, {"sifive-s21"}, FK_64BIT, {"rv64imac"})
  PROC(SIFIVE_S51, {"sifive-s51"}, FK_64BIT, {"rv64imac"})
  // PROC(SIFIVE_S51, {"sifive-s51"}, FK_64BIT, {"rv64imac"})
  PROC(SIFIVE_S54, {"sifive-s54"}, FK_64BIT, {"rv64gc"})
  // PROC(SIFIVE_S54, {"sifive-s54"}, FK_64BIT, {"rv64imafdc"})
  PROC(SIFIVE_S76, {"sifive-s76"}, FK_64BIT, {"rv64gc"})
  // PROC(SIFIVE_S76, {"sifive-s76"}, FK_64BIT, {"rv64imafdc"})
  PROC(SIFIVE_U54, {"sifive-u54"}, FK_64BIT, {"rv64gc"})
  // PROC(SIFIVE_U54, {"sifive-u54"}, FK_64BIT, {"rv64imafdc"})
  PROC(SIFIVE_U74, {"sifive-u74"}, FK_64BIT, {"rv64gc"})
  // PROC(SIFIVE_U74, {"sifive-u74"}, FK_64BIT, {"rv64imafdc"})
  
  #undef PROC
  
  #ifndef TUNE_PROC
  #define TUNE_PROC(ENUM, NAME)
  #endif
  
  TUNE_PROC(GENERIC, "generic")
  TUNE_PROC(ROCKET, "rocket")
  TUNE_PROC(SIFIVE_7, "sifive-7-series")
  
  #undef TUNE_PROC

---

> My preference would be to keep the Enum explicit as it would help using those enums in the code. Also, sometimes the enum cannot be derived from the Name (see for example "sifive-7-series" vs "SIFIVE_7").

I believe that we can change it to "SIFIVE-7-SERIES" since this enum name haven't been used in anywhere and it's just an enum name. :-)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137517/new/

https://reviews.llvm.org/D137517



More information about the llvm-commits mailing list