Skip to content

Commit 20e0f9e

Browse files
committed
[RISCV] Move RISCVVType namespace to Support
Clang and some middle-end optimizations may need these helper functions. This can reduce some duplications.
1 parent 87c0260 commit 20e0f9e

File tree

7 files changed

+181
-194
lines changed

7 files changed

+181
-194
lines changed

llvm/include/llvm/Support/RISCVISAInfo.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "llvm/ADT/StringMap.h"
1313
#include "llvm/ADT/StringRef.h"
1414
#include "llvm/Support/Error.h"
15+
#include "llvm/Support/MathExtras.h"
1516

1617
#include <map>
1718
#include <string>
@@ -116,6 +117,80 @@ class RISCVISAInfo {
116117
void updateMaxELen();
117118
};
118119

120+
namespace RISCVII {
121+
enum VLMUL : uint8_t {
122+
LMUL_1 = 0,
123+
LMUL_2,
124+
LMUL_4,
125+
LMUL_8,
126+
LMUL_RESERVED,
127+
LMUL_F8,
128+
LMUL_F4,
129+
LMUL_F2
130+
};
131+
132+
enum {
133+
TAIL_UNDISTURBED_MASK_UNDISTURBED = 0,
134+
TAIL_AGNOSTIC = 1,
135+
MASK_AGNOSTIC = 2,
136+
};
137+
} // namespace RISCVII
138+
139+
namespace RISCVVType {
140+
// Is this a SEW value that can be encoded into the VTYPE format.
141+
inline static bool isValidSEW(unsigned SEW) {
142+
return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 1024;
143+
}
144+
145+
// Is this a LMUL value that can be encoded into the VTYPE format.
146+
inline static bool isValidLMUL(unsigned LMUL, bool Fractional) {
147+
return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1);
148+
}
149+
150+
unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic,
151+
bool MaskAgnostic);
152+
153+
inline static RISCVII::VLMUL getVLMUL(unsigned VType) {
154+
unsigned VLMUL = VType & 0x7;
155+
return static_cast<RISCVII::VLMUL>(VLMUL);
156+
}
157+
158+
// Decode VLMUL into 1,2,4,8 and fractional indicator.
159+
std::pair<unsigned, bool> decodeVLMUL(RISCVII::VLMUL VLMUL);
160+
161+
inline static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional) {
162+
assert(isValidLMUL(LMUL, Fractional) && "Unsupported LMUL");
163+
unsigned LmulLog2 = Log2_32(LMUL);
164+
return static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2);
165+
}
166+
167+
inline static unsigned decodeVSEW(unsigned VSEW) {
168+
assert(VSEW < 8 && "Unexpected VSEW value");
169+
return 1 << (VSEW + 3);
170+
}
171+
172+
inline static unsigned encodeSEW(unsigned SEW) {
173+
assert(isValidSEW(SEW) && "Unexpected SEW value");
174+
return Log2_32(SEW) - 3;
175+
}
176+
177+
inline static unsigned getSEW(unsigned VType) {
178+
unsigned VSEW = (VType >> 3) & 0x7;
179+
return decodeVSEW(VSEW);
180+
}
181+
182+
inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; }
183+
184+
inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; }
185+
186+
void printVType(unsigned VType, raw_ostream &OS);
187+
188+
unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul);
189+
190+
std::optional<RISCVII::VLMUL>
191+
getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW);
192+
} // namespace RISCVVType
193+
119194
} // namespace llvm
120195

121196
#endif

