clang 18.0.0git
SemaRISCVVectorLookup.cpp
Go to the documentation of this file.
1//==- SemaRISCVVectorLookup.cpp - Name Lookup for RISC-V Vector Intrinsic -==//
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 name lookup for RISC-V vector intrinsic.
10//
11//===----------------------------------------------------------------------===//
12
14#include "clang/AST/Decl.h"
18#include "clang/Sema/Lookup.h"
20#include "clang/Sema/Sema.h"
22#include "llvm/ADT/SmallVector.h"
23#include <optional>
24#include <string>
25#include <vector>
26
27using namespace llvm;
28using namespace clang;
29using namespace clang::RISCV;
30
32
33namespace {
34
35// Function definition of a RVV intrinsic.
36struct RVVIntrinsicDef {
37 /// Full function name with suffix, e.g. vadd_vv_i32m1.
38 std::string Name;
39
40 /// Overloaded function name, e.g. vadd.
41 std::string OverloadName;
42
43 /// Mapping to which clang built-in function, e.g. __builtin_rvv_vadd.
44 std::string BuiltinName;
45
46 /// Function signature, first element is return type.
47 RVVTypes Signature;
48};
49
50struct RVVOverloadIntrinsicDef {
51 // Indexes of RISCVIntrinsicManagerImpl::IntrinsicList.
53};
54
55} // namespace
56
58#define DECL_SIGNATURE_TABLE
59#include "clang/Basic/riscv_vector_builtin_sema.inc"
60#undef DECL_SIGNATURE_TABLE
61};
62
64#define DECL_SIGNATURE_TABLE
65#include "clang/Basic/riscv_sifive_vector_builtin_sema.inc"
66#undef DECL_SIGNATURE_TABLE
67};
68
70#define DECL_INTRINSIC_RECORDS
71#include "clang/Basic/riscv_vector_builtin_sema.inc"
72#undef DECL_INTRINSIC_RECORDS
73};
74
76#define DECL_INTRINSIC_RECORDS
77#include "clang/Basic/riscv_sifive_vector_builtin_sema.inc"
78#undef DECL_INTRINSIC_RECORDS
79};
80
81// Get subsequence of signature table.
83ProtoSeq2ArrayRef(IntrinsicKind K, uint16_t Index, uint8_t Length) {
84 switch (K) {
85 case IntrinsicKind::RVV:
86 return ArrayRef(&RVVSignatureTable[Index], Length);
87 case IntrinsicKind::SIFIVE_VECTOR:
88 return ArrayRef(&RVSiFiveVectorSignatureTable[Index], Length);
89 }
90 llvm_unreachable("Unhandled IntrinsicKind");
91}
92
93static QualType RVVType2Qual(ASTContext &Context, const RVVType *Type) {
94 QualType QT;
95 switch (Type->getScalarType()) {
96 case ScalarTypeKind::Void:
97 QT = Context.VoidTy;
98 break;
99 case ScalarTypeKind::Size_t:
100 QT = Context.getSizeType();
101 break;
102 case ScalarTypeKind::Ptrdiff_t:
103 QT = Context.getPointerDiffType();
104 break;
105 case ScalarTypeKind::UnsignedLong:
106 QT = Context.UnsignedLongTy;
107 break;
108 case ScalarTypeKind::SignedLong:
109 QT = Context.LongTy;
110 break;
111 case ScalarTypeKind::Boolean:
112 QT = Context.BoolTy;
113 break;
114 case ScalarTypeKind::SignedInteger:
115 QT = Context.getIntTypeForBitwidth(Type->getElementBitwidth(), true);
116 break;
117 case ScalarTypeKind::UnsignedInteger:
118 QT = Context.getIntTypeForBitwidth(Type->getElementBitwidth(), false);
119 break;
120 case ScalarTypeKind::Float:
121 switch (Type->getElementBitwidth()) {
122 case 64:
123 QT = Context.DoubleTy;
124 break;
125 case 32:
126 QT = Context.FloatTy;
127 break;
128 case 16:
129 QT = Context.Float16Ty;
130 break;
131 default:
132 llvm_unreachable("Unsupported floating point width.");
133 }
134 break;
135 case Invalid:
136 case Undefined:
137 llvm_unreachable("Unhandled type.");
138 }
139 if (Type->isVector()) {
140 if (Type->isTuple())
141 QT = Context.getScalableVectorType(QT, *Type->getScale(), Type->getNF());
142 else
143 QT = Context.getScalableVectorType(QT, *Type->getScale());
144 }
145
146 if (Type->isConstant())
147 QT = Context.getConstType(QT);
148
149 // Transform the type to a pointer as the last step, if necessary.
150 if (Type->isPointer())
151 QT = Context.getPointerType(QT);
152
153 return QT;
154}
155
156namespace {
157class RISCVIntrinsicManagerImpl : public sema::RISCVIntrinsicManager {
158private:
159 Sema &S;
160 ASTContext &Context;
161 RVVTypeCache TypeCache;
162 bool ConstructedRISCVVBuiltins;
163 bool ConstructedRISCVSiFiveVectorBuiltins;
164
165 // List of all RVV intrinsic.
166 std::vector<RVVIntrinsicDef> IntrinsicList;
167 // Mapping function name to index of IntrinsicList.
168 StringMap<size_t> Intrinsics;
169 // Mapping function name to RVVOverloadIntrinsicDef.
170 StringMap<RVVOverloadIntrinsicDef> OverloadIntrinsics;
171
172
173 // Create RVVIntrinsicDef.
174 void InitRVVIntrinsic(const RVVIntrinsicRecord &Record, StringRef SuffixStr,
175 StringRef OverloadedSuffixStr, bool IsMask,
176 RVVTypes &Types, bool HasPolicy, Policy PolicyAttrs);
177
178 // Create FunctionDecl for a vector intrinsic.
179 void CreateRVVIntrinsicDecl(LookupResult &LR, IdentifierInfo *II,
180 Preprocessor &PP, unsigned Index,
181 bool IsOverload);
182
183 void ConstructRVVIntrinsics(ArrayRef<RVVIntrinsicRecord> Recs,
184 IntrinsicKind K);
185
186public:
187 RISCVIntrinsicManagerImpl(clang::Sema &S) : S(S), Context(S.Context) {
188 ConstructedRISCVVBuiltins = false;
189 ConstructedRISCVSiFiveVectorBuiltins = false;
190 }
191
192 // Initialize IntrinsicList
193 void InitIntrinsicList() override;
194
195 // Create RISC-V vector intrinsic and insert into symbol table if found, and
196 // return true, otherwise return false.
198 Preprocessor &PP) override;
199};
200} // namespace
201
202void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
204 const TargetInfo &TI = Context.getTargetInfo();
205 static const std::pair<const char *, RVVRequire> FeatureCheckList[] = {
206 {"64bit", RVV_REQ_RV64},
207 {"xsfvcp", RVV_REQ_Xsfvcp},
208 {"experimental-zvbb", RVV_REQ_Zvbb},
209 {"experimental-zvbc", RVV_REQ_Zvbc},
210 {"experimental-zvkb", RVV_REQ_Zvkb},
211 {"experimental-zvkg", RVV_REQ_Zvkg},
212 {"experimental-zvkned", RVV_REQ_Zvkned},
213 {"experimental-zvknha", RVV_REQ_Zvknha},
214 {"experimental-zvksed", RVV_REQ_Zvksed},
215 {"experimental-zvksh", RVV_REQ_Zvksh}};
216
217 // Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics
218 // in RISCVVEmitter.cpp.
219 for (auto &Record : Recs) {
220 // Check requirements.
221 if (llvm::any_of(FeatureCheckList, [&](const auto &Item) {
222 return (Record.RequiredExtensions & Item.second) == Item.second &&
223 !TI.hasFeature(Item.first);
224 }))
225 continue;
226
227 // Create Intrinsics for each type and LMUL.
228 BasicType BaseType = BasicType::Unknown;
229 ArrayRef<PrototypeDescriptor> BasicProtoSeq =
230 ProtoSeq2ArrayRef(K, Record.PrototypeIndex, Record.PrototypeLength);
232 ProtoSeq2ArrayRef(K, Record.SuffixIndex, Record.SuffixLength);
233 ArrayRef<PrototypeDescriptor> OverloadedSuffixProto = ProtoSeq2ArrayRef(
234 K, Record.OverloadedSuffixIndex, Record.OverloadedSuffixSize);
235
236 PolicyScheme UnMaskedPolicyScheme =
237 static_cast<PolicyScheme>(Record.UnMaskedPolicyScheme);
238 PolicyScheme MaskedPolicyScheme =
239 static_cast<PolicyScheme>(Record.MaskedPolicyScheme);
240
241 const Policy DefaultPolicy;
242
245 BasicProtoSeq, /*IsMasked=*/false,
246 /*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
247 UnMaskedPolicyScheme, DefaultPolicy, Record.IsTuple);
248
250 if (Record.HasMasked)
252 BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
253 Record.HasVL, Record.NF, MaskedPolicyScheme, DefaultPolicy,
254 Record.IsTuple);
255
256 bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone;
257 bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone;
258 SmallVector<Policy> SupportedUnMaskedPolicies =
260 SmallVector<Policy> SupportedMaskedPolicies =
262 Record.HasMaskPolicy);
263
264 for (unsigned int TypeRangeMaskShift = 0;
265 TypeRangeMaskShift <= static_cast<unsigned int>(BasicType::MaxOffset);
266 ++TypeRangeMaskShift) {
267 unsigned int BaseTypeI = 1 << TypeRangeMaskShift;
268 BaseType = static_cast<BasicType>(BaseTypeI);
269
270 if ((BaseTypeI & Record.TypeRangeMask) != BaseTypeI)
271 continue;
272
273 if (BaseType == BasicType::Float16) {
274 if ((Record.RequiredExtensions & RVV_REQ_ZvfhminOrZvfh) ==
276 if (!TI.hasFeature("zvfh") && !TI.hasFeature("zvfhmin"))
277 continue;
278 } else if (!TI.hasFeature("zvfh")) {
279 continue;
280 }
281 }
282
283 // Expanded with different LMUL.
284 for (int Log2LMUL = -3; Log2LMUL <= 3; Log2LMUL++) {
285 if (!(Record.Log2LMULMask & (1 << (Log2LMUL + 3))))
286 continue;
287
288 std::optional<RVVTypes> Types =
289 TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoSeq);
290
291 // Ignored to create new intrinsic if there are any illegal types.
292 if (!Types.has_value())
293 continue;
294
295 std::string SuffixStr = RVVIntrinsic::getSuffixStr(
296 TypeCache, BaseType, Log2LMUL, SuffixProto);
297 std::string OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
298 TypeCache, BaseType, Log2LMUL, OverloadedSuffixProto);
299
300 // Create non-masked intrinsic.
301 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, false, *Types,
302 UnMaskedHasPolicy, DefaultPolicy);
303
304 // Create non-masked policy intrinsic.
305 if (Record.UnMaskedPolicyScheme != PolicyScheme::SchemeNone) {
306 for (auto P : SupportedUnMaskedPolicies) {
309 BasicProtoSeq, /*IsMasked=*/false,
310 /*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
311 UnMaskedPolicyScheme, P, Record.IsTuple);
312 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
313 BaseType, Log2LMUL, Record.NF, PolicyPrototype);
314 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
315 /*IsMask=*/false, *PolicyTypes, UnMaskedHasPolicy,
316 P);
317 }
318 }
319 if (!Record.HasMasked)
320 continue;
321 // Create masked intrinsic.
322 std::optional<RVVTypes> MaskTypes =
323 TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoMaskSeq);
324 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, true,
325 *MaskTypes, MaskedHasPolicy, DefaultPolicy);
326 if (Record.MaskedPolicyScheme == PolicyScheme::SchemeNone)
327 continue;
328 // Create masked policy intrinsic.
329 for (auto P : SupportedMaskedPolicies) {
332 BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
333 Record.HasVL, Record.NF, MaskedPolicyScheme, P,
334 Record.IsTuple);
335 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
336 BaseType, Log2LMUL, Record.NF, PolicyPrototype);
337 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
338 /*IsMask=*/true, *PolicyTypes, MaskedHasPolicy, P);
339 }
340 } // End for different LMUL
341 } // End for different TypeRange
342 }
343}
344
345void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
346
347 if (S.DeclareRISCVVBuiltins && !ConstructedRISCVVBuiltins) {
348 ConstructedRISCVVBuiltins = true;
349 ConstructRVVIntrinsics(RVVIntrinsicRecords,
350 IntrinsicKind::RVV);
351 }
353 !ConstructedRISCVSiFiveVectorBuiltins) {
354 ConstructedRISCVSiFiveVectorBuiltins = true;
355 ConstructRVVIntrinsics(RVSiFiveVectorIntrinsicRecords,
356 IntrinsicKind::SIFIVE_VECTOR);
357 }
358}
359
360// Compute name and signatures for intrinsic with practical types.
361void RISCVIntrinsicManagerImpl::InitRVVIntrinsic(
362 const RVVIntrinsicRecord &Record, StringRef SuffixStr,
363 StringRef OverloadedSuffixStr, bool IsMasked, RVVTypes &Signature,
364 bool HasPolicy, Policy PolicyAttrs) {
365 // Function name, e.g. vadd_vv_i32m1.
366 std::string Name = Record.Name;
367 if (!SuffixStr.empty())
368 Name += "_" + SuffixStr.str();
369
370 // Overloaded function name, e.g. vadd.
371 std::string OverloadedName;
372 if (!Record.OverloadedName)
373 OverloadedName = StringRef(Record.Name).split("_").first.str();
374 else
375 OverloadedName = Record.OverloadedName;
376 if (!OverloadedSuffixStr.empty())
377 OverloadedName += "_" + OverloadedSuffixStr.str();
378
379 // clang built-in function name, e.g. __builtin_rvv_vadd.
380 std::string BuiltinName = "__builtin_rvv_" + std::string(Record.Name);
381
382 RVVIntrinsic::updateNamesAndPolicy(IsMasked, HasPolicy, Name, BuiltinName,
383 OverloadedName, PolicyAttrs,
384 Record.HasFRMRoundModeOp);
385
386 // Put into IntrinsicList.
387 size_t Index = IntrinsicList.size();
388 IntrinsicList.push_back({Name, OverloadedName, BuiltinName, Signature});
389
390 // Creating mapping to Intrinsics.
391 Intrinsics.insert({Name, Index});
392
393 // Get the RVVOverloadIntrinsicDef.
394 RVVOverloadIntrinsicDef &OverloadIntrinsicDef =
395 OverloadIntrinsics[OverloadedName];
396
397 // And added the index.
398 OverloadIntrinsicDef.Indexes.push_back(Index);
399}
400
401void RISCVIntrinsicManagerImpl::CreateRVVIntrinsicDecl(LookupResult &LR,
402 IdentifierInfo *II,
403 Preprocessor &PP,
404 unsigned Index,
405 bool IsOverload) {
406 ASTContext &Context = S.Context;
407 RVVIntrinsicDef &IDef = IntrinsicList[Index];
408 RVVTypes Sigs = IDef.Signature;
409 size_t SigLength = Sigs.size();
410 RVVType *ReturnType = Sigs[0];
411 QualType RetType = RVVType2Qual(Context, ReturnType);
413 QualType BuiltinFuncType;
414
415 // Skip return type, and convert RVVType to QualType for arguments.
416 for (size_t i = 1; i < SigLength; ++i)
417 ArgTypes.push_back(RVVType2Qual(Context, Sigs[i]));
418
420 Context.getDefaultCallingConvention(false, false, true));
421
422 PI.Variadic = false;
423
424 SourceLocation Loc = LR.getNameLoc();
425 BuiltinFuncType = Context.getFunctionType(RetType, ArgTypes, PI);
427
428 FunctionDecl *RVVIntrinsicDecl = FunctionDecl::Create(
429 Context, Parent, Loc, Loc, II, BuiltinFuncType, /*TInfo=*/nullptr,
431 /*isInlineSpecified*/ false,
432 /*hasWrittenPrototype*/ true);
433
434 // Create Decl objects for each parameter, adding them to the
435 // FunctionDecl.
436 const auto *FP = cast<FunctionProtoType>(BuiltinFuncType);
438 for (unsigned IParm = 0, E = FP->getNumParams(); IParm != E; ++IParm) {
439 ParmVarDecl *Parm =
440 ParmVarDecl::Create(Context, RVVIntrinsicDecl, Loc, Loc, nullptr,
441 FP->getParamType(IParm), nullptr, SC_None, nullptr);
442 Parm->setScopeInfo(0, IParm);
443 ParmList.push_back(Parm);
444 }
445 RVVIntrinsicDecl->setParams(ParmList);
446
447 // Add function attributes.
448 if (IsOverload)
449 RVVIntrinsicDecl->addAttr(OverloadableAttr::CreateImplicit(Context));
450
451 // Setup alias to __builtin_rvv_*
452 IdentifierInfo &IntrinsicII = PP.getIdentifierTable().get(IDef.BuiltinName);
453 RVVIntrinsicDecl->addAttr(
454 BuiltinAliasAttr::CreateImplicit(S.Context, &IntrinsicII));
455
456 // Add to symbol table.
457 LR.addDecl(RVVIntrinsicDecl);
458}
459
460bool RISCVIntrinsicManagerImpl::CreateIntrinsicIfFound(LookupResult &LR,
461 IdentifierInfo *II,
462 Preprocessor &PP) {
463 StringRef Name = II->getName();
464
465 // Lookup the function name from the overload intrinsics first.
466 auto OvIItr = OverloadIntrinsics.find(Name);
467 if (OvIItr != OverloadIntrinsics.end()) {
468 const RVVOverloadIntrinsicDef &OvIntrinsicDef = OvIItr->second;
469 for (auto Index : OvIntrinsicDef.Indexes)
470 CreateRVVIntrinsicDecl(LR, II, PP, Index,
471 /*IsOverload*/ true);
472
473 // If we added overloads, need to resolve the lookup result.
474 LR.resolveKind();
475 return true;
476 }
477
478 // Lookup the function name from the intrinsics.
479 auto Itr = Intrinsics.find(Name);
480 if (Itr != Intrinsics.end()) {
481 CreateRVVIntrinsicDecl(LR, II, PP, Itr->second,
482 /*IsOverload*/ false);
483 return true;
484 }
485
486 // It's not an RVV intrinsics.
487 return false;
488}
489
490namespace clang {
491std::unique_ptr<clang::sema::RISCVIntrinsicManager>
493 return std::make_unique<RISCVIntrinsicManagerImpl>(S);
494}
495} // namespace clang
Defines the clang::ASTContext interface.
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
Defines enum values for all the target-independent builtin functions.
Defines the clang::Preprocessor interface.
static const RVVIntrinsicRecord RVSiFiveVectorIntrinsicRecords[]
static const RVVIntrinsicRecord RVVIntrinsicRecords[]
static const PrototypeDescriptor RVSiFiveVectorSignatureTable[]
static QualType RVVType2Qual(ASTContext &Context, const RVVType *Type)
static ArrayRef< PrototypeDescriptor > ProtoSeq2ArrayRef(IntrinsicKind K, uint16_t Index, uint8_t Length)
static const PrototypeDescriptor RVVSignatureTable[]
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1059
CanQualType LongTy
Definition: ASTContext.h:1086
QualType getScalableVectorType(QualType EltTy, unsigned NumElts, unsigned NumFields=1) const
Return the unique reference to a scalable vector type of the specified element type and scalable numb...
CanQualType FloatTy
Definition: ASTContext.h:1089
CanQualType DoubleTy
Definition: ASTContext.h:1089
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const
Retrieves the default calling convention for the current target.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getConstType(QualType T) const
Return the uniqued reference to the type for a const qualified type.
Definition: ASTContext.h:1278
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CanQualType BoolTy
Definition: ASTContext.h:1078
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
CanQualType UnsignedLongTy
Definition: ASTContext.h:1087
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CanQualType Float16Ty
Definition: ASTContext.h:1103
CanQualType VoidTy
Definition: ASTContext.h:1077
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1542
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:743
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1409
void addAttr(Attr *A)
Definition: DeclBase.cpp:904
bool isFPConstrained() const
Definition: LangOptions.h:750
Represents a function declaration or definition.
Definition: Decl.h:1919
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, Expr *TrailingRequiresClause=nullptr)
Definition: Decl.h:2095
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Represents the results of name lookup.
Definition: Lookup.h:46
void addDecl(NamedDecl *D)
Add a declaration to these results with its natural access.
Definition: Lookup.h:472
void resolveKind()
Resolves the result kind of the lookup, possibly hiding decls.
Definition: SemaLookup.cpp:483
SourceLocation getNameLoc() const
Gets the location of the identifier.
Definition: Lookup.h:659
Represents a parameter to a function.
Definition: Decl.h:1724
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition: Decl.h:1757
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition: Decl.cpp:2888
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:128
IdentifierTable & getIdentifierTable()
A (possibly-)qualified type.
Definition: Type.h:736
static llvm::SmallVector< Policy > getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy)
static llvm::SmallVector< PrototypeDescriptor > computeBuiltinTypes(llvm::ArrayRef< PrototypeDescriptor > Prototype, bool IsMasked, bool HasMaskedOffOperand, bool HasVL, unsigned NF, PolicyScheme DefaultScheme, Policy PolicyAttrs, bool IsTuple)
static void updateNamesAndPolicy(bool IsMasked, bool HasPolicy, std::string &Name, std::string &BuiltinName, std::string &OverloadedName, Policy &PolicyAttrs, bool HasFRMRoundModeOp)
static std::string getSuffixStr(RVVTypeCache &TypeCache, BasicType Type, int Log2LMUL, llvm::ArrayRef< PrototypeDescriptor > PrototypeDescriptors)
static llvm::SmallVector< Policy > getSupportedUnMaskedPolicies()
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:356
ASTContext & Context
Definition: Sema.h:407
bool DeclareRISCVSiFiveVectorBuiltins
Indicate RISC-V SiFive vector builtin functions enabled or not.
Definition: Sema.h:1659
FPOptions & getCurFPFeatures()
Definition: Sema.h:1687
bool DeclareRISCVVBuiltins
Indicate RISC-V vector builtin functions enabled or not.
Definition: Sema.h:1656
Encodes a location in the source.
Exposes information about the current target.
Definition: TargetInfo.h:207
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
Definition: TargetInfo.h:1396
The base class of the type hierarchy.
Definition: Type.h:1597
virtual bool CreateIntrinsicIfFound(LookupResult &LR, IdentifierInfo *II, Preprocessor &PP)=0
Defines the clang::TargetInfo interface.
RISCV builtins.
std::vector< RVVTypePtr > RVVTypes
std::unique_ptr< sema::RISCVIntrinsicManager > CreateRISCVIntrinsicManager(Sema &S)
@ SC_Extern
Definition: Specifiers.h:242
@ SC_None
Definition: Specifiers.h:241
YAML serialization mapping.
Definition: Dominators.h:30
Extra information about a function prototype.
Definition: Type.h:4194