LLVM 23.0.0git
RISCVTargetParser.cpp
Go to the documentation of this file.
1//===-- RISCVTargetParser.cpp - Parser for target features ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements a target parser to recognise hardware features
10// for RISC-V CPUs.
11//
12//===----------------------------------------------------------------------===//
13
16#include "llvm/ADT/SmallSet.h"
22
23namespace llvm {
24namespace RISCV {
25
26char ParserError::ID = 0;
27char ParserWarning::ID = 0;
28
29enum CPUKind : unsigned {
30#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN, \
31 FAST_VECTOR_UNALIGN, MVENDORID, MARCHID, MIMPID) \
32 CK_##ENUM,
33#define TUNE_PROC(ENUM, NAME) CK_##ENUM,
34#include "llvm/TargetParser/RISCVTargetParserDef.inc"
35};
36
37constexpr CPUInfo RISCVCPUInfo[] = {
38#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN, \
39 FAST_VECTOR_UNALIGN, MVENDORID, MARCHID, MIMPID) \
40 { \
41 NAME, \
42 DEFAULT_MARCH, \
43 FAST_SCALAR_UNALIGN, \
44 FAST_VECTOR_UNALIGN, \
45 {MVENDORID, MARCHID, MIMPID}, \
46 },
47#include "llvm/TargetParser/RISCVTargetParserDef.inc"
48};
49
51 for (auto &C : RISCVCPUInfo)
52 if (C.Name == CPU)
53 return &C;
54 return nullptr;
55}
56
58 const CPUInfo *Info = getCPUInfoByName(CPU);
59 return Info && Info->FastScalarUnalignedAccess;
60}
61
63 const CPUInfo *Info = getCPUInfoByName(CPU);
64 return Info && Info->FastVectorUnalignedAccess;
65}
66
67bool hasValidCPUModel(StringRef CPU) { return getCPUModel(CPU).isValid(); }
68
70 const CPUInfo *Info = getCPUInfoByName(CPU);
71 if (!Info)
72 return {0, 0, 0};
73 return Info->Model;
74}
75
77 if (!Model.isValid())
78 return "";
79
80 for (auto &C : RISCVCPUInfo)
81 if (C.Model == Model)
82 return C.Name;
83 return "";
84}
85
86bool parseCPU(StringRef CPU, bool IsRV64) {
87 const CPUInfo *Info = getCPUInfoByName(CPU);
88
89 if (!Info)
90 return false;
91 return Info->is64Bit() == IsRV64;
92}
93
94bool parseTuneCPU(StringRef TuneCPU, bool IsRV64) {
95 std::optional<CPUKind> Kind =
97#define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM)
98 #include "llvm/TargetParser/RISCVTargetParserDef.inc"
99 .Default(std::nullopt);
100
101 if (Kind.has_value())
102 return true;
103
104 // Fallback to parsing as a CPU.
105 return parseCPU(TuneCPU, IsRV64);
106}
107
109 const CPUInfo *Info = getCPUInfoByName(CPU);
110 if (!Info)
111 return "";
112 return Info->DefaultMarch;
113}
114
116 for (const auto &C : RISCVCPUInfo) {
117 if (IsRV64 == C.is64Bit())
118 Values.emplace_back(C.Name);
119 }
120}
121
123 for (const auto &C : RISCVCPUInfo) {
124 if (IsRV64 == C.is64Bit())
125 Values.emplace_back(C.Name);
126 }
127#define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME));
128#include "llvm/TargetParser/RISCVTargetParserDef.inc"
129}
130
131// This function is currently used by IREE, so it's not dead code.
133 SmallVectorImpl<std::string> &EnabledFeatures,
134 bool NeedPlus) {
135 StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(CPU);
136 if (MarchFromCPU == "")
137 return;
138
139 EnabledFeatures.clear();
141 MarchFromCPU, /* EnableExperimentalExtension */ true);
142
143 if (llvm::errorToBool(RII.takeError()))
144 return;
145
146 std::vector<std::string> FeatStrings =
147 (*RII)->toFeatures(/* AddAllExtensions */ false);
148 for (const auto &F : FeatStrings)
149 if (NeedPlus)
150 EnabledFeatures.push_back(F);
151 else
152 EnabledFeatures.push_back(F.substr(1));
153}
154
155namespace {
156class RISCVTuneFeatureLookupTable {
157 struct RISCVTuneFeature {
158 unsigned PosIdx;
159 unsigned NegIdx;
160 unsigned FeatureIdx;
161 };
162
163 struct RISCVImpliedTuneFeature {
164 unsigned FeatureIdx;
165 unsigned ImpliedFeatureIdx;
166 };
167
168 struct RISCVConfigurableTuneFeatures {
169 StringRef Processor;
170 unsigned DirectiveIdx;
171
172 bool operator<(const RISCVConfigurableTuneFeatures &RHS) const {
173 return Processor < RHS.Processor;
174 }
175 };
176
177#define GET_TUNE_FEATURES
178#define GET_CONFIGURABLE_TUNE_FEATURES
179#include "llvm/TargetParser/RISCVTargetParserDef.inc"
180
181 // Positive directive name -> Feature name
182 StringMap<StringRef> PositiveMap;
183 // Negative directive name -> Feature name
184 StringMap<StringRef> NegativeMap;
185
186 StringMap<SmallVector<StringRef>> ImpliedFeatureMap;
187 StringMap<SmallVector<StringRef>> InvImpliedFeatureMap;
188
189public:
190 using SmallStringSet = SmallSet<StringRef, 4>;
191
192 static void getAllTuneFeatures(SmallVectorImpl<StringRef> &Features) {
193 for (const auto &TuneFeature : TuneFeatures)
194 Features.push_back(TuneFeatureStrings[TuneFeature.FeatureIdx]);
195 }
196
197 static void getConfigurableFeatures(StringRef ProcName,
198 SmallStringSet &Directives) {
199 // Entries for the same processor are always put together.
200 auto [ItFirst, ItEnd] =
201 std::equal_range(std::begin(ConfigurableTuneFeatures),
202 std::end(ConfigurableTuneFeatures),
203 RISCVConfigurableTuneFeatures{ProcName, 0});
204 for (; ItFirst != ItEnd; ++ItFirst)
205 Directives.insert(TuneFeatureStrings[ItFirst->DirectiveIdx]);
206 }
207
208 RISCVTuneFeatureLookupTable() {
209 for (const auto &TuneFeature : TuneFeatures) {
210 StringRef PosDirective = TuneFeatureStrings[TuneFeature.PosIdx];
211 StringRef NegDirective = TuneFeatureStrings[TuneFeature.NegIdx];
212 StringRef FeatureName = TuneFeatureStrings[TuneFeature.FeatureIdx];
213 PositiveMap[PosDirective] = FeatureName;
214 NegativeMap[NegDirective] = FeatureName;
215 }
216
217 for (const auto &Imp : ImpliedTuneFeatures) {
218 StringRef Feature = TuneFeatureStrings[Imp.FeatureIdx];
219 StringRef ImpliedFeature = TuneFeatureStrings[Imp.ImpliedFeatureIdx];
220 ImpliedFeatureMap[Feature].push_back(ImpliedFeature);
221 InvImpliedFeatureMap[ImpliedFeature].push_back(Feature);
222 }
223 }
224
225 /// Returns {Feature name, Is positive or not}, or empty feature name
226 /// if not found.
227 std::pair<StringRef, bool> getFeature(StringRef DirectiveName) const {
228 auto It = PositiveMap.find(DirectiveName);
229 if (It != PositiveMap.end())
230 return {It->getValue(), /*IsPositive=*/true};
231
232 return {NegativeMap.lookup(DirectiveName), /*IsPositive=*/false};
233 }
234
235 /// Returns the implied features, or empty ArrayRef if not found. Note:
236 /// ImpliedFeatureMap / InvImpliedFeatureMap are the owners of these implied
237 /// feature lists, so we can just return the ArrayRef.
238 ArrayRef<StringRef> featureImplies(StringRef FeatureName,
239 bool Inverse = false) const {
240 const auto &Map = Inverse ? InvImpliedFeatureMap : ImpliedFeatureMap;
241 auto It = Map.find(FeatureName);
242 if (It == Map.end())
243 return {};
244 return It->second;
245 }
246};
247} // namespace
248
250 RISCVTuneFeatureLookupTable::getAllTuneFeatures(Features);
251}
252
254 SmallVectorImpl<std::string> &ResFeatures) {
255 RISCVTuneFeatureLookupTable TFLookup;
256 using SmallStringSet = RISCVTuneFeatureLookupTable::SmallStringSet;
257
258 // Do not create ParserWarning right away. Instead, we store the warning
259 // message until the last moment.
260 std::string WarningMsg;
261
262 TFString = TFString.trim();
263 if (TFString.empty())
264 return Error::success();
265
266 // Note: StringSet is not really ergonomic to use in this case here.
267 SmallStringSet PositiveFeatures;
268 SmallStringSet NegativeFeatures;
269 SmallStringSet PerProcDirectives;
270 RISCVTuneFeatureLookupTable::getConfigurableFeatures(ProcName,
271 PerProcDirectives);
272 if (PerProcDirectives.empty() && !ProcName.empty())
273 return make_error<ParserError>("Processor '" + Twine(ProcName) +
274 "' has no "
275 "configurable tuning features");
276
277 // Phase 1: Collect explicit features.
278 StringRef DirectiveStr;
279 do {
280 std::tie(DirectiveStr, TFString) = TFString.split(",");
281 auto [FeatureName, IsPositive] = TFLookup.getFeature(DirectiveStr);
282 if (FeatureName.empty()) {
283 raw_string_ostream SS(WarningMsg);
284 SS << "unrecognized tune feature directive '" << DirectiveStr << "'";
285 continue;
286 }
287
288 auto &Features = IsPositive ? PositiveFeatures : NegativeFeatures;
289 if (!Features.insert(FeatureName).second)
291 "cannot specify more than one instance of '" + Twine(DirectiveStr) +
292 "'");
293
294 if (!PerProcDirectives.count(DirectiveStr) && !ProcName.empty())
295 return make_error<ParserError>("Directive '" + Twine(DirectiveStr) +
296 "' is not "
297 "allowed to be used with processor '" +
298 Twine(ProcName) + "'");
299 } while (!TFString.empty());
300
301 auto Intersection =
302 llvm::set_intersection(PositiveFeatures, NegativeFeatures);
303 if (!Intersection.empty()) {
304 std::string IntersectedStr = join(Intersection, "', '");
305 return make_error<ParserError>("Feature(s) '" + Twine(IntersectedStr) +
306 "' cannot appear in both "
307 "positive and negative directives");
308 }
309
310 // Phase 2: Derive implied features.
311 SmallStringSet DerivedPosFeatures;
312 SmallStringSet DerivedNegFeatures;
313 for (StringRef PF : PositiveFeatures) {
314 if (auto FeatureList = TFLookup.featureImplies(PF); !FeatureList.empty())
315 DerivedPosFeatures.insert_range(FeatureList);
316 }
317 for (StringRef NF : NegativeFeatures) {
318 if (auto FeatureList = TFLookup.featureImplies(NF, /*Inverse=*/true);
319 !FeatureList.empty())
320 DerivedNegFeatures.insert_range(FeatureList);
321 }
322 PositiveFeatures.insert_range(DerivedPosFeatures);
323 NegativeFeatures.insert_range(DerivedNegFeatures);
324
325 Intersection = llvm::set_intersection(PositiveFeatures, NegativeFeatures);
326 if (!Intersection.empty()) {
327 std::string IntersectedStr = join(Intersection, "', '");
328 return make_error<ParserError>("Feature(s) '" + Twine(IntersectedStr) +
329 "' were implied by both "
330 "positive and negative directives");
331 }
332
333 // Export the result.
334 const std::string PosPrefix("+");
335 const std::string NegPrefix("-");
336 for (StringRef PF : PositiveFeatures)
337 ResFeatures.emplace_back(PosPrefix + PF.str());
338 for (StringRef NF : NegativeFeatures)
339 ResFeatures.emplace_back(NegPrefix + NF.str());
340
341 if (WarningMsg.empty())
342 return Error::success();
343
344 return make_error<ParserWarning>(WarningMsg);
345}
346
348 SmallVectorImpl<StringRef> &Directives) {
349 RISCVTuneFeatureLookupTable::SmallStringSet DirectiveSet;
350 RISCVTuneFeatureLookupTable::getConfigurableFeatures(CPU, DirectiveSet);
351 Directives.assign(DirectiveSet.begin(), DirectiveSet.end());
352}
353} // namespace RISCV
354
355namespace RISCVVType {
356// Encode VTYPE into the binary format used by the the VSETVLI instruction which
357// is used by our MC layer representation.
358//
359// Bits | Name | Description
360// -----+------------+------------------------------------------------
361// 8 | altfmt | Alternative format for bf16/ofp8
362// 7 | vma | Vector mask agnostic
363// 6 | vta | Vector tail agnostic
364// 5:3 | vsew[2:0] | Standard element width (SEW) setting
365// 2:0 | vlmul[2:0] | Vector register group multiplier (LMUL) setting
366unsigned encodeVTYPE(VLMUL VLMul, unsigned SEW, bool TailAgnostic,
367 bool MaskAgnostic, bool AltFmt) {
368 assert(isValidSEW(SEW) && "Invalid SEW");
369 unsigned VLMulBits = static_cast<unsigned>(VLMul);
370 unsigned VSEWBits = encodeSEW(SEW);
371 unsigned VTypeI = (VSEWBits << 3) | (VLMulBits & 0x7);
372 if (TailAgnostic)
373 VTypeI |= 0x40;
374 if (MaskAgnostic)
375 VTypeI |= 0x80;
376 if (AltFmt)
377 VTypeI |= 0x100;
378
379 return VTypeI;
380}
381
382unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt) {
383 assert(isValidSEW(SEW) && "Invalid SEW");
384 assert((Widen == 1 || Widen == 2 || Widen == 4) && "Invalid Widen");
385 unsigned VSEWBits = encodeSEW(SEW);
386 unsigned TWiden = Log2_32(Widen) + 1;
387 unsigned VTypeI = (VSEWBits << 3) | AltFmt << 8 | TWiden << 9;
388 return VTypeI;
389}
390
391namespace IME {
392static void assertValidXLenForVType(unsigned XLen) {
393 assert((XLen == 32 || XLen == 64) && "Invalid XLEN");
394}
395
396static unsigned getLambdaShift(unsigned XLen) {
398 return XLen - 4;
399}
400
401static unsigned getAltFmtAShift(unsigned XLen) {
403 return XLen - 6;
404}
405
406static unsigned getAltFmtBShift(unsigned XLen) {
408 return XLen - 7;
409}
410
411static unsigned getBSShift(unsigned XLen) {
413 return XLen - 5;
414}
415
416unsigned encodeLambda(unsigned Lambda) {
417 assert(isValidLambda(Lambda) && "Invalid IME lambda");
418 if (Lambda == 0)
419 return 0;
420 return Log2_32(Lambda) + 1;
421}
422
423std::optional<unsigned> decodeLambda(unsigned Encoding) {
424 assert(Encoding < 8 && "Invalid IME lambda encoding");
425 if (Encoding == 0)
426 return std::nullopt;
427 return 1U << (Encoding - 1);
428}
429
432 return (0x7ULL << getLambdaShift(XLen)) | (1ULL << getAltFmtAShift(XLen)) |
433 (1ULL << getAltFmtBShift(XLen)) | (1ULL << getBSShift(XLen));
434}
435
436uint64_t encodeVTypeFields(unsigned XLen, unsigned Lambda, bool AltFmtA,
437 bool AltFmtB, bool BlockSize16) {
439 uint64_t VType = uint64_t(encodeLambda(Lambda)) << getLambdaShift(XLen);
440 if (AltFmtA)
441 VType |= 1ULL << getAltFmtAShift(XLen);
442 if (AltFmtB)
443 VType |= 1ULL << getAltFmtBShift(XLen);
444 if (BlockSize16)
445 VType |= 1ULL << getBSShift(XLen);
446 return VType;
447}
448
449uint64_t addVTypeFields(uint64_t VType, unsigned XLen, unsigned Lambda,
450 bool AltFmtA, bool AltFmtB, bool BlockSize16) {
451 return (VType & ~getVTypeFieldsMask(XLen)) |
452 encodeVTypeFields(XLen, Lambda, AltFmtA, AltFmtB, BlockSize16);
453}
454
455unsigned getLambdaEncoding(uint64_t VType, unsigned XLen) {
457 return (VType >> getLambdaShift(XLen)) & 0x7;
458}
459
460std::optional<unsigned> getLambda(uint64_t VType, unsigned XLen) {
461 return decodeLambda(getLambdaEncoding(VType, XLen));
462}
463
464bool isAltFmtA(uint64_t VType, unsigned XLen) {
466 return VType & (1ULL << getAltFmtAShift(XLen));
467}
468
469bool isAltFmtB(uint64_t VType, unsigned XLen) {
471 return VType & (1ULL << getAltFmtBShift(XLen));
472}
473
474bool isBlockSize16(uint64_t VType, unsigned XLen) {
476 return VType & (1ULL << getBSShift(XLen));
477}
478} // namespace IME
479
480std::pair<unsigned, bool> decodeVLMUL(VLMUL VLMul) {
481 switch (VLMul) {
482 default:
483 llvm_unreachable("Unexpected LMUL value!");
484 case LMUL_1:
485 case LMUL_2:
486 case LMUL_4:
487 case LMUL_8:
488 return std::make_pair(1 << static_cast<unsigned>(VLMul), false);
489 case LMUL_F2:
490 case LMUL_F4:
491 case LMUL_F8:
492 return std::make_pair(1 << (8 - static_cast<unsigned>(VLMul)), true);
493 }
494}
495
496void printVType(unsigned VType, raw_ostream &OS) {
497 unsigned Sew = getSEW(VType);
498 OS << "e" << Sew;
499
500 bool AltFmt = RISCVVType::isAltFmt(VType);
501 if (AltFmt)
502 OS << "alt";
503
504 unsigned LMul;
505 bool Fractional;
506 std::tie(LMul, Fractional) = decodeVLMUL(getVLMUL(VType));
507
508 if (Fractional)
509 OS << ", mf";
510 else
511 OS << ", m";
512 OS << LMul;
513
514 if (isTailAgnostic(VType))
515 OS << ", ta";
516 else
517 OS << ", tu";
518
519 if (isMaskAgnostic(VType))
520 OS << ", ma";
521 else
522 OS << ", mu";
523}
524
525void printXSfmmVType(unsigned VType, raw_ostream &OS) {
526 OS << "e" << getSEW(VType) << ", w" << getXSfmmWiden(VType);
527}
528
529unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul) {
530 unsigned LMul;
531 bool Fractional;
532 std::tie(LMul, Fractional) = decodeVLMUL(VLMul);
533
534 // Convert LMul to a fixed point value with 3 fractional bits.
535 LMul = Fractional ? (8 / LMul) : (LMul * 8);
536
537 assert(SEW >= 8 && "Unexpected SEW value");
538 return (SEW * 8) / LMul;
539}
540
541std::optional<VLMUL> getSameRatioLMUL(unsigned Ratio, unsigned EEW) {
542 unsigned EMULFixedPoint = (EEW * 8) / Ratio;
543 bool Fractional = EMULFixedPoint < 8;
544 unsigned EMUL = Fractional ? 8 / EMULFixedPoint : EMULFixedPoint / 8;
545 if (!isValidLMUL(EMUL, Fractional))
546 return std::nullopt;
547 return RISCVVType::encodeLMUL(EMUL, Fractional);
548}
549
550} // namespace RISCVVType
551
552} // namespace llvm
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define ENUM(Name,...)
Definition ClauseT.h:60
#define F(x, y, z)
Definition MD5.cpp:54
#define TUNE_PROC(ENUM, NAME)
This file defines generic set operations that may be used on set's of different types,...
This file defines the SmallSet class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Value * RHS
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
const_iterator begin() const
Definition SmallSet.h:216
const_iterator end() const
Definition SmallSet.h:222
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:730
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition StringRef.h:844
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
static unsigned getAltFmtBShift(unsigned XLen)
LLVM_ABI bool isAltFmtB(uint64_t VType, unsigned XLen)
LLVM_ABI std::optional< unsigned > getLambda(uint64_t VType, unsigned XLen)
LLVM_ABI bool isBlockSize16(uint64_t VType, unsigned XLen)
static bool isValidLambda(unsigned Lambda)
static unsigned getBSShift(unsigned XLen)
LLVM_ABI uint64_t addVTypeFields(uint64_t VType, unsigned XLen, unsigned Lambda, bool AltFmtA, bool AltFmtB, bool BlockSize16)
LLVM_ABI bool isAltFmtA(uint64_t VType, unsigned XLen)
LLVM_ABI unsigned getLambdaEncoding(uint64_t VType, unsigned XLen)
LLVM_ABI std::optional< unsigned > decodeLambda(unsigned Encoding)
LLVM_ABI uint64_t getVTypeFieldsMask(unsigned XLen)
LLVM_ABI uint64_t encodeVTypeFields(unsigned XLen, unsigned Lambda, bool AltFmtA, bool AltFmtB, bool BlockSize16)
static void assertValidXLenForVType(unsigned XLen)
static unsigned getLambdaShift(unsigned XLen)
static unsigned getAltFmtAShift(unsigned XLen)
LLVM_ABI unsigned encodeLambda(unsigned Lambda)
static bool isTailAgnostic(unsigned VType)
static VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
LLVM_ABI void printXSfmmVType(unsigned VType, raw_ostream &OS)
LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt)
static unsigned getXSfmmWiden(unsigned VType)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
LLVM_ABI std::optional< VLMUL > getSameRatioLMUL(unsigned Ratio, unsigned EEW)
static bool isMaskAgnostic(unsigned VType)
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
static unsigned encodeSEW(unsigned SEW)
LLVM_ABI unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul)
static bool isValidSEW(unsigned SEW)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static bool isAltFmt(unsigned VType)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
static unsigned getSEW(unsigned VType)
static VLMUL getVLMUL(unsigned VType)
LLVM_ABI bool hasFastVectorUnalignedAccess(StringRef CPU)
LLVM_ABI void getFeaturesForCPU(StringRef CPU, SmallVectorImpl< std::string > &EnabledFeatures, bool NeedPlus=false)
LLVM_ABI void fillValidTuneCPUArchList(SmallVectorImpl< StringRef > &Values, bool IsRV64)
static const CPUInfo * getCPUInfoByName(StringRef CPU)
constexpr CPUInfo RISCVCPUInfo[]
LLVM_ABI CPUModel getCPUModel(StringRef CPU)
LLVM_ABI Error parseTuneFeatureString(StringRef ProcName, StringRef TFString, SmallVectorImpl< std::string > &TuneFeatures)
Parse the tune feature string with the respective processor.
LLVM_ABI void getAllTuneFeatures(SmallVectorImpl< StringRef > &TuneFeatures)
LLVM_ABI StringRef getMArchFromMcpu(StringRef CPU)
LLVM_ABI bool parseCPU(StringRef CPU, bool IsRV64)
LLVM_ABI bool hasFastScalarUnalignedAccess(StringRef CPU)
LLVM_ABI bool hasValidCPUModel(StringRef CPU)
LLVM_ABI StringRef getCPUNameFromCPUModel(const CPUModel &Model)
LLVM_ABI bool parseTuneCPU(StringRef CPU, bool IsRV64)
LLVM_ABI void fillValidCPUArchList(SmallVectorImpl< StringRef > &Values, bool IsRV64)
LLVM_ABI void getCPUConfigurableTuneFeatures(StringRef CPU, SmallVectorImpl< StringRef > &Directives)
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
Definition Error.h:1129
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
S1Ty set_intersection(const S1Ty &S1, const S2Ty &S2)
set_intersection(A, B) - Return A ^ B
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
ArrayRef(const T &OneElt) -> ArrayRef< T >