llvm/lib/Support/RISCVISAInfo.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,3 +1378,90 @@ std::string RISCVISAInfo::getTargetFeatureForExtension(StringRef Ext) {
13781378
return isExperimentalExtension(Name) ? "experimental-" + Name.str()
13791379
: Name.str();
13801380
}
1381+
1382+
// Encode VTYPE into the binary format used by the the VSETVLI instruction which
1383+
// is used by our MC layer representation.
1384+
//
1385+
// Bits | Name | Description
1386+
// -----+------------+------------------------------------------------
1387+
// 7 | vma | Vector mask agnostic
1388+
// 6 | vta | Vector tail agnostic
1389+
// 5:3 | vsew[2:0] | Standard element width (SEW) setting
1390+
// 2:0 | vlmul[2:0] | Vector register group multiplier (LMUL) setting
1391+
unsigned RISCVVType::encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW,
1392+
bool TailAgnostic, bool MaskAgnostic) {
1393+
assert(isValidSEW(SEW) && "Invalid SEW");
1394+
unsigned VLMULBits = static_cast<unsigned>(VLMUL);
1395+
unsigned VSEWBits = encodeSEW(SEW);
1396+
unsigned VTypeI = (VSEWBits << 3) | (VLMULBits & 0x7);
1397+
if (TailAgnostic)
1398+
VTypeI |= 0x40;
1399+
if (MaskAgnostic)
1400+
VTypeI |= 0x80;
1401+
1402+
return VTypeI;
1403+
}
1404+
1405+
std::pair<unsigned, bool> RISCVVType::decodeVLMUL(RISCVII::VLMUL VLMUL) {
1406+
switch (VLMUL) {
1407+
default:
1408+
llvm_unreachable("Unexpected LMUL value!");
1409+
case RISCVII::VLMUL::LMUL_1:
1410+
case RISCVII::VLMUL::LMUL_2:
1411+
case RISCVII::VLMUL::LMUL_4:
1412+
case RISCVII::VLMUL::LMUL_8:
1413+
return std::make_pair(1 << static_cast<unsigned>(VLMUL), false);
1414+
case RISCVII::VLMUL::LMUL_F2:
1415+
case RISCVII::VLMUL::LMUL_F4:
1416+
case RISCVII::VLMUL::LMUL_F8:
1417+
return std::make_pair(1 << (8 - static_cast<unsigned>(VLMUL)), true);
1418+
}
1419+
}
1420+
1421+
void RISCVVType::printVType(unsigned VType, raw_ostream &OS) {
1422+
unsigned Sew = getSEW(VType);
1423+
OS << "e" << Sew;
1424+
1425+
unsigned LMul;
1426+
bool Fractional;
1427+
std::tie(LMul, Fractional) = decodeVLMUL(getVLMUL(VType));
1428+
1429+
if (Fractional)
1430+
OS << ", mf";
1431+
else
1432+
OS << ", m";
1433+
OS << LMul;
1434+
1435+
if (isTailAgnostic(VType))
1436+
OS << ", ta";
1437+
else
1438+
OS << ", tu";
1439+
1440+
if (isMaskAgnostic(VType))
1441+
OS << ", ma";
1442+
else
1443+
OS << ", mu";
1444+
}
1445+
1446+
unsigned RISCVVType::getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul) {
1447+
unsigned LMul;
1448+
bool Fractional;
1449+
std::tie(LMul, Fractional) = decodeVLMUL(VLMul);
1450+
1451+
// Convert LMul to a fixed point value with 3 fractional bits.
1452+
LMul = Fractional ? (8 / LMul) : (LMul * 8);
1453+
1454+
assert(SEW >= 8 && "Unexpected SEW value");
1455+
return (SEW * 8) / LMul;
1456+
}
1457+
1458+
std::optional<RISCVII::VLMUL>
1459+
RISCVVType::getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW) {
1460+
unsigned Ratio = RISCVVType::getSEWLMULRatio(SEW, VLMUL);
1461+
unsigned EMULFixedPoint = (EEW * 8) / Ratio;
1462+
bool Fractional = EMULFixedPoint < 8;
1463+
unsigned EMUL = Fractional ? 8 / EMULFixedPoint : EMULFixedPoint / 8;
1464+
if (!isValidLMUL(EMUL, Fractional))
1465+
return std::nullopt;
1466+
return RISCVVType::encodeLMUL(EMUL, Fractional);
1467+
}

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp

Lines changed: 0 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -134,93 +134,6 @@ parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits) {
134134

135135
} // namespace RISCVFeatures
136136

