Skip to content

Commit ff7a9ce

Browse files
committed
[RISCV] Assert extensions are sorted at compile time. NFCI
This replaces verifyTables and assert(llvm::is_sorted) with a constexpr static_assert, so that adding an extension or implication in the wrong order will be a compile time failure rather than a runtime failure.
1 parent db78c30 commit ff7a9ce

File tree

1 file changed

+80
-82
lines changed

1 file changed

+80
-82
lines changed

llvm/lib/Support/RISCVISAInfo.cpp

Lines changed: 80 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "llvm/Support/raw_ostream.h"
1717

1818
#include <array>
19-
#include <atomic>
2019
#include <optional>
2120
#include <string>
2221
#include <vector>
@@ -35,8 +34,8 @@ struct RISCVSupportedExtension {
3534
/// Supported version.
3635
RISCVExtensionVersion Version;
3736

38-
bool operator<(const RISCVSupportedExtension &RHS) const {
39-
return StringRef(Name) < StringRef(RHS.Name);
37+
constexpr bool operator<(const RISCVSupportedExtension &RHS) const {
38+
return std::string_view(Name) < std::string_view(RHS.Name);
4039
}
4140
};
4241

@@ -49,7 +48,7 @@ static const char *RISCVGImplications[] = {
4948
};
5049

5150
// NOTE: This table should be sorted alphabetically by extension name.
52-
static const RISCVSupportedExtension SupportedExtensions[] = {
51+
static constexpr RISCVSupportedExtension SupportedExtensions[] = {
5352
{"a", RISCVExtensionVersion{2, 1}},
5453
{"c", RISCVExtensionVersion{2, 0}},
5554
{"d", RISCVExtensionVersion{2, 2}},
@@ -187,7 +186,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
187186
};
188187

189188
// NOTE: This table should be sorted alphabetically by extension name.
190-
static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
189+
static constexpr RISCVSupportedExtension SupportedExperimentalExtensions[] = {
191190
{"zacas", RISCVExtensionVersion{1, 0}},
192191

193192
{"zcmop", RISCVExtensionVersion{0, 2}},
@@ -207,19 +206,19 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
207206
{"zvfbfwma", RISCVExtensionVersion{0, 8}},
208207
};
209208

210-
static void verifyTables() {
211-
#ifndef NDEBUG
212-
static std::atomic<bool> TableChecked(false);
213-
if (!TableChecked.load(std::memory_order_relaxed)) {
214-
assert(llvm::is_sorted(SupportedExtensions) &&
215-
"Extensions are not sorted by name");
216-
assert(llvm::is_sorted(SupportedExperimentalExtensions) &&
217-
"Experimental extensions are not sorted by name");
218-
TableChecked.store(true, std::memory_order_relaxed);
219-
}
220-
#endif
209+
// TODO: Replace with std::is_sorted once we move to C++20
210+
template <typename T> constexpr bool isSorted(T &&Extensions) {
211+
for (size_t I = 0; I < std::size(Extensions) - 1; I++)
212+
if (!(Extensions[I] < Extensions[I + 1]))
213+
return false;
214+
return true;
221215
}
222216

217+
static_assert(isSorted(SupportedExtensions) &&
218+
"Extensions are not sorted by name");
219+
static_assert(isSorted(SupportedExperimentalExtensions) &&
220+
"Experimental extensions are not sorted by name");
221+
223222
static void PrintExtension(StringRef Name, StringRef Version,
224223
StringRef Description) {
225224
outs().indent(4);
@@ -359,8 +358,6 @@ bool RISCVISAInfo::isSupportedExtensionFeature(StringRef Ext) {
359358
}
360359

361360
bool RISCVISAInfo::isSupportedExtension(StringRef Ext) {
362-
verifyTables();
363-
364361
for (auto ExtInfo : {ArrayRef(SupportedExtensions),
365362
ArrayRef(SupportedExperimentalExtensions)}) {
366363
auto I = llvm::lower_bound(ExtInfo, Ext, LessExtName());
@@ -1062,79 +1059,82 @@ static const char *ImpliedExtsZvl65536b[] = {"zvl32768b"};
10621059
static const char *ImpliedExtsZvl8192b[] = {"zvl4096b"};
10631060

10641061
struct ImpliedExtsEntry {
1065-
StringLiteral Name;
1062+
const char *Name;
10661063
ArrayRef<const char *> Exts;
10671064

1068-
bool operator<(const ImpliedExtsEntry &Other) const {
1069-
return Name < Other.Name;
1065+
constexpr bool operator<(const ImpliedExtsEntry &Other) const {
1066+
return std::string_view(Name) < std::string_view(Other.Name);
10701067
}
10711068

10721069
bool operator<(StringRef Other) const { return Name < Other; }
10731070
};
10741071

10751072
// Note: The table needs to be sorted by name.
10761073
static constexpr ImpliedExtsEntry ImpliedExts[] = {
1077-
{{"d"}, {ImpliedExtsD}},
1078-
{{"f"}, {ImpliedExtsF}},
1079-
{{"v"}, {ImpliedExtsV}},
1080-
{{"xsfvcp"}, {ImpliedExtsXSfvcp}},
1081-
{{"xsfvfnrclipxfqf"}, {ImpliedExtsXSfvfnrclipxfqf}},
1082-
{{"xsfvfwmaccqqq"}, {ImpliedExtsXSfvfwmaccqqq}},
1083-
{{"xsfvqmaccdod"}, {ImpliedExtsXSfvqmaccdod}},
1084-
{{"xsfvqmaccqoq"}, {ImpliedExtsXSfvqmaccqoq}},
1085-
{{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}},
1086-
{{"zacas"}, {ImpliedExtsZacas}},
1087-
{{"zcb"}, {ImpliedExtsZcb}},
1088-
{{"zcd"}, {ImpliedExtsZcd}},
1089-
{{"zce"}, {ImpliedExtsZce}},
1090-
{{"zcf"}, {ImpliedExtsZcf}},
1091-
{{"zcmop"}, {ImpliedExtsZcmop}},
1092-
{{"zcmp"}, {ImpliedExtsZcmp}},
1093-
{{"zcmt"}, {ImpliedExtsZcmt}},
1094-
{{"zdinx"}, {ImpliedExtsZdinx}},
1095-
{{"zfa"}, {ImpliedExtsZfa}},
1096-
{{"zfbfmin"}, {ImpliedExtsZfbfmin}},
1097-
{{"zfh"}, {ImpliedExtsZfh}},
1098-
{{"zfhmin"}, {ImpliedExtsZfhmin}},
1099-
{{"zfinx"}, {ImpliedExtsZfinx}},
1100-
{{"zhinx"}, {ImpliedExtsZhinx}},
1101-
{{"zhinxmin"}, {ImpliedExtsZhinxmin}},
1102-
{{"zicfiss"}, {ImpliedExtsZicfiss}},
1103-
{{"zicntr"}, {ImpliedExtsZicntr}},
1104-
{{"zihpm"}, {ImpliedExtsZihpm}},
1105-
{{"zk"}, {ImpliedExtsZk}},
1106-
{{"zkn"}, {ImpliedExtsZkn}},
1107-
{{"zks"}, {ImpliedExtsZks}},
1108-
{{"zvbb"}, {ImpliedExtsZvbb}},
1109-
{{"zve32f"}, {ImpliedExtsZve32f}},
1110-
{{"zve32x"}, {ImpliedExtsZve32x}},
1111-
{{"zve64d"}, {ImpliedExtsZve64d}},
1112-
{{"zve64f"}, {ImpliedExtsZve64f}},
1113-
{{"zve64x"}, {ImpliedExtsZve64x}},
1114-
{{"zvfbfmin"}, {ImpliedExtsZvfbfmin}},
1115-
{{"zvfbfwma"}, {ImpliedExtsZvfbfwma}},
1116-
{{"zvfh"}, {ImpliedExtsZvfh}},
1117-
{{"zvfhmin"}, {ImpliedExtsZvfhmin}},
1118-
{{"zvkn"}, {ImpliedExtsZvkn}},
1119-
{{"zvknc"}, {ImpliedExtsZvknc}},
1120-
{{"zvkng"}, {ImpliedExtsZvkng}},
1121-
{{"zvknhb"}, {ImpliedExtsZvknhb}},
1122-
{{"zvks"}, {ImpliedExtsZvks}},
1123-
{{"zvksc"}, {ImpliedExtsZvksc}},
1124-
{{"zvksg"}, {ImpliedExtsZvksg}},
1125-
{{"zvl1024b"}, {ImpliedExtsZvl1024b}},
1126-
{{"zvl128b"}, {ImpliedExtsZvl128b}},
1127-
{{"zvl16384b"}, {ImpliedExtsZvl16384b}},
1128-
{{"zvl2048b"}, {ImpliedExtsZvl2048b}},
1129-
{{"zvl256b"}, {ImpliedExtsZvl256b}},
1130-
{{"zvl32768b"}, {ImpliedExtsZvl32768b}},
1131-
{{"zvl4096b"}, {ImpliedExtsZvl4096b}},
1132-
{{"zvl512b"}, {ImpliedExtsZvl512b}},
1133-
{{"zvl64b"}, {ImpliedExtsZvl64b}},
1134-
{{"zvl65536b"}, {ImpliedExtsZvl65536b}},
1135-
{{"zvl8192b"}, {ImpliedExtsZvl8192b}},
1074+
{"d", {ImpliedExtsD}},
1075+
{"f", {ImpliedExtsF}},
1076+
{"v", {ImpliedExtsV}},
1077+
{"xsfvcp", {ImpliedExtsXSfvcp}},
1078+
{"xsfvfnrclipxfqf", {ImpliedExtsXSfvfnrclipxfqf}},
1079+
{"xsfvfwmaccqqq", {ImpliedExtsXSfvfwmaccqqq}},
1080+
{"xsfvqmaccdod", {ImpliedExtsXSfvqmaccdod}},
1081+
{"xsfvqmaccqoq", {ImpliedExtsXSfvqmaccqoq}},
1082+
{"xtheadvdot", {ImpliedExtsXTHeadVdot}},
1083+
{"zacas", {ImpliedExtsZacas}},
1084+
{"zcb", {ImpliedExtsZcb}},
1085+
{"zcd", {ImpliedExtsZcd}},
1086+
{"zce", {ImpliedExtsZce}},
1087+
{"zcf", {ImpliedExtsZcf}},
1088+
{"zcmop", {ImpliedExtsZcmop}},
1089+
{"zcmp", {ImpliedExtsZcmp}},
1090+
{"zcmt", {ImpliedExtsZcmt}},
1091+
{"zdinx", {ImpliedExtsZdinx}},
1092+
{"zfa", {ImpliedExtsZfa}},
1093+
{"zfbfmin", {ImpliedExtsZfbfmin}},
1094+
{"zfh", {ImpliedExtsZfh}},
1095+
{"zfhmin", {ImpliedExtsZfhmin}},
1096+
{"zfinx", {ImpliedExtsZfinx}},
1097+
{"zhinx", {ImpliedExtsZhinx}},
1098+
{"zhinxmin", {ImpliedExtsZhinxmin}},
1099+
{"zicfiss", {ImpliedExtsZicfiss}},
1100+
{"zicntr", {ImpliedExtsZicntr}},
1101+
{"zihpm", {ImpliedExtsZihpm}},
1102+
{"zk", {ImpliedExtsZk}},
1103+
{"zkn", {ImpliedExtsZkn}},
1104+
{"zks", {ImpliedExtsZks}},
1105+
{"zvbb", {ImpliedExtsZvbb}},
1106+
{"zve32f", {ImpliedExtsZve32f}},
1107+
{"zve32x", {ImpliedExtsZve32x}},
1108+
{"zve64d", {ImpliedExtsZve64d}},
1109+
{"zve64f", {ImpliedExtsZve64f}},
1110+
{"zve64x", {ImpliedExtsZve64x}},
1111+
{"zvfbfmin", {ImpliedExtsZvfbfmin}},
1112+
{"zvfbfwma", {ImpliedExtsZvfbfwma}},
1113+
{"zvfh", {ImpliedExtsZvfh}},
1114+
{"zvfhmin", {ImpliedExtsZvfhmin}},
1115+
{"zvkn", {ImpliedExtsZvkn}},
1116+
{"zvknc", {ImpliedExtsZvknc}},
1117+
{"zvkng", {ImpliedExtsZvkng}},
1118+
{"zvknhb", {ImpliedExtsZvknhb}},
1119+
{"zvks", {ImpliedExtsZvks}},
1120+
{"zvksc", {ImpliedExtsZvksc}},
1121+
{"zvksg", {ImpliedExtsZvksg}},
1122+
{"zvl1024b", {ImpliedExtsZvl1024b}},
1123+
{"zvl128b", {ImpliedExtsZvl128b}},
1124+
{"zvl16384b", {ImpliedExtsZvl16384b}},
1125+
{"zvl2048b", {ImpliedExtsZvl2048b}},
1126+
{"zvl256b", {ImpliedExtsZvl256b}},
1127+
{"zvl32768b", {ImpliedExtsZvl32768b}},
1128+
{"zvl4096b", {ImpliedExtsZvl4096b}},
1129+
{"zvl512b", {ImpliedExtsZvl512b}},
1130+
{"zvl64b", {ImpliedExtsZvl64b}},
1131+
{"zvl65536b", {ImpliedExtsZvl65536b}},
1132+
{"zvl8192b", {ImpliedExtsZvl8192b}},
11361133
};
11371134

1135+
static_assert(isSorted(ImpliedExts) &&
1136+
"Implied extensions are not sorted by name");
1137+
11381138
void RISCVISAInfo::updateImplication() {
11391139
bool HasE = Exts.count("e") != 0;
11401140
bool HasI = Exts.count("i") != 0;
@@ -1146,8 +1146,6 @@ void RISCVISAInfo::updateImplication() {
11461146
addExtension("i", Version->Major, Version->Minor);
11471147
}
11481148

1149-
assert(llvm::is_sorted(ImpliedExts) && "Table not sorted by Name");
1150-
11511149
// This loop may execute over 1 iteration since implication can be layered
11521150
// Exits loop if no more implication is applied
11531151
SmallSetVector<StringRef, 16> WorkList;

0 commit comments

Comments
 (0)