[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