137-
// Encode VTYPE into the binary format used by the the VSETVLI instruction which
138-
// is used by our MC layer representation.
139-
//
140-
// Bits | Name | Description
141-
// -----+------------+------------------------------------------------
142-
// 7 | vma | Vector mask agnostic
143-
// 6 | vta | Vector tail agnostic
144-
// 5:3 | vsew[2:0] | Standard element width (SEW) setting
145-
// 2:0 | vlmul[2:0] | Vector register group multiplier (LMUL) setting
146-
unsigned RISCVVType::encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW,
147-
bool TailAgnostic, bool MaskAgnostic) {
148-
assert(isValidSEW(SEW) && "Invalid SEW");
149-
unsigned VLMULBits = static_cast<unsigned>(VLMUL);
150-
unsigned VSEWBits = encodeSEW(SEW);
151-
unsigned VTypeI = (VSEWBits << 3) | (VLMULBits & 0x7);
152-
if (TailAgnostic)
153-
VTypeI |= 0x40;
154-
if (MaskAgnostic)
155-
VTypeI |= 0x80;
156-
157-
return VTypeI;
158-
}
159-
160-
std::pair<unsigned, bool> RISCVVType::decodeVLMUL(RISCVII::VLMUL VLMUL) {
161-
switch (VLMUL) {
162-
default:
163-
llvm_unreachable("Unexpected LMUL value!");
164-
case RISCVII::VLMUL::LMUL_1:
165-
case RISCVII::VLMUL::LMUL_2:
166-
case RISCVII::VLMUL::LMUL_4:
167-
case RISCVII::VLMUL::LMUL_8:
168-
return std::make_pair(1 << static_cast<unsigned>(VLMUL), false);
169-
case RISCVII::VLMUL::LMUL_F2:
170-
case RISCVII::VLMUL::LMUL_F4:
171-
case RISCVII::VLMUL::LMUL_F8:
172-
return std::make_pair(1 << (8 - static_cast<unsigned>(VLMUL)), true);
173-
}
174-
}
175-
176-
void RISCVVType::printVType(unsigned VType, raw_ostream &OS) {
177-
unsigned Sew = getSEW(VType);
178-
OS << "e" << Sew;
179-
180-
unsigned LMul;
181-
bool Fractional;
182-
std::tie(LMul, Fractional) = decodeVLMUL(getVLMUL(VType));
183-
184-
if (Fractional)
185-
OS << ", mf";
186-
else
187-
OS << ", m";
188-
OS << LMul;
189-
190-
if (isTailAgnostic(VType))
191-
OS << ", ta";
192-
else
193-
OS << ", tu";
194-
195-
if (isMaskAgnostic(VType))
196-
OS << ", ma";
197-
else
198-
OS << ", mu";
199-
}
200-
201-
unsigned RISCVVType::getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul) {
202-
unsigned LMul;
203-
bool Fractional;
204-
std::tie(LMul, Fractional) = decodeVLMUL(VLMul);
205-
206-
// Convert LMul to a fixed point value with 3 fractional bits.
207-
LMul = Fractional ? (8 / LMul) : (LMul * 8);
208-
209-
assert(SEW >= 8 && "Unexpected SEW value");
210-
return (SEW * 8) / LMul;
211-
}
212-
213-
std::optional<RISCVII::VLMUL>
214-
RISCVVType::getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW) {
215-
unsigned Ratio = RISCVVType::getSEWLMULRatio(SEW, VLMUL);
216-
unsigned EMULFixedPoint = (EEW * 8) / Ratio;
217-
bool Fractional = EMULFixedPoint < 8;
218-
unsigned EMUL = Fractional ? 8 / EMULFixedPoint : EMULFixedPoint / 8;
219-
if (!isValidLMUL(EMUL, Fractional))
220-
return std::nullopt;
221-
return RISCVVType::encodeLMUL(EMUL, Fractional);
222-
}
223-
224137
// Include the auto-generated portion of the compress emitter.
225138
#define GEN_UNCOMPRESS_INSTR
226139
#define GEN_COMPRESS_INSTR

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -124,23 +124,6 @@ enum {
124124
TargetOverlapConstraintTypeMask = 3ULL << TargetOverlapConstraintTypeShift,
125125
};
126126

127-
enum VLMUL : uint8_t {
128-
LMUL_1 = 0,
129-
LMUL_2,
130-
LMUL_4,
131-
LMUL_8,
132-
LMUL_RESERVED,
133-
LMUL_F8,
134-
LMUL_F4,
135-
LMUL_F2
136-
};
137-
138-
enum {
139-
TAIL_UNDISTURBED_MASK_UNDISTURBED = 0,
140-
TAIL_AGNOSTIC = 1,
141-
MASK_AGNOSTIC = 2,
142-
};
143-
144127
// Helper functions to read TSFlags.
145128
/// \returns the format of the instruction.
146129
static inline unsigned getFormat(uint64_t TSFlags) {
@@ -484,61 +467,6 @@ parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits);
484467

