[clang] [llvm] [RFC][RISCV] Support RISC-V Profiles in -march option (PR #76357)

Wang Pengcheng via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 25 03:06:01 PST 2023


https://github.com/wangpc-pp updated https://github.com/llvm/llvm-project/pull/76357

>From 806babf92282735c364b7ac88faa5256d04f2742 Mon Sep 17 00:00:00 2001
From: wangpc <wangpengcheng.pp at bytedance.com>
Date: Mon, 25 Dec 2023 18:52:36 +0800
Subject: [PATCH] [RFC][RISCV] Support RISC-V Profiles in -march option

This PR implements the draft
https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/36.

Currently, we replace specified profile in `-march` with standard
arch string.

We may need to pass it to backend so that we can emit an ELF attr
proposed by
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/409.
---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp    |  7 +-
 clang/test/Driver/riscv-profiles.c            | 79 +++++++++++++++++++
 llvm/include/llvm/TargetParser/CMakeLists.txt |  1 +
 .../llvm/TargetParser/RISCVTargetParser.h     |  1 +
 llvm/lib/Target/RISCV/RISCV.td                |  6 ++
 llvm/lib/Target/RISCV/RISCVProfiles.td        | 70 ++++++++++++++++
 llvm/lib/TargetParser/RISCVTargetParser.cpp   | 24 ++++++
 llvm/utils/TableGen/RISCVTargetDefEmitter.cpp | 19 +++++
 8 files changed, 205 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Driver/riscv-profiles.c
 create mode 100644 llvm/lib/Target/RISCV/RISCVProfiles.td

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 25b43cefce6b57..87ec51b89547c5 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -277,8 +277,11 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
   // instead of `rv{XLEN}gc` though they are (currently) equivalent.
 
   // 1. If `-march=` is specified, use it.
-  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
-    return A->getValue();
+  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+    StringRef Value = A->getValue();
+    StringRef MArchFromProfile = llvm::RISCV::getMArchFromProfile(Value);
+    return MArchFromProfile.empty() ? Value : MArchFromProfile;
+  }
 
   // 2. Get march (isa string) based on `-mcpu=`
   if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
diff --git a/clang/test/Driver/riscv-profiles.c b/clang/test/Driver/riscv-profiles.c
new file mode 100644
index 00000000000000..375d4fc10db6ca
--- /dev/null
+++ b/clang/test/Driver/riscv-profiles.c
@@ -0,0 +1,79 @@
+// RUN: %clang -### -c %s 2>&1 -march=RVI20U32 | FileCheck -check-prefix=RVI20U32 %s
+// RVI20U32: "-target-cpu" "generic-rv32"
+// RVI20U32: "-target-feature" "-a"
+// RVI20U32: "-target-feature" "-c"
+// RVI20U32: "-target-feature" "-d"
+// RVI20U32: "-target-feature" "-f"
+// RVI20U32: "-target-feature" "-m"
+// RVI20U32: "-target-abi" "ilp32"
+
+// RUN: %clang -### -c %s 2>&1 -march=RVI20U64 | FileCheck -check-prefix=RVI20U64 %s
+// RVI20U64: "-target-cpu" "generic-rv64"
+// RVI20U64: "-target-feature" "-a"
+// RVI20U64: "-target-feature" "-c"
+// RVI20U64: "-target-feature" "-d"
+// RVI20U64: "-target-feature" "-f"
+// RVI20U64: "-target-feature" "-m"
+// RVI20U64: "-target-abi" "lp64"
+
+// RUN: %clang -### -c %s 2>&1 -march=RVA20U64 | FileCheck -check-prefix=RVA20U64 %s
+// RVA20U64: "-target-cpu" "generic-rv64"
+// RVA20U64: "-target-feature" "+m"
+// RVA20U64: "-target-feature" "+a"
+// RVA20U64: "-target-feature" "+f"
+// RVA20U64: "-target-feature" "+d"
+// RVA20U64: "-target-feature" "+c"
+// RVA20U64: "-target-feature" "+zicsr"
+// RVA20U64: "-target-abi" "lp64d"
+
+// RUN: %clang -### -c %s 2>&1 -march=RVA20S64 | FileCheck -check-prefix=RVA20S64 %s
+// RVA20S64: "-target-cpu" "generic-rv64"
+// RVA20S64: "-target-feature" "+m"
+// RVA20S64: "-target-feature" "+a"
+// RVA20S64: "-target-feature" "+f"
+// RVA20S64: "-target-feature" "+d"
+// RVA20S64: "-target-feature" "+c"
+// RVA20S64: "-target-feature" "+zicsr"
+// RVA20S64: "-target-feature" "+zifencei"
+// RVA20S64: "-target-abi" "lp64d"
+
+// RUN: %clang -### -c %s 2>&1 -march=RVA22U64 | FileCheck -check-prefix=RVA22U64 %s
+// RVA22U64: "-target-cpu" "generic-rv64"
+// RVA22U64: "-target-feature" "+m"
+// RVA22U64: "-target-feature" "+a"
+// RVA22U64: "-target-feature" "+f"
+// RVA22U64: "-target-feature" "+d"
+// RVA22U64: "-target-feature" "+c"
+// RVA22U64: "-target-feature" "+zicbom"
+// RVA22U64: "-target-feature" "+zicbop"
+// RVA22U64: "-target-feature" "+zicboz"
+// RVA22U64: "-target-feature" "+zicsr"
+// RVA22U64: "-target-feature" "+zihintpause"
+// RVA22U64: "-target-feature" "+zfhmin" 
+// RVA22U64: "-target-feature" "+zba"
+// RVA22U64: "-target-feature" "+zbb"
+// RVA22U64: "-target-feature" "+zbs"
+// RVA22U64: "-target-feature" "+zkt"
+// RVA22U64: "-target-abi" "lp64d"
+
+// RUN: %clang -### -c %s 2>&1 -march=RVA22S64 | FileCheck -check-prefix=RVA22S64 %s
+// RVA22S64: "-target-cpu" "generic-rv64"
+// RVA22S64: "-target-feature" "+m"
+// RVA22S64: "-target-feature" "+a"
+// RVA22S64: "-target-feature" "+f"
+// RVA22S64: "-target-feature" "+d"
+// RVA22S64: "-target-feature" "+c"
+// RVA22S64: "-target-feature" "+zicbom"
+// RVA22S64: "-target-feature" "+zicbop"
+// RVA22S64: "-target-feature" "+zicboz"
+// RVA22S64: "-target-feature" "+zicsr"
+// RVA22S64: "-target-feature" "+zifencei"
+// RVA22S64: "-target-feature" "+zihintpause"
+// RVA22S64: "-target-feature" "+zfhmin" 
+// RVA22S64: "-target-feature" "+zba"
+// RVA22S64: "-target-feature" "+zbb"
+// RVA22S64: "-target-feature" "+zbs"
+// RVA22S64: "-target-feature" "+zkt"
+// RVA22S64: "-target-feature" "+svinval"
+// RVA22S64: "-target-feature" "+svpbmt"
+// RVA22S64: "-target-abi" "lp64d"
diff --git a/llvm/include/llvm/TargetParser/CMakeLists.txt b/llvm/include/llvm/TargetParser/CMakeLists.txt
index 7f080e01548c7c..6eaadd1a480891 100644
--- a/llvm/include/llvm/TargetParser/CMakeLists.txt
+++ b/llvm/include/llvm/TargetParser/CMakeLists.txt
@@ -1,3 +1,4 @@
 set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/RISCV/RISCV.td)
 tablegen(LLVM RISCVTargetParserDef.inc -gen-riscv-target-def -I ${PROJECT_SOURCE_DIR}/lib/Target/RISCV/)
