27struct RISCVSupportedExtension {
32 bool operator<(
const RISCVSupportedExtension &RHS)
const {
41 bool operator<(
const RISCVProfile &RHS)
const {
49 "i",
"m",
"a",
"f",
"d",
"zicsr",
"zifencei"
52#define GET_SUPPORTED_EXTENSIONS
53#include "llvm/TargetParser/RISCVTargetParserDef.inc"
55#define GET_SUPPORTED_PROFILES
56#include "llvm/TargetParser/RISCVTargetParserDef.inc"
60 static std::atomic<bool> TableChecked(
false);
61 if (!TableChecked.load(std::memory_order_relaxed)) {
63 "Extensions are not sorted by name");
65 "Experimental extensions are not sorted by name");
67 "Profiles are not sorted by name");
69 "Experimental profiles are not sorted by name");
70 TableChecked.store(
true, std::memory_order_relaxed);
78 unsigned VersionWidth = Description.
empty() ? 0 : 10;
80 << Description <<
"\n";
84 outs() <<
"All available -march extensions for RISC-V\n\n";
88 for (
const auto &E : SupportedExtensions)
89 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
90 for (
const auto &E : ExtMap) {
92 std::to_string(E.second.Major) +
"." + std::to_string(E.second.Minor);
96 outs() <<
"\nExperimental extensions\n";
98 for (
const auto &E : SupportedExperimentalExtensions)
99 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
100 for (
const auto &E : ExtMap) {
102 std::to_string(E.second.Major) +
"." + std::to_string(E.second.Minor);
106 outs() <<
"\nSupported Profiles\n";
107 for (
const auto &
P : SupportedProfiles)
110 outs() <<
"\nExperimental Profiles\n";
111 for (
const auto &
P : SupportedExperimentalProfiles)
114 outs() <<
"\nUse -march to specify the target's extension.\n"
115 "For example, clang -march=rv32i_v1p0\n";
119 bool IsRV64, std::set<StringRef> &EnabledFeatureNames,
121 outs() <<
"Extensions enabled for the given RISC-V target\n\n";
126 for (
const auto &E : SupportedExtensions)
127 if (EnabledFeatureNames.count(E.Name) != 0) {
128 FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
129 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
131 for (
const auto &E : ExtMap) {
133 std::to_string(E.second.Major) +
"." + std::to_string(E.second.Minor);
137 outs() <<
"\nExperimental extensions\n";
139 for (
const auto &E : SupportedExperimentalExtensions) {
141 if (EnabledFeatureNames.count(
"experimental-" +
Name.str()) != 0) {
142 FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
143 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
146 for (
const auto &E : ExtMap) {
148 std::to_string(E.second.Major) +
"." + std::to_string(E.second.Minor);
152 unsigned XLen = IsRV64 ? 64 : 32;
154 outs() <<
"\nISA String: " << ISAString.get()->toString() <<
"\n";
158 return Ext.consume_front(
"experimental-");
170 "Already guarded by if-statement in ::parseArchString");
172 int Pos = Ext.size() - 1;
173 while (Pos > 0 &&
isDigit(Ext[Pos]))
175 if (Pos > 0 && Ext[Pos] ==
'p' &&
isDigit(Ext[Pos - 1])) {
177 while (Pos > 0 &&
isDigit(Ext[Pos]))
194static std::optional<RISCVISAUtils::ExtensionVersion>
198 for (
auto &ExtInfo : {
ArrayRef(SupportedExtensions),
199 ArrayRef(SupportedExperimentalExtensions)}) {
202 if (
I == ExtInfo.end() ||
I->Name != ExtName)
211 if (Ext.starts_with(
's'))
212 return "standard supervisor-level extension";
213 if (Ext.starts_with(
'x'))
214 return "non-standard user-level extension";
215 if (Ext.starts_with(
'z'))
216 return "standard user-level extension";
221 if (Ext.starts_with(
's'))
223 if (Ext.starts_with(
'x'))
225 if (Ext.starts_with(
'z'))
230static std::optional<RISCVISAUtils::ExtensionVersion>
234 if (
I == std::end(SupportedExperimentalExtensions) ||
I->Name != Ext)
244 IsExperimental ?
ArrayRef(SupportedExperimentalExtensions)
248 return I != ExtInfo.
end() &&
I->Name == Ext;
254 for (
auto ExtInfo : {
ArrayRef(SupportedExtensions),
255 ArrayRef(SupportedExperimentalExtensions)}) {
257 if (
I != ExtInfo.end() &&
I->Name == Ext)
265 unsigned MinorVersion) {
266 for (
auto ExtInfo : {
ArrayRef(SupportedExtensions),
267 ArrayRef(SupportedExperimentalExtensions)}) {
269 std::equal_range(ExtInfo.begin(), ExtInfo.end(), Ext, LessExtName());
271 if (
I->Version.Major == MajorVersion &&
I->Version.Minor == MinorVersion)
284 return Exts.count(Ext.str()) != 0;
288 bool IgnoreUnknown)
const {
289 std::vector<std::string> Features;
290 for (
const auto &[ExtName,
_] : Exts) {
300 Features.push_back((
llvm::Twine(
"+experimental-") + ExtName).str());
302 Features.push_back((
llvm::Twine(
"+") + ExtName).str());
305 if (AddAllExtensions) {
306 for (
const RISCVSupportedExtension &Ext : SupportedExtensions) {
307 if (Exts.count(Ext.Name))
309 Features.push_back((
llvm::Twine(
"-") + Ext.Name).str());
312 for (
const RISCVSupportedExtension &Ext : SupportedExperimentalExtensions) {
313 if (Exts.count(Ext.Name))
315 Features.push_back((
llvm::Twine(
"-experimental-") + Ext.Name).str());
326 if (ExtName.
size() == 1) {
327 return getError(
"unsupported standard user-level extension '" + ExtName +
340 unsigned &Minor,
unsigned &ConsumeLength,
341 bool EnableExperimentalExtension,
342 bool ExperimentalExtensionVersionCheck) {
347 MajorStr = In.take_while(
isDigit);
348 In = In.substr(MajorStr.
size());
350 if (!MajorStr.
empty() && In.consume_front(
"p")) {
351 MinorStr = In.take_while(
isDigit);
352 In = In.substr(MajorStr.
size() + MinorStr.
size() - 1);
355 if (MinorStr.
empty()) {
356 return getError(
"minor version number missing after 'p' for extension '" +
362 return getError(
"Failed to parse major version number for extension '" +
366 return getError(
"Failed to parse minor version number for extension '" +
369 ConsumeLength = MajorStr.
size();
371 if (!MinorStr.
empty())
372 ConsumeLength += MinorStr.
size() + 1 ;
377 if (Ext.size() > 1 && In.size())
379 "multi-character extensions must be separated by underscores");
383 if (!EnableExperimentalExtension)
384 return getError(
"requires '-menable-experimental-extensions' "
385 "for experimental extension '" +
388 if (ExperimentalExtensionVersionCheck &&
391 "experimental extension requires explicit version number `" + Ext +
394 auto SupportedVers = *ExperimentalExtension;
395 if (ExperimentalExtensionVersionCheck &&
396 (Major != SupportedVers.Major || Minor != SupportedVers.Minor)) {
397 std::string
Error =
"unsupported version number " + MajorStr.
str();
398 if (!MinorStr.
empty())
400 Error +=
" for experimental extension '" + Ext.str() +
401 "' (this compiler supports " + utostr(SupportedVers.Major) +
402 "." + utostr(SupportedVers.Minor) +
")";
415 Major = DefaultVersion->Major;
416 Minor = DefaultVersion->Minor;
429 std::string
Error =
"unsupported version number " + MajorStr.
str();
430 if (!MinorStr.
empty())
432 Error +=
" for extension '" + Ext.str() +
"'";
439 assert(XLen == 32 || XLen == 64);
440 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
442 ISAInfo->Exts = Exts;
444 return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
449 const std::vector<std::string> &Features) {
450 assert(XLen == 32 || XLen == 64);
451 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
453 for (
auto &Feature : Features) {
455 assert(ExtName.
size() > 1 && (ExtName[0] ==
'+' || ExtName[0] ==
'-'));
456 bool Add = ExtName[0] ==
'+';
459 auto ExtensionInfos = Experimental
460 ?
ArrayRef(SupportedExperimentalExtensions)
462 auto ExtensionInfoIterator =
467 if (ExtensionInfoIterator == ExtensionInfos.end() ||
468 ExtensionInfoIterator->Name != ExtName)
472 ISAInfo->Exts[ExtName.
str()] = ExtensionInfoIterator->Version;
474 ISAInfo->Exts.erase(ExtName.
str());
477 return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
485 return getError(
"string may only contain [a-z0-9_]");
494 if (XLen == 0 || Arch.
empty() || (Arch[0] !=
'i' && Arch[0] !=
'e'))
495 return getError(
"arch string must begin with valid base ISA");
497 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
502 while (!Arch.
empty()) {
503 if (Arch[0] ==
'_') {
504 if (Arch.
size() == 1 || Arch[1] ==
'_')
505 return getError(
"extension name missing after separator '_'");
514 std::tie(Prefix, MinorVersionStr) = Ext.rsplit(
'p');
515 if (MinorVersionStr.
empty())
516 return getError(
"extension lacks version in expected format");
517 unsigned MajorVersion, MinorVersion;
519 return getError(
"failed to parse minor version number");
523 size_t VersionStart = Prefix.size();
524 while (VersionStart != 0) {
525 if (!
isDigit(Prefix[VersionStart - 1]))
529 if (VersionStart == Prefix.size())
530 return getError(
"extension lacks version in expected format");
532 if (VersionStart == 0)
533 return getError(
"missing extension name");
535 StringRef ExtName = Prefix.slice(0, VersionStart);
538 return getError(
"failed to parse major version number");
540 if ((ExtName[0] ==
'z' || ExtName[0] ==
's' || ExtName[0] ==
'x') &&
543 "' must be followed by a letter");
550 return getError(
"duplicate extension '" + ExtName +
"'");
552 ISAInfo->updateImpliedLengths();
553 return std::move(ISAInfo);
558 bool ExperimentalExtensionVersionCheck) {
562 return getError(
"string may only contain [a-z0-9_]");
576 bool FoundProfile =
I != std::begin(SupportedProfiles) &&
580 FoundProfile = (
I != std::begin(SupportedExperimentalProfiles) &&
582 if (FoundProfile && !EnableExperimentalExtension) {
583 return getError(
"requires '-menable-experimental-extensions' "
585 std::prev(
I)->
Name +
"'");
590 std::string NewArch =
I->MArch.str();
592 if (!ArchWithoutProfile.
empty()) {
593 if (ArchWithoutProfile.
front() !=
'_')
594 return getError(
"additional extensions must be after separator '_'");
595 NewArch += ArchWithoutProfile.
str();
598 ExperimentalExtensionVersionCheck);
602 if (XLen == 0 || Arch.
empty())
604 "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
607 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
611 char Baseline = Arch.
front();
615 unsigned Major, Minor, ConsumeLength;
621 "\' should be 'e', 'i' or 'g'");
626 StringRef(&Baseline, 1), Arch, Major, Minor, ConsumeLength,
627 EnableExperimentalExtension, ExperimentalExtensionVersionCheck))
630 ISAInfo->Exts[std::string(1, Baseline)] = {Major, Minor};
635 return getError(
"version not supported for 'g'");
647 ISAInfo->Exts[std::string(Ext)] = {
Version->Major,
Version->Minor};
656 while (!Arch.
empty()) {
657 if (Arch.
front() ==
'_') {
658 if (Arch.
size() == 1 || Arch[1] ==
'_')
659 return getError(
"extension name missing after separator '_'");
670 Name = Ext.take_front(1);
671 Ext = Ext.drop_front();
673 Desc =
"standard user-level extension";
674 }
else if (Ext.front() ==
'z' || Ext.front() ==
's' ||
675 Ext.front() ==
'x') {
687 Name = Ext.substr(0, Pos);
688 Vers = Ext.substr(Pos);
695 return getError(
"invalid standard user-level extension '" +
696 Twine(Ext.front()) +
"'");
699 unsigned Major, Minor, ConsumeLength;
701 EnableExperimentalExtension,
702 ExperimentalExtensionVersionCheck))
705 if (
Name.size() == 1)
706 Ext = Ext.substr(ConsumeLength);
718 }
while (!Ext.empty());
721 return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
725 return getError(
"'" + Ext1 +
"' and '" + Ext2 +
726 "' extensions are incompatible");
730 return getError(
"'" + Ext +
"' requires '" + ReqExt +
731 "' extension to also be specified");
734Error RISCVISAInfo::checkDependency() {
735 bool HasE = Exts.count(
"e") != 0;
736 bool HasI = Exts.count(
"i") != 0;
737 bool HasC = Exts.count(
"c") != 0;
738 bool HasF = Exts.count(
"f") != 0;
739 bool HasD = Exts.count(
"d") != 0;
740 bool HasZfinx = Exts.count(
"zfinx") != 0;
741 bool HasVector = Exts.count(
"zve32x") != 0;
742 bool HasZvl = MinVLen != 0;
743 bool HasZcmt = Exts.count(
"zcmt") != 0;
748 if (HasF && HasZfinx)
751 if (HasZvl && !HasVector)
756 {
"zvbb",
"zvbc32e",
"zvkb",
"zvkg",
"zvkgs",
"zvkned",
"zvknha",
"zvksed",
"zvksh"})
760 if (!Exts.count(
"zve64x"))
761 for (
auto Ext : {
"zvknhb",
"zvbc"})
765 if ((HasZcmt || Exts.count(
"zcmp")) && HasD && (HasC || Exts.count(
"zcd")))
767 "' extension is incompatible with '" +
768 (HasC ?
"c" :
"zcd") +
769 "' extension when 'd' extension is enabled");
771 if (XLen != 32 && Exts.count(
"zcf"))
772 return getError(
"'zcf' is only supported for 'rv32'");
774 if (!(Exts.count(
"a") || Exts.count(
"zaamo")))
775 for (
auto Ext : {
"zacas",
"zabha"})
779 if (Exts.count(
"xwchc") != 0) {
781 return getError(
"'xwchc' is only supported for 'rv32'");
786 if (Exts.count(
"zcb") != 0)
810#define GET_IMPLIED_EXTENSIONS
811#include "llvm/TargetParser/RISCVTargetParserDef.inc"
813void RISCVISAInfo::updateImplication() {
814 bool HasE = Exts.count(
"e") != 0;
815 bool HasI = Exts.count(
"i") != 0;
819 if (!HasE && !HasI) {
832 for (
auto const &Ext : Exts)
835 while (!WorkList.
empty()) {
837 auto Range = std::equal_range(std::begin(ImpliedExts),
838 std::end(ImpliedExts), ExtName);
841 const char *ImpliedExt = Implied.ImpliedExt;
842 if (Exts.count(ImpliedExt))
844 auto Version = findDefaultVersion(ImpliedExt);
845 Exts[ImpliedExt] = *Version;
846 WorkList.push_back(ImpliedExt);
851 if (XLen == 32 && Exts.count(
"zce") && Exts.count(
"f") &&
852 !Exts.count(
"zcf")) {
859 {
"zk"}, {
"zkn"}, {
"zks"}, {
"zvkn"}, {
"zvknc"},
860 {
"zvkng"}, {
"zvks"}, {
"zvksc"}, {
"zvksg"},
863void RISCVISAInfo::updateCombination() {
864 bool MadeChange =
false;
868 if (Exts.count(CombineExt.str()))
873 auto Range = std::equal_range(std::begin(ImpliedExts),
874 std::end(ImpliedExts), CombineExt);
875 bool HasAllRequiredFeatures = std::all_of(
877 return Exts.count(Implied.ImpliedExt);
879 if (HasAllRequiredFeatures) {
881 Exts[CombineExt.str()] = *
Version;
885 }
while (MadeChange);
888void RISCVISAInfo::updateImpliedLengths() {
889 assert(FLen == 0 && MaxELenFp == 0 && MaxELen == 0 && MinVLen == 0 &&
890 "Expected lengths to be initialied to zero");
895 else if (Exts.count(
"f"))
898 if (Exts.count(
"v")) {
899 MaxELenFp = std::max(MaxELenFp, 64u);
900 MaxELen = std::max(MaxELen, 64u);
903 for (
auto const &Ext : Exts) {
912 MaxELenFp = std::max(MaxELenFp, 32u);
913 else if (ExtName ==
"d")
914 MaxELenFp = std::max(MaxELenFp, 64u);
915 else if (ExtName !=
"x")
918 MaxELen = std::max(MaxELen, ZveELen);
931 MinVLen = std::max(MinVLen, ZvlLen);
941 Arch <<
"rv" << XLen;
943 ListSeparator LS(
"_");
944 for (
auto const &Ext : Exts) {
946 auto ExtInfo = Ext.second;
947 Arch << LS << ExtName;
948 Arch << ExtInfo.Major <<
"p" << ExtInfo.Minor;
955RISCVISAInfo::postProcessAndChecking(std::unique_ptr<RISCVISAInfo> &&ISAInfo) {
956 ISAInfo->updateImplication();
957 ISAInfo->updateCombination();
958 ISAInfo->updateImpliedLengths();
960 if (
Error Result = ISAInfo->checkDependency())
961 return std::move(Result);
962 return std::move(ISAInfo);
974 }
else if (XLen == 64) {
996 unsigned Major, Minor, ConsumeLength;
1008 return std::string();
1014 return std::string();
1017 return std::string();
1030 {
"a", 0, 0}, {
"c", 0, 2},
1031 {
"d", 0, 3}, {
"f", 0, 5},
1032 {
"i", 0, 8}, {
"m", 0, 12},
1033 {
"v", 0, 21}, {
"zacas", 0, 26},
1034 {
"zba", 0, 27}, {
"zbb", 0, 28},
1035 {
"zbc", 0, 29}, {
"zbkb", 0, 30},
1036 {
"zbkc", 0, 31}, {
"zbkx", 0, 32},
1037 {
"zbs", 0, 33}, {
"zfa", 0, 34},
1038 {
"zfh", 0, 35}, {
"zfhmin", 0, 36},
1039 {
"zicboz", 0, 37}, {
"zicond", 0, 38},
1040 {
"zihintntl", 0, 39}, {
"zihintpause", 0, 40},
1041 {
"zknd", 0, 41}, {
"zkne", 0, 42},
1042 {
"zknh", 0, 43}, {
"zksed", 0, 44},
1043 {
"zksh", 0, 45}, {
"zkt", 0, 46},
1044 {
"ztso", 0, 47}, {
"zvbb", 0, 48},
1045 {
"zvbc", 0, 49}, {
"zvfh", 0, 50},
1046 {
"zvfhmin", 0, 51}, {
"zvkb", 0, 52},
1047 {
"zvkg", 0, 53}, {
"zvkned", 0, 54},
1048 {
"zvknha", 0, 55}, {
"zvknhb", 0, 56},
1049 {
"zvksed", 0, 57}, {
"zvksh", 0, 58},
1050 {
"zvkt", 0, 59}, {
"zve32x", 0, 60},
1051 {
"zve32f", 0, 61}, {
"zve64x", 0, 62},
1052 {
"zve64x", 0, 63}, {
"zve64d", 1, 0},
1053 {
"zimop", 1, 1}, {
"zca", 1, 2},
1054 {
"zcb", 1, 3}, {
"zcd", 1, 4},
1055 {
"zcf", 1, 5}, {
"zcmop", 1, 6},
1063 if (E.ext.equals_insensitive(Ext))
1064 return std::make_pair(E.groupid, E.bitpos);
1065 return std::make_pair(-1, -1);
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
std::optional< std::vector< StOtherPiece > > Other
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static void verifyTables()
static StringRef getExtensionTypeDesc(StringRef Ext)
static std::optional< RISCVISAUtils::ExtensionVersion > findDefaultVersion(StringRef ExtName)
static size_t findLastNonVersionCharacter(StringRef Ext)
static Error getExtensionRequiresError(StringRef Ext, StringRef ReqExt)
static constexpr RISCVExtBit RISCVBitPositions[]
static StringRef getExtensionType(StringRef Ext)
static Error getErrorForInvalidExt(StringRef ExtName)
static constexpr StringLiteral CombineIntoExts[]
static bool stripExperimentalPrefix(StringRef &Ext)
static std::optional< RISCVISAUtils::ExtensionVersion > isExperimentalExtension(StringRef Ext)
static void PrintExtension(StringRef Name, StringRef Version, StringRef Description)
static bool operator<(const ImpliedExtsEntry &LHS, StringRef RHS)
static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major, unsigned &Minor, unsigned &ConsumeLength, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck)
static Error getIncompatibleError(StringRef Ext1, StringRef Ext2)
static Error getError(const Twine &Message)
static const char * RISCVGImplications[]
static bool isDigit(const char C)
static bool isLower(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static void verifyTables()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
static bool isSupportedExtensionFeature(StringRef Ext)
static std::string getTargetFeatureForExtension(StringRef Ext)
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseNormalizedArchString(StringRef Arch)
Parse RISC-V ISA info from an arch string that is already in normalized form (as defined in the psABI...
bool hasExtension(StringRef Ext) const
std::string toString() const
StringRef computeDefaultABI() const
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static bool isSupportedExtension(StringRef Ext)
static void printEnabledExtensions(bool IsRV64, std::set< StringRef > &EnabledFeatureNames, StringMap< StringRef > &DescMap)
static void printSupportedExtensions(StringMap< StringRef > &DescMap)
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatures(unsigned XLen, const std::vector< std::string > &Features)
Parse RISC-V ISA info from feature vector.
static std::pair< int, int > getRISCVFeaturesBitsInfo(StringRef Ext)
Return the group id and bit position of __riscv_feature_bits.
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > createFromExtMap(unsigned XLen, const RISCVISAUtils::OrderedExtensionMap &Exts)
std::vector< std::string > toFeatures(bool AddAllExtensions=false, bool IgnoreUnknown=true) const
Convert RISC-V ISA info to a feature vector.
static bool isSupportedExtensionWithVersion(StringRef Ext)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
str - Get the contents as an std::string.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static constexpr size_t npos
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
constexpr StringLiteral AllStdExts
std::map< std::string, ExtensionVersion, ExtensionComparator > OrderedExtensionMap
OrderedExtensionMap is std::map, it's specialized to keep entries in canonical order of extension.
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
FormattedString left_justify(StringRef Str, unsigned Width)
left_justify - append spaces after string so total output is Width characters.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
void consumeError(Error Err)
Consume a Error without doing anything.
bool operator<(const ImpliedExtsEntry &Other) const
Description of the encoding of one expression Op.
Represents the major and version number components of a RISC-V extension.