485468
} // namespace RISCVFeatures
486469

487-
namespace RISCVVType {
488-
// Is this a SEW value that can be encoded into the VTYPE format.
489-
inline static bool isValidSEW(unsigned SEW) {
490-
return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 1024;
491-
}
492-
493-
// Is this a LMUL value that can be encoded into the VTYPE format.
494-
inline static bool isValidLMUL(unsigned LMUL, bool Fractional) {
495-
return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1);
496-
}
497-
498-
unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic,
499-
bool MaskAgnostic);
500-
501-
inline static RISCVII::VLMUL getVLMUL(unsigned VType) {
502-
unsigned VLMUL = VType & 0x7;
503-
return static_cast<RISCVII::VLMUL>(VLMUL);
504-
}
505-
506-
// Decode VLMUL into 1,2,4,8 and fractional indicator.
507-
std::pair<unsigned, bool> decodeVLMUL(RISCVII::VLMUL VLMUL);
508-
509-
inline static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional) {
510-
assert(isValidLMUL(LMUL, Fractional) && "Unsupported LMUL");
511-
unsigned LmulLog2 = Log2_32(LMUL);
512-
return static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2);
513-
}
514-
515-
inline static unsigned decodeVSEW(unsigned VSEW) {
516-
assert(VSEW < 8 && "Unexpected VSEW value");
517-
return 1 << (VSEW + 3);
518-
}
519-
520-
inline static unsigned encodeSEW(unsigned SEW) {
521-
assert(isValidSEW(SEW) && "Unexpected SEW value");
522-
return Log2_32(SEW) - 3;
523-
}
524-
525-
inline static unsigned getSEW(unsigned VType) {
526-
unsigned VSEW = (VType >> 3) & 0x7;
527-
return decodeVSEW(VSEW);
528-
}
529-
530-
inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; }
531-
532-
inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; }
533-
534-
void printVType(unsigned VType, raw_ostream &OS);
535-
536-
unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul);
537-
538-
std::optional<RISCVII::VLMUL>
539-
getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW);
540-
} // namespace RISCVVType
541-
542470
namespace RISCVRVC {
543471
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI);
544472
bool uncompress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI);

llvm/unittests/Support/RISCVISAInfoTest.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,3 +906,22 @@ For example, clang -march=rv32i_v1p0)";
906906
return Captured.find(Expected) != std::string::npos;
907907
}(CapturedOutput, ExpectedOutput));
908908
}
909+
910+
TEST(RISCVVType, CheckSameRatioLMUL) {
911+
// Smaller LMUL.
912+
EXPECT_EQ(RISCVII::LMUL_1,
913+
RISCVVType::getSameRatioLMUL(16, RISCVII::LMUL_2, 8));
914+
EXPECT_EQ(RISCVII::LMUL_F2,
915+
RISCVVType::getSameRatioLMUL(16, RISCVII::LMUL_1, 8));
916+
// Smaller fractional LMUL.
917+
EXPECT_EQ(RISCVII::LMUL_F8,
918+
RISCVVType::getSameRatioLMUL(16, RISCVII::LMUL_F4, 8));
919+
// Bigger LMUL.
920+
EXPECT_EQ(RISCVII::LMUL_2,
921+
RISCVVType::getSameRatioLMUL(8, RISCVII::LMUL_1, 16));
922+
EXPECT_EQ(RISCVII::LMUL_1,
923+
RISCVVType::getSameRatioLMUL(8, RISCVII::LMUL_F2, 16));
924+
// Bigger fractional LMUL.
925+
EXPECT_EQ(RISCVII::LMUL_F2,
926+
RISCVVType::getSameRatioLMUL(8, RISCVII::LMUL_F4, 16));
927+
}

llvm/unittests/Target/RISCV/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ set(LLVM_LINK_COMPONENTS
1616

1717
add_llvm_target_unittest(RISCVTests
1818
MCInstrAnalysisTest.cpp
19-
RISCVBaseInfoTest.cpp
2019
RISCVInstrInfoTest.cpp
2120
)
2221

0 commit comments

Comments
 (0)