From ac1ffd3caca12c254e0b8c847aa8ce8e51b6cfbf Mon Sep 17 00:00:00 2001 From: Francesco Petrogalli Date: Wed, 11 Jan 2023 10:23:55 +0100 Subject: [PATCH] [TargetParser] Generate the defs for RISCV CPUs using llvm-tblgen. Rework the change to prevent build failures. NFCI. The failing code was submitted as cf7a8305a2b4ddfd299c748136cb9a2960ef7089 and reverted via 8bd65e535fb33bc48805bafed8217b16a853e158. The rework in this new commit prevents failures like the following: FAILED: tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/Targets/RISCV.cpp.o /usr/bin/c++ [bunch of non interesting stuff] -c /llvm-project/clang/lib/Basic/Targets/RISCV.cpp In file included from /llvm-project/clang/lib/Basic/Targets/RISCV.cpp:19: /llvm-project/llvm/include/llvm/TargetParser/RISCVTargetParser.h:29:10: fatal error: llvm/TargetParser/RISCVTargetParserDef.inc: No such file or directory 29 | #include "llvm/TargetParser/RISCVTargetParserDef.inc" | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These failures happen because the library LLVMTargetParser depends on RISCVTargetParserTableGen, which is a tablegen target that generates the list of CPUs in llvm/TargetParser/RISCVTargetParserDef.inc. This *.inc file is included by the public header file llvm/TargetParser/RISCVTargetParser.h. The header file llvm/TargetParser/RISCVTargetParser.h is also used in components (clangDriver and clangBasic) that link into LLVMTargetParser, but on some configurations such components might end up being built before TargetParser is ready. The fix is to make sure that clangDriver and clangBasic depend on the tablegen target RISCVTargetParserTableGen, which generates the .inc file whether or not LLVMTargetParser is ready. WRT the original patch at https://reviews.llvm.org/D137517, this commit is just adding RISCVTargetParserTableGen in the DEPENDS list of clangDriver and clangBasic. --- clang/lib/Basic/CMakeLists.txt | 1 + clang/lib/Basic/Targets/RISCV.cpp | 2 +- clang/lib/Driver/CMakeLists.txt | 1 + clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 2 +- llvm/include/llvm/CMakeLists.txt | 1 + llvm/include/llvm/TargetParser/CMakeLists.txt | 4 + .../llvm/TargetParser/RISCVTargetParser.def | 35 --- llvm/include/llvm/TargetParser/RISCVTargetParser.h | 50 +++++ llvm/include/llvm/TargetParser/TargetParser.h | 28 --- llvm/include/llvm/module.extern.modulemap | 1 + llvm/include/llvm/module.install.modulemap | 4 + llvm/include/llvm/module.modulemap | 11 +- llvm/lib/Target/RISCV/RISCV.td | 246 +++++++++++++-------- llvm/lib/Target/RISCV/RISCVISelLowering.h | 2 +- llvm/lib/TargetParser/CMakeLists.txt | 5 +- llvm/lib/TargetParser/RISCVTargetParser.cpp | 104 +++++++++ llvm/lib/TargetParser/TargetParser.cpp | 86 ------- llvm/utils/TableGen/CMakeLists.txt | 1 + llvm/utils/TableGen/RISCVTargetDefEmitter.cpp | 62 ++++++ llvm/utils/TableGen/TableGen.cpp | 9 +- llvm/utils/TableGen/TableGenBackends.h | 1 + 21 files changed, 411 insertions(+), 245 deletions(-) create mode 100644 llvm/include/llvm/TargetParser/CMakeLists.txt delete mode 100644 llvm/include/llvm/TargetParser/RISCVTargetParser.def create mode 100644 llvm/include/llvm/TargetParser/RISCVTargetParser.h create mode 100644 llvm/lib/TargetParser/RISCVTargetParser.cpp create mode 100644 llvm/utils/TableGen/RISCVTargetDefEmitter.cpp diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index 936709d..32af83e 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -110,6 +110,7 @@ add_clang_library(clangBasic DEPENDS omp_gen + RISCVTargetParserTableGen ) target_link_libraries(clangBasic diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 7713398..a9adafd 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -15,8 +15,8 @@ #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/TargetParser.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/RISCVTargetParser.h" #include using namespace clang; diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 0b6ce91..ba56a93 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -93,6 +93,7 @@ add_clang_library(clangDriver DEPENDS ClangDriverOptions + RISCVTargetParserTableGen LINK_LIBS clangBasic diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index 4724e5c..5c11064 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -17,8 +17,8 @@ #include "llvm/Support/Error.h" #include "llvm/Support/Host.h" #include "llvm/Support/RISCVISAInfo.h" -#include "llvm/Support/TargetParser.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/RISCVTargetParser.h" using namespace clang::driver; using namespace clang::driver::tools; diff --git a/llvm/include/llvm/CMakeLists.txt b/llvm/include/llvm/CMakeLists.txt index b46319f..d1dc0a9 100644 --- a/llvm/include/llvm/CMakeLists.txt +++ b/llvm/include/llvm/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(IR) add_subdirectory(Support) add_subdirectory(Frontend) +add_subdirectory(TargetParser) # If we're doing an out-of-tree build, copy a module map for generated # header files into the build area. diff --git a/llvm/include/llvm/TargetParser/CMakeLists.txt b/llvm/include/llvm/TargetParser/CMakeLists.txt new file mode 100644 index 0000000..d102dcf --- /dev/null +++ b/llvm/include/llvm/TargetParser/CMakeLists.txt @@ -0,0 +1,4 @@ +set(LLVM_TARGET_DEFINITIONS ${CMAKE_SOURCE_DIR}/lib/Target/RISCV/RISCV.td) +tablegen(LLVM RISCVTargetParserDef.inc -gen-riscv-target-def -I ${CMAKE_SOURCE_DIR}/lib/Target/RISCV/) +add_public_tablegen_target(RISCVTargetParserTableGen) + diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.def b/llvm/include/llvm/TargetParser/RISCVTargetParser.def deleted file mode 100644 index 6d65ac1..0000000 --- a/llvm/include/llvm/TargetParser/RISCVTargetParser.def +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef PROC -#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) -#endif - -PROC(INVALID, {"invalid"}, FK_INVALID, {""}) -PROC(GENERIC_RV32, {"generic-rv32"}, FK_NONE, {""}) -PROC(GENERIC_RV64, {"generic-rv64"}, FK_64BIT, {""}) -PROC(ROCKET_RV32, {"rocket-rv32"}, FK_NONE, {""}) -PROC(ROCKET_RV64, {"rocket-rv64"}, FK_64BIT, {""}) -PROC(SIFIVE_E20, {"sifive-e20"}, FK_NONE, {"rv32imc"}) -PROC(SIFIVE_E21, {"sifive-e21"}, FK_NONE, {"rv32imac"}) -PROC(SIFIVE_E24, {"sifive-e24"}, FK_NONE, {"rv32imafc"}) -PROC(SIFIVE_E31, {"sifive-e31"}, FK_NONE, {"rv32imac"}) -PROC(SIFIVE_E34, {"sifive-e34"}, FK_NONE, {"rv32imafc"}) -PROC(SIFIVE_E76, {"sifive-e76"}, FK_NONE, {"rv32imafc"}) -PROC(SIFIVE_S21, {"sifive-s21"}, FK_64BIT, {"rv64imac"}) -PROC(SIFIVE_S51, {"sifive-s51"}, FK_64BIT, {"rv64imac"}) -PROC(SIFIVE_S54, {"sifive-s54"}, FK_64BIT, {"rv64gc"}) -PROC(SIFIVE_S76, {"sifive-s76"}, FK_64BIT, {"rv64gc"}) -PROC(SIFIVE_U54, {"sifive-u54"}, FK_64BIT, {"rv64gc"}) -PROC(SIFIVE_U74, {"sifive-u74"}, FK_64BIT, {"rv64gc"}) -PROC(SYNTACORE_SCR1_BASE, {"syntacore-scr1-base"}, FK_NONE, {"rv32ic"}) -PROC(SYNTACORE_SCR1_MAX, {"syntacore-scr1-max"}, FK_NONE, {"rv32imc"}) - -#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 diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h new file mode 100644 index 0000000..85819e1 --- /dev/null +++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h @@ -0,0 +1,50 @@ +//===-- RISCVTargetParser - Parser for target features ----------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file implements a target parser to recognise hardware features +// FOR RISC-V CPUS. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGETPARSER_RISCVTARGETPARSER_H +#define LLVM_TARGETPARSER_RISCVTARGETPARSER_H + +#include "llvm/ADT/StringRef.h" +#include + +namespace llvm { +namespace RISCV { + +// We use 64 bits as the known part in the scalable vector types. +static constexpr unsigned RVVBitsPerBlock = 64; + +enum CPUKind : unsigned { +#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) CK_##ENUM, +#define TUNE_PROC(ENUM, NAME) CK_##ENUM, +#include "llvm/TargetParser/RISCVTargetParserDef.inc" +}; + +enum FeatureKind : unsigned { + FK_INVALID = 0, + FK_NONE = 1, + FK_64BIT = 1 << 2, +}; + +bool checkCPUKind(CPUKind Kind, bool IsRV64); +bool checkTuneCPUKind(CPUKind Kind, bool IsRV64); +CPUKind parseCPUKind(StringRef CPU); +CPUKind parseTuneCPUKind(StringRef CPU, bool IsRV64); +StringRef getMArchFromMcpu(StringRef CPU); +void fillValidCPUArchList(SmallVectorImpl &Values, bool IsRV64); +void fillValidTuneCPUArchList(SmallVectorImpl &Values, bool IsRV64); +bool getCPUFeaturesExceptStdExt(CPUKind Kind, std::vector &Features); + +} // namespace RISCV +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/TargetParser/TargetParser.h b/llvm/include/llvm/TargetParser/TargetParser.h index d986d83..243eaff 100644 --- a/llvm/include/llvm/TargetParser/TargetParser.h +++ b/llvm/include/llvm/TargetParser/TargetParser.h @@ -154,34 +154,6 @@ void fillValidArchListR600(SmallVectorImpl &Values); IsaVersion getIsaVersion(StringRef GPU); } // namespace AMDGPU - -namespace RISCV { - -// We use 64 bits as the known part in the scalable vector types. -static constexpr unsigned RVVBitsPerBlock = 64; - -enum CPUKind : unsigned { -#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) CK_##ENUM, -#define TUNE_PROC(ENUM, NAME) CK_##ENUM, -#include "RISCVTargetParser.def" -}; - -enum FeatureKind : unsigned { - FK_INVALID = 0, - FK_NONE = 1, - FK_64BIT = 1 << 2, -}; - -bool checkCPUKind(CPUKind Kind, bool IsRV64); -bool checkTuneCPUKind(CPUKind Kind, bool IsRV64); -CPUKind parseCPUKind(StringRef CPU); -CPUKind parseTuneCPUKind(StringRef CPU, bool IsRV64); -StringRef getMArchFromMcpu(StringRef CPU); -void fillValidCPUArchList(SmallVectorImpl &Values, bool IsRV64); -void fillValidTuneCPUArchList(SmallVectorImpl &Values, bool IsRV64); -bool getCPUFeaturesExceptStdExt(CPUKind Kind, std::vector &Features); - -} // namespace RISCV } // namespace llvm #endif diff --git a/llvm/include/llvm/module.extern.modulemap b/llvm/include/llvm/module.extern.modulemap index 8acda13..8e726a3 100644 --- a/llvm/include/llvm/module.extern.modulemap +++ b/llvm/include/llvm/module.extern.modulemap @@ -3,3 +3,4 @@ module LLVM_Extern_IR_Attributes_Gen {} module LLVM_Extern_IR_Intrinsics_Gen {} module LLVM_Extern_IR_Intrinsics_Enum {} module LLVM_Extern_Utils_DataTypes {} +module LLVM_Extern_TargetParser_Gen {} diff --git a/llvm/include/llvm/module.install.modulemap b/llvm/include/llvm/module.install.modulemap index ac73a86..1be5921 100644 --- a/llvm/include/llvm/module.install.modulemap +++ b/llvm/include/llvm/module.install.modulemap @@ -25,3 +25,7 @@ module LLVM_Extern_Utils_DataTypes { header "Support/DataTypes.h" export * } + +module LLVM_Extern_TargetParser_Gen { + textual header "TargetParser/RISCVTargetParserDef.inc" +} diff --git a/llvm/include/llvm/module.modulemap b/llvm/include/llvm/module.modulemap index 4f9d1fb..06c4e63 100644 --- a/llvm/include/llvm/module.modulemap +++ b/llvm/include/llvm/module.modulemap @@ -391,6 +391,16 @@ module LLVM_Transforms { extern module LLVM_Extern_Utils_DataTypes "module.extern.modulemap" +// Build the module with the tablegen-generated files needed by the +// TargetParser module before building the TargetParser module itself. +module TargetParserGen { + module RISCVTargetParserDef { + header "TargetParser/RISCVTargetParser.h" + extern module LLVM_Extern_TargetParser_Gen "module.extern.modulemap" + export * + } +} + // A module covering ADT/ and Support/. These are intertwined and // codependent, and notionally form a single module. module LLVM_Utils { @@ -427,7 +437,6 @@ module LLVM_Utils { textual header "TargetParser/AArch64TargetParser.def" textual header "TargetParser/ARMTargetParser.def" textual header "TargetParser/CSKYTargetParser.def" - textual header "TargetParser/RISCVTargetParser.def" textual header "TargetParser/X86TargetParser.def" textual header "TargetParser/LoongArchTargetParser.def" } diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td index 0e9b88b..1f78532 100644 --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -573,99 +573,167 @@ include "RISCVSchedSyntacoreSCR1.td" // RISC-V processors supported. //===----------------------------------------------------------------------===// -def : ProcessorModel<"generic-rv32", NoSchedModel, [Feature32Bit]>; -def : ProcessorModel<"generic-rv64", NoSchedModel, [Feature64Bit]>; +class RISCVProcessorModel f, + string default_march = "", + list tunef = []> + : ProcessorModel { + string DefaultMarch = default_march; +} + +class RISCVTuneProcessorModel tunef = [], + list f = []> + : ProcessorModel; + +def GENERIC_RV32 : RISCVProcessorModel<"generic-rv32", + NoSchedModel, + [Feature32Bit]>; +def GENERIC_RV64 : RISCVProcessorModel<"generic-rv64", + NoSchedModel, + [Feature64Bit]>; // Support generic for compatibility with other targets. The triple will be used // to change to the appropriate rv32/rv64 version. def : ProcessorModel<"generic", NoSchedModel, []>; -def : ProcessorModel<"rocket-rv32", RocketModel, [Feature32Bit]>; -def : ProcessorModel<"rocket-rv64", RocketModel, [Feature64Bit]>; -def : ProcessorModel<"rocket", RocketModel, []>; - -def : ProcessorModel<"sifive-7-series", SiFive7Model, [], - [TuneSiFive7]>; - -def : ProcessorModel<"sifive-e20", RocketModel, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-e21", RocketModel, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-e24", RocketModel, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-e31", RocketModel, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-e34", RocketModel, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-e76", SiFive7Model, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtC], - [TuneSiFive7]>; - -def : ProcessorModel<"sifive-s21", RocketModel, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-s51", RocketModel, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-s54", RocketModel, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtD, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-s76", SiFive7Model, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtD, - FeatureStdExtC], - [TuneSiFive7]>; - -def : ProcessorModel<"sifive-u54", RocketModel, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtD, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-u74", SiFive7Model, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtD, - FeatureStdExtC], - [TuneSiFive7]>; - -def : ProcessorModel<"syntacore-scr1-base", SyntacoreSCR1Model, - [Feature32Bit, FeatureStdExtC], - [TuneNoDefaultUnroll]>; - -def : ProcessorModel<"syntacore-scr1-max", SyntacoreSCR1Model, - [Feature32Bit, FeatureStdExtM, FeatureStdExtC], - [TuneNoDefaultUnroll]>; +def ROCKET_RV32 : RISCVProcessorModel<"rocket-rv32", + RocketModel, + [Feature32Bit]>; +def ROCKET_RV64 : RISCVProcessorModel<"rocket-rv64", + RocketModel, + [Feature64Bit]>; +def ROCKET : RISCVTuneProcessorModel<"rocket", + RocketModel>; + +def SIFIVE_7 : RISCVTuneProcessorModel<"sifive-7-series", + SiFive7Model, + [TuneSiFive7]>; + +def SIFIVE_E20 : RISCVProcessorModel<"sifive-e20", + RocketModel, + [Feature32Bit, + FeatureStdExtM, + FeatureStdExtC], + "rv32imc">; + +def SIFIVE_E21 : RISCVProcessorModel<"sifive-e21", + RocketModel, + [Feature32Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtC], + "rv32imac">; + +def SIFIVE_E24 : RISCVProcessorModel<"sifive-e24", + RocketModel, + [Feature32Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtC], + "rv32imafc">; + +def SIFIVE_E31 : RISCVProcessorModel<"sifive-e31", + RocketModel, + [Feature32Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtC], + "rv32imac">; + +def SIFIVE_E34 : RISCVProcessorModel<"sifive-e34", + RocketModel, + [Feature32Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtC], + "rv32imafc">; + +def SIFIVE_E76 : RISCVProcessorModel<"sifive-e76", + SiFive7Model, + [Feature32Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtC], + "rv32imafc", + [TuneSiFive7]>; + +def SIFIVE_S21 : RISCVProcessorModel<"sifive-s21", + RocketModel, + [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtC], + "rv64imac">; + +def SIFIVE_S51 : RISCVProcessorModel<"sifive-s51", + RocketModel, + [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtC], + "rv64imac">; + +def SIFIVE_S54 : RISCVProcessorModel<"sifive-s54", + RocketModel, + [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtD, + FeatureStdExtC], + "rv64gc">; + +def SIFIVE_S76 : RISCVProcessorModel<"sifive-s76", + SiFive7Model, + [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtD, + FeatureStdExtC], + "rv64gc", + [TuneSiFive7]>; + +def SIFIVE_U54 : RISCVProcessorModel<"sifive-u54", + RocketModel, + [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtD, + FeatureStdExtC], + "rv64gc">; + +def SIFIVE_U74 : RISCVProcessorModel<"sifive-u74", + SiFive7Model, + [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtD, + FeatureStdExtC], + "rv64gc", + [TuneSiFive7] >; + +def SYNTACORE_SCR1_BASE : RISCVProcessorModel<"syntacore-scr1-base", + SyntacoreSCR1Model, + [Feature32Bit, + FeatureStdExtC], + "rv32ic", + [TuneNoDefaultUnroll]>; + +def SYNTACORE_SCR1_MAX : RISCVProcessorModel<"syntacore-scr1-max", + SyntacoreSCR1Model, + [Feature32Bit, + FeatureStdExtM, + FeatureStdExtC], + "rv32imc", + [TuneNoDefaultUnroll]>; //===----------------------------------------------------------------------===// // Define the RISC-V target. diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index a20b089..883715a 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -18,7 +18,7 @@ #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/TargetLowering.h" -#include "llvm/Support/TargetParser.h" +#include "llvm/TargetParser/RISCVTargetParser.h" #include namespace llvm { diff --git a/llvm/lib/TargetParser/CMakeLists.txt b/llvm/lib/TargetParser/CMakeLists.txt index 7e31f81..392c674 100644 --- a/llvm/lib/TargetParser/CMakeLists.txt +++ b/llvm/lib/TargetParser/CMakeLists.txt @@ -1,4 +1,3 @@ - add_llvm_component_library(LLVMTargetParser AArch64TargetParser.cpp ARMTargetParserCommon.cpp @@ -6,6 +5,7 @@ add_llvm_component_library(LLVMTargetParser CSKYTargetParser.cpp Host.cpp LoongArchTargetParser.cpp + RISCVTargetParser.cpp TargetParser.cpp Triple.cpp X86TargetParser.cpp @@ -16,4 +16,7 @@ add_llvm_component_library(LLVMTargetParser LINK_COMPONENTS Support + + DEPENDS + RISCVTargetParserTableGen ) diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp new file mode 100644 index 0000000..6ec2892 --- /dev/null +++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp @@ -0,0 +1,104 @@ +//===-- RISCVTargetParser.cpp - Parser for target features ------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file implements a target parser to recognise hardware features +// FOR RISC-V CPUS. +// +//===----------------------------------------------------------------------===// + +#include "llvm/TargetParser/RISCVTargetParser.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringSwitch.h" + +namespace llvm { +namespace RISCV { + +struct CPUInfo { + StringLiteral Name; + CPUKind Kind; + unsigned Features; + StringLiteral DefaultMarch; + bool is64Bit() const { return (Features & FK_64BIT); } +}; + +constexpr CPUInfo RISCVCPUInfo[] = { +#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) \ + {NAME, CK_##ENUM, FEATURES, DEFAULT_MARCH}, +#include "llvm/TargetParser/RISCVTargetParserDef.inc" +}; + +bool checkCPUKind(CPUKind Kind, bool IsRV64) { + if (Kind == CK_INVALID) + return false; + return RISCVCPUInfo[static_cast(Kind)].is64Bit() == IsRV64; +} + +bool checkTuneCPUKind(CPUKind Kind, bool IsRV64) { + if (Kind == CK_INVALID) + return false; +#define TUNE_PROC(ENUM, NAME) \ + if (Kind == CK_##ENUM) \ + return true; +#include "llvm/TargetParser/RISCVTargetParserDef.inc" + return RISCVCPUInfo[static_cast(Kind)].is64Bit() == IsRV64; +} + +CPUKind parseCPUKind(StringRef CPU) { + return llvm::StringSwitch(CPU) +#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) +#include "llvm/TargetParser/RISCVTargetParserDef.inc" + .Default(CK_INVALID); +} + +CPUKind parseTuneCPUKind(StringRef TuneCPU, bool IsRV64) { + return llvm::StringSwitch(TuneCPU) +#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) +#define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM) +#include "llvm/TargetParser/RISCVTargetParserDef.inc" + .Default(CK_INVALID); +} + +StringRef getMArchFromMcpu(StringRef CPU) { + CPUKind Kind = parseCPUKind(CPU); + return RISCVCPUInfo[static_cast(Kind)].DefaultMarch; +} + +void fillValidCPUArchList(SmallVectorImpl &Values, bool IsRV64) { + for (const auto &C : RISCVCPUInfo) { + if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) + Values.emplace_back(C.Name); + } +} + +void fillValidTuneCPUArchList(SmallVectorImpl &Values, bool IsRV64) { + for (const auto &C : RISCVCPUInfo) { + if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) + Values.emplace_back(C.Name); + } +#define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME)); +#include "llvm/TargetParser/RISCVTargetParserDef.inc" +} + +// Get all features except standard extension feature +bool getCPUFeaturesExceptStdExt(CPUKind Kind, + std::vector &Features) { + unsigned CPUFeatures = RISCVCPUInfo[static_cast(Kind)].Features; + + if (CPUFeatures == FK_INVALID) + return false; + + if (CPUFeatures & FK_64BIT) + Features.push_back("+64bit"); + else + Features.push_back("-64bit"); + + return true; +} + +} // namespace RISCV +} // namespace llvm diff --git a/llvm/lib/TargetParser/TargetParser.cpp b/llvm/lib/TargetParser/TargetParser.cpp index b3eb5e1..e9fccef 100644 --- a/llvm/lib/TargetParser/TargetParser.cpp +++ b/llvm/lib/TargetParser/TargetParser.cpp @@ -251,89 +251,3 @@ StringRef AMDGPU::getCanonicalArchName(const Triple &T, StringRef Arch) { return T.isAMDGCN() ? getArchNameAMDGCN(ProcKind) : getArchNameR600(ProcKind); } - -namespace llvm { -namespace RISCV { - -struct CPUInfo { - StringLiteral Name; - CPUKind Kind; - unsigned Features; - StringLiteral DefaultMarch; - bool is64Bit() const { return (Features & FK_64BIT); } -}; - -constexpr CPUInfo RISCVCPUInfo[] = { -#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) \ - {NAME, CK_##ENUM, FEATURES, DEFAULT_MARCH}, -#include "llvm/TargetParser/RISCVTargetParser.def" -}; - -bool checkCPUKind(CPUKind Kind, bool IsRV64) { - if (Kind == CK_INVALID) - return false; - return RISCVCPUInfo[static_cast(Kind)].is64Bit() == IsRV64; -} - -bool checkTuneCPUKind(CPUKind Kind, bool IsRV64) { - if (Kind == CK_INVALID) - return false; -#define TUNE_PROC(ENUM, NAME) if (Kind == CK_##ENUM) return true; -#include "llvm/TargetParser/RISCVTargetParser.def" - return RISCVCPUInfo[static_cast(Kind)].is64Bit() == IsRV64; -} - -CPUKind parseCPUKind(StringRef CPU) { - return llvm::StringSwitch(CPU) -#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) -#include "llvm/TargetParser/RISCVTargetParser.def" - .Default(CK_INVALID); -} - -CPUKind parseTuneCPUKind(StringRef TuneCPU, bool IsRV64) { - return llvm::StringSwitch(TuneCPU) -#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) -#define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM) -#include "llvm/TargetParser/RISCVTargetParser.def" - .Default(CK_INVALID); -} - -StringRef getMArchFromMcpu(StringRef CPU) { - CPUKind Kind = parseCPUKind(CPU); - return RISCVCPUInfo[static_cast(Kind)].DefaultMarch; -} - -void fillValidCPUArchList(SmallVectorImpl &Values, bool IsRV64) { - for (const auto &C : RISCVCPUInfo) { - if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) - Values.emplace_back(C.Name); - } -} - -void fillValidTuneCPUArchList(SmallVectorImpl &Values, bool IsRV64) { - for (const auto &C : RISCVCPUInfo) { - if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) - Values.emplace_back(C.Name); - } -#define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME)); -#include "llvm/TargetParser/RISCVTargetParser.def" -} - -// Get all features except standard extension feature -bool getCPUFeaturesExceptStdExt(CPUKind Kind, - std::vector &Features) { - unsigned CPUFeatures = RISCVCPUInfo[static_cast(Kind)].Features; - - if (CPUFeatures == FK_INVALID) - return false; - - if (CPUFeatures & FK_64BIT) - Features.push_back("+64bit"); - else - Features.push_back("-64bit"); - - return true; -} - -} // namespace RISCV -} // namespace llvm diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt index 56035bd..aa16e7e 100644 --- a/llvm/utils/TableGen/CMakeLists.txt +++ b/llvm/utils/TableGen/CMakeLists.txt @@ -45,6 +45,7 @@ add_tablegen(llvm-tblgen LLVM CompressInstEmitter.cpp RegisterBankEmitter.cpp RegisterInfoEmitter.cpp + RISCVTargetDefEmitter.cpp SDNodeProperties.cpp SearchableTableEmitter.cpp SubtargetEmitter.cpp diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp new file mode 100644 index 0000000..cfd4a98 --- /dev/null +++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp @@ -0,0 +1,62 @@ +//===- RISCVTargetDefEmitter.cpp - Generate lists of RISCV CPUs -----------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend emits the include file needed by the target +// parser to parse the RISC-V CPUs. +// +//===----------------------------------------------------------------------===// + +#include "TableGenBackends.h" +#include "llvm/TableGen/Record.h" + +using namespace llvm; + +static std::string getEnumFeatures(const Record &Rec) { + std::vector Features = Rec.getValueAsListOfDefs("Features"); + if (find_if(Features, [](const Record *R) { + return R->getName() == "Feature64Bit"; + }) != Features.end()) + return "FK_64BIT"; + + return "FK_NONE"; +} + +void llvm::EmitRISCVTargetDef(const RecordKeeper &RK, raw_ostream &OS) { + using MapTy = std::pair>; + using RecordMap = std::map, std::less<>>; + const RecordMap &Map = RK.getDefs(); + + OS << "#ifndef PROC\n" + << "#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH)\n" + << "#endif\n\n"; + + OS << "PROC(INVALID, {\"invalid\"}, FK_INVALID, {\"\"})\n"; + // Iterate on all definition records. + for (const MapTy &Def : Map) { + const Record &Rec = *(Def.second); + if (Rec.isSubClassOf("RISCVProcessorModel")) + OS << "PROC(" << Rec.getName() << ", " + << "{\"" << Rec.getValueAsString("Name") << "\"}," + << getEnumFeatures(Rec) << ", " + << "{\"" << Rec.getValueAsString("DefaultMarch") << "\"})\n"; + } + OS << "\n#undef PROC\n"; + OS << "\n"; + OS << "#ifndef TUNE_PROC\n" + << "#define TUNE_PROC(ENUM, NAME)\n" + << "#endif\n\n"; + OS << "TUNE_PROC(GENERIC, \"generic\")\n"; + for (const MapTy &Def : Map) { + const Record &Rec = *(Def.second); + if (Rec.isSubClassOf("RISCVTuneProcessorModel")) + OS << "TUNE_PROC(" << Rec.getName() << ", " + << "\"" << Rec.getValueAsString("Name") << "\")\n"; + } + + OS << "\n#undef TUNE_PROC\n"; +} diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp index efd6418..746e2dd 100644 --- a/llvm/utils/TableGen/TableGen.cpp +++ b/llvm/utils/TableGen/TableGen.cpp @@ -58,6 +58,7 @@ enum ActionType { GenDirectivesEnumDecl, GenDirectivesEnumImpl, GenDXILOperation, + GenRISCVTargetDef, }; namespace llvm { @@ -141,8 +142,9 @@ cl::opt Action( clEnumValN(GenDirectivesEnumImpl, "gen-directive-impl", "Generate directive related implementation code"), clEnumValN(GenDXILOperation, "gen-dxil-operation", - "Generate DXIL operation information"))); - + "Generate DXIL operation information"), + clEnumValN(GenRISCVTargetDef, "gen-riscv-target-def", + "Generate the list of CPU for RISCV"))); cl::OptionCategory PrintEnumsCat("Options for -print-enums"); cl::opt Class("class", cl::desc("Print Enum list for this class"), cl::value_desc("class name"), @@ -278,6 +280,9 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenDXILOperation: EmitDXILOperation(Records, OS); break; + case GenRISCVTargetDef: + EmitRISCVTargetDef(Records, OS); + break; } return false; diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h index 4dff130..ac44bab 100644 --- a/llvm/utils/TableGen/TableGenBackends.h +++ b/llvm/utils/TableGen/TableGenBackends.h @@ -94,6 +94,7 @@ void EmitAutomata(RecordKeeper &RK, raw_ostream &OS); void EmitDirectivesDecl(RecordKeeper &RK, raw_ostream &OS); void EmitDirectivesImpl(RecordKeeper &RK, raw_ostream &OS); void EmitDXILOperation(RecordKeeper &RK, raw_ostream &OS); +void EmitRISCVTargetDef(const RecordKeeper &RK, raw_ostream &OS); } // End llvm namespace -- 2.7.4