[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