22#include "llvm/ADT/SmallVector.h"
34struct RVVIntrinsicDef {
39 std::string OverloadName;
42 std::string BuiltinName;
48struct RVVOverloadIntrinsicDef {
56#define DECL_SIGNATURE_TABLE
57#include "clang/Basic/riscv_vector_builtin_sema.inc"
58#undef DECL_SIGNATURE_TABLE
62#define DECL_INTRINSIC_RECORDS
63#include "clang/Basic/riscv_vector_builtin_sema.inc"
64#undef DECL_INTRINSIC_RECORDS
75 switch (
Type->getScalarType()) {
76 case ScalarTypeKind::Void:
79 case ScalarTypeKind::Size_t:
82 case ScalarTypeKind::Ptrdiff_t:
85 case ScalarTypeKind::UnsignedLong:
88 case ScalarTypeKind::SignedLong:
91 case ScalarTypeKind::Boolean:
94 case ScalarTypeKind::SignedInteger:
97 case ScalarTypeKind::UnsignedInteger:
100 case ScalarTypeKind::Float:
101 switch (
Type->getElementBitwidth()) {
112 llvm_unreachable(
"Unsupported floating point width.");
116 llvm_unreachable(
"Unhandled type.");
118 if (
Type->isVector())
121 if (
Type->isConstant())
125 if (
Type->isPointer())
139 std::vector<RVVIntrinsicDef> IntrinsicList;
141 StringMap<size_t> Intrinsics;
143 StringMap<RVVOverloadIntrinsicDef> OverloadIntrinsics;
146 void InitIntrinsicList();
150 StringRef OverloadedSuffixStr,
bool IsMask,
159 RISCVIntrinsicManagerImpl(
clang::Sema &S) : S(S), Context(S.Context) {
170void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
185 Record.OverloadedSuffixIndex,
Record.OverloadedSuffixSize);
192 const Policy DefaultPolicy;
198 UnMaskedPolicyScheme, DefaultPolicy);
202 BasicProtoSeq,
true,
Record.HasMaskedOffOperand,
203 Record.HasVL,
Record.NF, MaskedPolicyScheme, DefaultPolicy);
205 bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone;
206 bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone;
213 for (
unsigned int TypeRangeMaskShift = 0;
214 TypeRangeMaskShift <= static_cast<unsigned int>(BasicType::MaxOffset);
215 ++TypeRangeMaskShift) {
216 unsigned int BaseTypeI = 1 << TypeRangeMaskShift;
217 BaseType =
static_cast<BasicType>(BaseTypeI);
219 if ((BaseTypeI &
Record.TypeRangeMask) != BaseTypeI)
227 if ((BaseType == BasicType::Int64) &&
234 for (
int Log2LMUL = -3; Log2LMUL <= 3; Log2LMUL++) {
235 if (!(
Record.Log2LMULMask & (1 << (Log2LMUL + 3))))
238 std::optional<RVVTypes> Types =
239 TypeCache.computeTypes(BaseType, Log2LMUL,
Record.NF, ProtoSeq);
242 if (!Types.has_value())
246 TypeCache, BaseType, Log2LMUL, SuffixProto);
248 TypeCache, BaseType, Log2LMUL, OverloadedSuffixProto);
251 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
false, *Types,
252 UnMaskedHasPolicy, DefaultPolicy);
255 if (
Record.UnMaskedPolicyScheme != PolicyScheme::SchemeNone) {
256 for (
auto P : SupportedUnMaskedPolicies) {
259 BasicProtoSeq,
false,
261 UnMaskedPolicyScheme,
P);
262 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
263 BaseType, Log2LMUL,
Record.NF, PolicyPrototype);
264 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
265 false, *PolicyTypes, UnMaskedHasPolicy,
272 std::optional<RVVTypes> MaskTypes =
273 TypeCache.computeTypes(BaseType, Log2LMUL,
Record.NF, ProtoMaskSeq);
274 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
true,
275 *MaskTypes, MaskedHasPolicy, DefaultPolicy);
276 if (
Record.MaskedPolicyScheme == PolicyScheme::SchemeNone)
279 for (
auto P : SupportedMaskedPolicies) {
282 BasicProtoSeq,
true,
Record.HasMaskedOffOperand,
284 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
285 BaseType, Log2LMUL,
Record.NF, PolicyPrototype);
286 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
287 true, *PolicyTypes, MaskedHasPolicy,
P);
295void RISCVIntrinsicManagerImpl::InitRVVIntrinsic(
297 StringRef OverloadedSuffixStr,
bool IsMasked,
RVVTypes &Signature,
298 bool HasPolicy,
Policy PolicyAttrs) {
300 std::string Name =
Record.Name;
301 if (!SuffixStr.empty())
302 Name +=
"_" + SuffixStr.str();
305 std::string OverloadedName;
306 if (!
Record.OverloadedName)
307 OverloadedName = StringRef(
Record.Name).split(
"_").first.str();
309 OverloadedName =
Record.OverloadedName;
310 if (!OverloadedSuffixStr.empty())
311 OverloadedName +=
"_" + OverloadedSuffixStr.str();
314 std::string BuiltinName =
"__builtin_rvv_" + std::string(
Record.Name);
317 OverloadedName, PolicyAttrs);
320 size_t Index = IntrinsicList.size();
321 IntrinsicList.push_back({Name, OverloadedName, BuiltinName, Signature});
324 Intrinsics.insert({Name, Index});
327 RVVOverloadIntrinsicDef &OverloadIntrinsicDef =
328 OverloadIntrinsics[OverloadedName];
331 OverloadIntrinsicDef.Indexes.push_back(Index);
334void RISCVIntrinsicManagerImpl::CreateRVVIntrinsicDecl(
LookupResult &LR,
340 RVVIntrinsicDef &IDef = IntrinsicList[Index];
342 size_t SigLength = Sigs.size();
349 for (
size_t i = 1; i < SigLength; ++i)
362 Context,
Parent, Loc, Loc, II, BuiltinFuncType,
nullptr,
369 const auto *FP = cast<FunctionProtoType>(BuiltinFuncType);
371 for (
unsigned IParm = 0, E = FP->getNumParams(); IParm != E; ++IParm) {
374 FP->getParamType(IParm),
nullptr,
SC_None,
nullptr);
376 ParmList.push_back(Parm);
378 RVVIntrinsicDecl->setParams(ParmList);
382 RVVIntrinsicDecl->
addAttr(OverloadableAttr::CreateImplicit(Context));
387 BuiltinAliasAttr::CreateImplicit(S.
Context, &IntrinsicII));
393bool RISCVIntrinsicManagerImpl::CreateIntrinsicIfFound(
LookupResult &LR,
396 StringRef Name = II->
getName();
399 auto OvIItr = OverloadIntrinsics.find(Name);
400 if (OvIItr != OverloadIntrinsics.end()) {
401 const RVVOverloadIntrinsicDef &OvIntrinsicDef = OvIItr->second;
402 for (
auto Index : OvIntrinsicDef.Indexes)
403 CreateRVVIntrinsicDecl(LR, II, PP, Index,
412 auto Itr = Intrinsics.find(Name);
413 if (Itr != Intrinsics.end()) {
414 CreateRVVIntrinsicDecl(LR, II, PP, Itr->second,
424std::unique_ptr<clang::sema::RISCVIntrinsicManager>
426 return std::make_unique<RISCVIntrinsicManagerImpl>(S);
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
Defines the clang::Preprocessor interface.
static ArrayRef< PrototypeDescriptor > ProtoSeq2ArrayRef(uint16_t Index, uint8_t Length)
static const RVVIntrinsicRecord RVVIntrinsicRecords[]
static QualType RVVType2Qual(ASTContext &Context, const RVVType *Type)
static const PrototypeDescriptor RVVSignatureTable[]
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
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.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
CanQualType UnsignedLongTy
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
const TargetInfo & getTargetInfo() const
QualType getScalableVectorType(QualType EltTy, unsigned NumElts) const
Return the unique reference to a scalable vector type of the specified element type and scalable numb...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
bool isFPConstrained() const
Represents a function declaration or definition.
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)
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.
void addDecl(NamedDecl *D)
Add a declaration to these results with its natural access.
void resolveKind()
Resolves the result kind of the lookup, possibly hiding decls.
SourceLocation getNameLoc() const
Gets the location of the identifier.
Represents a parameter to a function.
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
IdentifierTable & getIdentifierTable()
A (possibly-)qualified type.
static llvm::SmallVector< Policy > getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy)
static std::string getSuffixStr(RVVTypeCache &TypeCache, BasicType Type, int Log2LMUL, llvm::ArrayRef< PrototypeDescriptor > PrototypeDescriptors)
static void updateNamesAndPolicy(bool IsMasked, bool HasPolicy, std::string &Name, std::string &BuiltinName, std::string &OverloadedName, Policy &PolicyAttrs)
static llvm::SmallVector< PrototypeDescriptor > computeBuiltinTypes(llvm::ArrayRef< PrototypeDescriptor > Prototype, bool IsMasked, bool HasMaskedOffOperand, bool HasVL, unsigned NF, PolicyScheme DefaultScheme, Policy PolicyAttrs)
static llvm::SmallVector< Policy > getSupportedUnMaskedPolicies()
Sema - This implements semantic analysis and AST building for C.
FPOptions & getCurFPFeatures()
Encodes a location in the source.
Exposes information about the current target.
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
The base class of the type hierarchy.
virtual bool CreateIntrinsicIfFound(LookupResult &LR, IdentifierInfo *II, Preprocessor &PP)=0
Defines the clang::TargetInfo interface.
std::vector< RVVTypePtr > RVVTypes
std::unique_ptr< sema::RISCVIntrinsicManager > CreateRISCVIntrinsicManager(Sema &S)
YAML serialization mapping.
Extra information about a function prototype.