+tablegen(LLVM RISCVProfileDef.inc -gen-riscv-profile-def -I ${PROJECT_SOURCE_DIR}/lib/Target/RISCV/)
 add_public_tablegen_target(RISCVTargetParserTableGen)
diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
index e7da677c7d3ead..571777a8946499 100644
--- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h
+++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
@@ -28,6 +28,7 @@ static constexpr unsigned RVVBitsPerBlock = 64;
 bool parseCPU(StringRef CPU, bool IsRV64);
 bool parseTuneCPU(StringRef CPU, bool IsRV64);
 StringRef getMArchFromMcpu(StringRef CPU);
+StringRef getMArchFromProfile(StringRef Profile);
 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
 void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
 bool hasFastUnalignedAccess(StringRef CPU);
diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index be93d5933d3329..b08a7686ff1265 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -44,6 +44,12 @@ include "RISCVSchedSyntacoreSCR1.td"
 
 include "RISCVProcessors.td"
 
+//===----------------------------------------------------------------------===//
+// RISC-V profiles supported.
+//===----------------------------------------------------------------------===//
+
+include "RISCVProfiles.td"
+
 //===----------------------------------------------------------------------===//
 // Define the RISC-V target.
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVProfiles.td b/llvm/lib/Target/RISCV/RISCVProfiles.td
new file mode 100644
index 00000000000000..da9dcf9f3f812e
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVProfiles.td
@@ -0,0 +1,70 @@
+//===-- RISCVProfiles.td - RISC-V Profiles -------------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+class RISCVProfile<string name, list<SubtargetFeature> features> {
+  string Name = name;
+  list<SubtargetFeature> Features = features;
+}
+
+def RVI20U32 : RISCVProfile<"RVI20U32", [Feature32Bit]>;
+
+def RVI20U64 : RISCVProfile<"RVI20U64", [Feature64Bit]>;
+
+def RVA20U64 : RISCVProfile<"RVA20U64", [Feature64Bit,
+                                         FeatureStdExtM,
+                                         FeatureStdExtA,
+                                         FeatureStdExtF,
+                                         FeatureStdExtD,
+                                         FeatureStdExtC,
+                                         FeatureStdExtZicsr]>;
+
+def RVA20S64 : RISCVProfile<"RVA20S64", [Feature64Bit,
+                                         FeatureStdExtM,
+                                         FeatureStdExtA,
+                                         FeatureStdExtF,
+                                         FeatureStdExtD,
+                                         FeatureStdExtC,
+                                         FeatureStdExtZicsr,
+                                         FeatureStdExtZifencei]>;
+
+def RVA22U64 : RISCVProfile<"RVA22U64", [Feature64Bit,
+                                         FeatureStdExtM,
+                                         FeatureStdExtA,
+                                         FeatureStdExtF,
+                                         FeatureStdExtD,
+                                         FeatureStdExtC,
+                                         FeatureStdExtZba,
+                                         FeatureStdExtZbb,
+                                         FeatureStdExtZbs,
+                                         FeatureStdExtZfhmin,
+                                         FeatureStdExtZicbom,
+                                         FeatureStdExtZicbop,
+                                         FeatureStdExtZicboz,
+                                         FeatureStdExtZkt,
+                                         FeatureStdExtZicsr,
+                                         FeatureStdExtZihintpause]>;
+
+def RVA22S64 : RISCVProfile<"RVA22S64", [Feature64Bit,
+                                         FeatureStdExtM,
+                                         FeatureStdExtA,
+                                         FeatureStdExtF,
+                                         FeatureStdExtD,
+                                         FeatureStdExtC,
+                                         FeatureStdExtZba,
+                                         FeatureStdExtZbb,
+                                         FeatureStdExtZbs,
+                                         FeatureStdExtZfhmin,
+                                         FeatureStdExtZicbom,
+                                         FeatureStdExtZicbop,
+                                         FeatureStdExtZicboz,
+                                         FeatureStdExtZkt,
+                                         FeatureStdExtZicsr,
+                                         FeatureStdExtZifencei,
+                                         FeatureStdExtZihintpause,
+                                         FeatureStdExtSvpbmt,
+                                         FeatureStdExtSvinval]>;
\ No newline at end of file
diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp
index 85cdd1289a9538..c24b87afc7e45c 100644
--- a/llvm/lib/TargetParser/RISCVTargetParser.cpp
+++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp
@@ -32,12 +32,22 @@ struct CPUInfo {
   bool is64Bit() const { return DefaultMarch.starts_with("rv64"); }
 };
 
