diff options
author | Wang Pengcheng <wangpengcheng.pp@bytedance.com> | 2024-03-06 10:56:19 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-06 10:56:19 +0800 |
commit | 85388a06b6022d0a7bc984bcaff86cf96f045338 (patch) | |
tree | dcd747a6aad19fdc8339953466789dfc64686a59 | |
parent | 49ec8b747c83b8dec8317614c30e5610d133790e (diff) | |
download | llvm-85388a06b6022d0a7bc984bcaff86cf96f045338.zip llvm-85388a06b6022d0a7bc984bcaff86cf96f045338.tar.gz llvm-85388a06b6022d0a7bc984bcaff86cf96f045338.tar.bz2 |
[RISCV] Move RISCVVType namespace to TargetParser (#83222)
Clang and some middle-end optimizations may need these helper
functions.
This can reduce some duplications.
-rw-r--r-- | llvm/include/llvm/TargetParser/RISCVTargetParser.h | 77 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp | 87 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 73 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.h | 1 | ||||
-rw-r--r-- | llvm/lib/TargetParser/RISCVTargetParser.cpp | 91 | ||||
-rw-r--r-- | llvm/unittests/Target/RISCV/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/unittests/TargetParser/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/unittests/TargetParser/RISCVTargetParserTest.cpp (renamed from llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp) | 7 |
8 files changed, 173 insertions, 165 deletions
diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h index 553b4ef..cdd1918 100644 --- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h +++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h @@ -15,6 +15,8 @@ #define LLVM_TARGETPARSER_RISCVTARGETPARSER_H #include "llvm/ADT/StringRef.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" namespace llvm { @@ -36,6 +38,81 @@ void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64); bool hasFastUnalignedAccess(StringRef CPU); } // namespace RISCV + +namespace RISCVII { +enum VLMUL : uint8_t { + LMUL_1 = 0, + LMUL_2, + LMUL_4, + LMUL_8, + LMUL_RESERVED, + LMUL_F8, + LMUL_F4, + LMUL_F2 +}; + +enum { + TAIL_UNDISTURBED_MASK_UNDISTURBED = 0, + TAIL_AGNOSTIC = 1, + MASK_AGNOSTIC = 2, +}; +} // namespace RISCVII + +namespace RISCVVType { +// Is this a SEW value that can be encoded into the VTYPE format. +inline static bool isValidSEW(unsigned SEW) { + return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 1024; +} + +// Is this a LMUL value that can be encoded into the VTYPE format. +inline static bool isValidLMUL(unsigned LMUL, bool Fractional) { + return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1); +} + +unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic, + bool MaskAgnostic); + +inline static RISCVII::VLMUL getVLMUL(unsigned VType) { + unsigned VLMUL = VType & 0x7; + return static_cast<RISCVII::VLMUL>(VLMUL); +} + +// Decode VLMUL into 1,2,4,8 and fractional indicator. +std::pair<unsigned, bool> decodeVLMUL(RISCVII::VLMUL VLMUL); + +inline static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional) { + assert(isValidLMUL(LMUL, Fractional) && "Unsupported LMUL"); + unsigned LmulLog2 = Log2_32(LMUL); + return static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2); +} + +inline static unsigned decodeVSEW(unsigned VSEW) { + assert(VSEW < 8 && "Unexpected VSEW value"); + return 1 << (VSEW + 3); +} + +inline static unsigned encodeSEW(unsigned SEW) { + assert(isValidSEW(SEW) && "Unexpected SEW value"); + return Log2_32(SEW) - 3; +} + +inline static unsigned getSEW(unsigned VType) { + unsigned VSEW = (VType >> 3) & 0x7; + return decodeVSEW(VSEW); +} + +inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; } + +inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; } + +void printVType(unsigned VType, raw_ostream &OS); + +unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul); + +std::optional<RISCVII::VLMUL> +getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW); +} // namespace RISCVVType + } // namespace llvm #endif diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp index be9c7d1..61f8e71 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp @@ -134,93 +134,6 @@ parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits) { } // namespace RISCVFeatures -// Encode VTYPE into the binary format used by the the VSETVLI instruction which -// is used by our MC layer representation. -// -// Bits | Name | Description -// -----+------------+------------------------------------------------ -// 7 | vma | Vector mask agnostic -// 6 | vta | Vector tail agnostic -// 5:3 | vsew[2:0] | Standard element width (SEW) setting -// 2:0 | vlmul[2:0] | Vector register group multiplier (LMUL) setting -unsigned RISCVVType::encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, - bool TailAgnostic, bool MaskAgnostic) { - assert(isValidSEW(SEW) && "Invalid SEW"); - unsigned VLMULBits = static_cast<unsigned>(VLMUL); - unsigned VSEWBits = encodeSEW(SEW); - unsigned VTypeI = (VSEWBits << 3) | (VLMULBits & 0x7); - if (TailAgnostic) - VTypeI |= 0x40; - if (MaskAgnostic) - VTypeI |= 0x80; - - return VTypeI; -} - -std::pair<unsigned, bool> RISCVVType::decodeVLMUL(RISCVII::VLMUL VLMUL) { - switch (VLMUL) { - default: - llvm_unreachable("Unexpected LMUL value!"); - case RISCVII::VLMUL::LMUL_1: - case RISCVII::VLMUL::LMUL_2: - case RISCVII::VLMUL::LMUL_4: - case RISCVII::VLMUL::LMUL_8: - return std::make_pair(1 << static_cast<unsigned>(VLMUL), false); - case RISCVII::VLMUL::LMUL_F2: - case RISCVII::VLMUL::LMUL_F4: - case RISCVII::VLMUL::LMUL_F8: - return std::make_pair(1 << (8 - static_cast<unsigned>(VLMUL)), true); - } -} - -void RISCVVType::printVType(unsigned VType, raw_ostream &OS) { - unsigned Sew = getSEW(VType); - OS << "e" << Sew; - - unsigned LMul; - bool Fractional; - std::tie(LMul, Fractional) = decodeVLMUL(getVLMUL(VType)); - - if (Fractional) - OS << ", mf"; - else - OS << ", m"; - OS << LMul; - - if (isTailAgnostic(VType)) - OS << ", ta"; - else - OS << ", tu"; - - if (isMaskAgnostic(VType)) - OS << ", ma"; - else - OS << ", mu"; -} - -unsigned RISCVVType::getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul) { - unsigned LMul; - bool Fractional; - std::tie(LMul, Fractional) = decodeVLMUL(VLMul); - - // Convert LMul to a fixed point value with 3 fractional bits. - LMul = Fractional ? (8 / LMul) : (LMul * 8); - - assert(SEW >= 8 && "Unexpected SEW value"); - return (SEW * 8) / LMul; -} - -std::optional<RISCVII::VLMUL> -RISCVVType::getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW) { - unsigned Ratio = RISCVVType::getSEWLMULRatio(SEW, VLMUL); - unsigned EMULFixedPoint = (EEW * 8) / Ratio; - bool Fractional = EMULFixedPoint < 8; - unsigned EMUL = Fractional ? 8 / EMULFixedPoint : EMULFixedPoint / 8; - if (!isValidLMUL(EMUL, Fractional)) - return std::nullopt; - return RISCVVType::encodeLMUL(EMUL, Fractional); -} - // Include the auto-generated portion of the compress emitter. #define GEN_UNCOMPRESS_INSTR #define GEN_COMPRESS_INSTR diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index d7f7859..6d0381c 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -20,6 +20,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/Support/RISCVISAInfo.h" +#include "llvm/TargetParser/RISCVTargetParser.h" #include "llvm/TargetParser/SubtargetFeature.h" namespace llvm { @@ -124,23 +125,6 @@ enum { TargetOverlapConstraintTypeMask = 3ULL << TargetOverlapConstraintTypeShift, }; -enum VLMUL : uint8_t { - LMUL_1 = 0, - LMUL_2, - LMUL_4, - LMUL_8, - LMUL_RESERVED, - LMUL_F8, - LMUL_F4, - LMUL_F2 -}; - -enum { - TAIL_UNDISTURBED_MASK_UNDISTURBED = 0, - TAIL_AGNOSTIC = 1, - MASK_AGNOSTIC = 2, -}; - // Helper functions to read TSFlags. /// \returns the format of the instruction. static inline unsigned getFormat(uint64_t TSFlags) { @@ -484,61 +468,6 @@ parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits); } // namespace RISCVFeatures -namespace RISCVVType { -// Is this a SEW value that can be encoded into the VTYPE format. -inline static bool isValidSEW(unsigned SEW) { - return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 1024; -} - -// Is this a LMUL value that can be encoded into the VTYPE format. -inline static bool isValidLMUL(unsigned LMUL, bool Fractional) { - return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1); -} - -unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic, - bool MaskAgnostic); - -inline static RISCVII::VLMUL getVLMUL(unsigned VType) { - unsigned VLMUL = VType & 0x7; - return static_cast<RISCVII::VLMUL>(VLMUL); -} - -// Decode VLMUL into 1,2,4,8 and fractional indicator. -std::pair<unsigned, bool> decodeVLMUL(RISCVII::VLMUL VLMUL); - -inline static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional) { - assert(isValidLMUL(LMUL, Fractional) && "Unsupported LMUL"); - unsigned LmulLog2 = Log2_32(LMUL); - return static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2); -} - -inline static unsigned decodeVSEW(unsigned VSEW) { - assert(VSEW < 8 && "Unexpected VSEW value"); - return 1 << (VSEW + 3); -} - -inline static unsigned encodeSEW(unsigned SEW) { - assert(isValidSEW(SEW) && "Unexpected SEW value"); - return Log2_32(SEW) - 3; -} - -inline static unsigned getSEW(unsigned VType) { - unsigned VSEW = (VType >> 3) & 0x7; - return decodeVSEW(VSEW); -} - -inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; } - -inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; } - -void printVType(unsigned VType, raw_ostream &OS); - -unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul); - -std::optional<RISCVII::VLMUL> -getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW); -} // namespace RISCVVType - namespace RISCVRVC { bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI); bool uncompress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index a38463f..f90cb4d 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -18,7 +18,6 @@ #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/TargetLowering.h" -#include "llvm/TargetParser/RISCVTargetParser.h" #include <optional> namespace llvm { diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp index 8036df4..0d95e3a 100644 --- a/llvm/lib/TargetParser/RISCVTargetParser.cpp +++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp @@ -120,4 +120,95 @@ void getFeaturesForCPU(StringRef CPU, EnabledFeatures.push_back(F.substr(1)); } } // namespace RISCV + +namespace RISCVVType { +// Encode VTYPE into the binary format used by the the VSETVLI instruction which +// is used by our MC layer representation. +// +// Bits | Name | Description +// -----+------------+------------------------------------------------ +// 7 | vma | Vector mask agnostic +// 6 | vta | Vector tail agnostic +// 5:3 | vsew[2:0] | Standard element width (SEW) setting +// 2:0 | vlmul[2:0] | Vector register group multiplier (LMUL) setting +unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic, + bool MaskAgnostic) { + assert(isValidSEW(SEW) && "Invalid SEW"); + unsigned VLMULBits = static_cast<unsigned>(VLMUL); + unsigned VSEWBits = encodeSEW(SEW); + unsigned VTypeI = (VSEWBits << 3) | (VLMULBits & 0x7); + if (TailAgnostic) + VTypeI |= 0x40; + if (MaskAgnostic) + VTypeI |= 0x80; + + return VTypeI; +} + +std::pair<unsigned, bool> decodeVLMUL(RISCVII::VLMUL VLMUL) { + switch (VLMUL) { + default: + llvm_unreachable("Unexpected LMUL value!"); + case RISCVII::VLMUL::LMUL_1: + case RISCVII::VLMUL::LMUL_2: + case RISCVII::VLMUL::LMUL_4: + case RISCVII::VLMUL::LMUL_8: + return std::make_pair(1 << static_cast<unsigned>(VLMUL), false); + case RISCVII::VLMUL::LMUL_F2: + case RISCVII::VLMUL::LMUL_F4: + case RISCVII::VLMUL::LMUL_F8: + return std::make_pair(1 << (8 - static_cast<unsigned>(VLMUL)), true); + } +} + +void printVType(unsigned VType, raw_ostream &OS) { + unsigned Sew = getSEW(VType); + OS << "e" << Sew; + + unsigned LMul; + bool Fractional; + std::tie(LMul, Fractional) = decodeVLMUL(getVLMUL(VType)); + + if (Fractional) + OS << ", mf"; + else + OS << ", m"; + OS << LMul; + + if (isTailAgnostic(VType)) + OS << ", ta"; + else + OS << ", tu"; + + if (isMaskAgnostic(VType)) + OS << ", ma"; + else + OS << ", mu"; +} + +unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul) { + unsigned LMul; + bool Fractional; + std::tie(LMul, Fractional) = decodeVLMUL(VLMul); + + // Convert LMul to a fixed point value with 3 fractional bits. + LMul = Fractional ? (8 / LMul) : (LMul * 8); + + assert(SEW >= 8 && "Unexpected SEW value"); + return (SEW * 8) / LMul; +} + +std::optional<RISCVII::VLMUL> +getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW) { + unsigned Ratio = RISCVVType::getSEWLMULRatio(SEW, VLMUL); + unsigned EMULFixedPoint = (EEW * 8) / Ratio; + bool Fractional = EMULFixedPoint < 8; + unsigned EMUL = Fractional ? 8 / EMULFixedPoint : EMULFixedPoint / 8; + if (!isValidLMUL(EMUL, Fractional)) + return std::nullopt; + return RISCVVType::encodeLMUL(EMUL, Fractional); +} + +} // namespace RISCVVType + } // namespace llvm diff --git a/llvm/unittests/Target/RISCV/CMakeLists.txt b/llvm/unittests/Target/RISCV/CMakeLists.txt index d80d29b..b58d605 100644 --- a/llvm/unittests/Target/RISCV/CMakeLists.txt +++ b/llvm/unittests/Target/RISCV/CMakeLists.txt @@ -16,7 +16,6 @@ set(LLVM_LINK_COMPONENTS add_llvm_target_unittest(RISCVTests MCInstrAnalysisTest.cpp - RISCVBaseInfoTest.cpp RISCVInstrInfoTest.cpp ) diff --git a/llvm/unittests/TargetParser/CMakeLists.txt b/llvm/unittests/TargetParser/CMakeLists.txt index 501acc0..3bbc74f 100644 --- a/llvm/unittests/TargetParser/CMakeLists.txt +++ b/llvm/unittests/TargetParser/CMakeLists.txt @@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS add_llvm_unittest(TargetParserTests CSKYTargetParserTest.cpp Host.cpp + RISCVTargetParserTest.cpp TargetParserTest.cpp TripleTest.cpp ) diff --git a/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp b/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp index 0e4c90c..68338b5 100644 --- a/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp @@ -1,4 +1,4 @@ -//===- RISCVBaseInfoTest.cpp - RISCVBaseInfo unit tests ----------===// +//===---- RISCVTargetParserTest.cpp - RISCVTargetParser unit tests --------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,14 +6,13 @@ // //===----------------------------------------------------------------------===// -#include "MCTargetDesc/RISCVBaseInfo.h" - +#include "llvm/TargetParser/RISCVTargetParser.h" #include "gtest/gtest.h" using namespace llvm; namespace { -TEST(RISCVBaseInfo, CheckSameRatioLMUL) { +TEST(RISCVVType, CheckSameRatioLMUL) { // Smaller LMUL. EXPECT_EQ(RISCVII::LMUL_1, RISCVVType::getSameRatioLMUL(16, RISCVII::LMUL_2, 8)); |