+struct ProfileInfo {
+  StringLiteral Name;
+  StringLiteral March;
+};
+
 constexpr CPUInfo RISCVCPUInfo[] = {
 #define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGN)                          \
   {NAME, DEFAULT_MARCH, FAST_UNALIGN},
 #include "llvm/TargetParser/RISCVTargetParserDef.inc"
 };
 
+constexpr ProfileInfo RISCVProfileInfo[] = {
+#define PROFILE(ENUM, NAME, MARCH) {NAME, MARCH},
+#include "llvm/TargetParser/RISCVProfileDef.inc"
+};
+
 static const CPUInfo *getCPUInfoByName(StringRef CPU) {
   for (auto &C : RISCVCPUInfo)
     if (C.Name == CPU)
@@ -45,6 +55,13 @@ static const CPUInfo *getCPUInfoByName(StringRef CPU) {
   return nullptr;
 }
 
+static const ProfileInfo *getProfileInfoByName(StringRef Profile) {
+  for (auto &C : RISCVProfileInfo)
+    if (C.Name == Profile)
+      return &C;
+  return nullptr;
+}
+
 bool hasFastUnalignedAccess(StringRef CPU) {
   const CPUInfo *Info = getCPUInfoByName(CPU);
   return Info && Info->FastUnalignedAccess;
@@ -79,6 +96,13 @@ StringRef getMArchFromMcpu(StringRef CPU) {
   return Info->DefaultMarch;
 }
 
+StringRef getMArchFromProfile(StringRef Profile) {
+  const ProfileInfo *Info = getProfileInfoByName(Profile);
+  if (!Info)
+    return "";
+  return Info->March;
+}
+
 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) {
   for (const auto &C : RISCVCPUInfo) {
     if (IsRV64 == C.is64Bit())
diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
index 7a6439cb94910e..6f177ed272aafc 100644
--- a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
@@ -85,5 +85,24 @@ static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) {
   OS << "\n#undef TUNE_PROC\n";
 }
 
+static void emitRISCVProfileDef(RecordKeeper &RK, raw_ostream &OS) {
+  OS << "#ifndef PROFILE\n"
+     << "#define PROFILE(ENUM, NAME, MARCH)\n"
+     << "#endif\n\n";
+
+  // Iterate on all definition records.
+  for (const Record *Rec : RK.getAllDerivedDefinitions("RISCVProfile")) {
+    std::string MArch = getMArch(*Rec);
+
+    OS << "PROFILE(" << Rec->getName() << ", "
+       << "{\"" << Rec->getValueAsString("Name") << "\"}, "
+       << "{\"" << MArch << "\"})\n";
+  }
+  OS << "\n#undef PROFILE\n";
+}
+
 static TableGen::Emitter::Opt X("gen-riscv-target-def", EmitRISCVTargetDef,
                                 "Generate the list of CPU for RISCV");
+
+static TableGen::Emitter::Opt Y("gen-riscv-profile-def", emitRISCVProfileDef,
+                                "Generate the list of profiles for RISCV");



More information about the cfe-commits mailing list