diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index a2c55c71e09ae..12351e98e5a2b 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -25,10 +25,12 @@ #include "clang/AST/RawCommentList.h" #include "clang/AST/SYCLKernelInfo.h" #include "clang/AST/TemplateName.h" +#include "clang/AST/TypeOrdering.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -51,6 +53,36 @@ class FixedPointSemantics; struct fltSemantics; template class SmallPtrSet; +struct ScalableVecTyKey { + clang::QualType EltTy; + unsigned NumElts; + unsigned NumFields; + + bool operator==(const ScalableVecTyKey &RHS) const { + return EltTy == RHS.EltTy && NumElts == RHS.NumElts && + NumFields == RHS.NumFields; + } +}; + +// Provide a DenseMapInfo specialization so that ScalableVecTyKey can be used +// as a key in DenseMap. +template <> struct DenseMapInfo { + static inline ScalableVecTyKey getEmptyKey() { + return {DenseMapInfo::getEmptyKey(), ~0U, ~0U}; + } + static inline ScalableVecTyKey getTombstoneKey() { + return {DenseMapInfo::getTombstoneKey(), ~0U, ~0U}; + } + static unsigned getHashValue(const ScalableVecTyKey &Val) { + return hash_combine(DenseMapInfo::getHashValue(Val.EltTy), + Val.NumElts, Val.NumFields); + } + static bool isEqual(const ScalableVecTyKey &LHS, + const ScalableVecTyKey &RHS) { + return LHS == RHS; + } +}; + } // namespace llvm namespace clang { @@ -505,6 +537,9 @@ class ASTContext : public RefCountedBase { SmallVector> ObjCSubClasses; + // A mapping from Scalable Vector Type keys to their corresponding QualType. + mutable llvm::DenseMap ScalableVecTyMap; + ASTContext &this_() { return *this; } public: diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 97c59b2ceec2f..07d42e7e2f3b3 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4567,6 +4567,10 @@ QualType ASTContext::getWebAssemblyExternrefType() const { /// type. QualType ASTContext::getScalableVectorType(QualType EltTy, unsigned NumElts, unsigned NumFields) const { + auto K = llvm::ScalableVecTyKey{EltTy, NumElts, NumFields}; + if (auto It = ScalableVecTyMap.find(K); It != ScalableVecTyMap.end()) + return It->second; + if (Target->hasAArch64ACLETypes()) { uint64_t EltTySize = getTypeSize(EltTy); @@ -4575,29 +4579,29 @@ QualType ASTContext::getScalableVectorType(QualType EltTy, unsigned NumElts, if (EltTy->hasIntegerRepresentation() && !EltTy->isBooleanType() && \ EltTy->hasSignedIntegerRepresentation() == IsSigned && \ EltTySize == ElBits && NumElts == (NumEls * NF) && NumFields == 1) { \ - return SingletonId; \ + return ScalableVecTyMap[K] = SingletonId; \ } #define SVE_VECTOR_TYPE_FLOAT(Name, MangledName, Id, SingletonId, NumEls, \ ElBits, NF) \ if (EltTy->hasFloatingRepresentation() && !EltTy->isBFloat16Type() && \ EltTySize == ElBits && NumElts == (NumEls * NF) && NumFields == 1) { \ - return SingletonId; \ + return ScalableVecTyMap[K] = SingletonId; \ } #define SVE_VECTOR_TYPE_BFLOAT(Name, MangledName, Id, SingletonId, NumEls, \ ElBits, NF) \ if (EltTy->hasFloatingRepresentation() && EltTy->isBFloat16Type() && \ EltTySize == ElBits && NumElts == (NumEls * NF) && NumFields == 1) { \ - return SingletonId; \ + return ScalableVecTyMap[K] = SingletonId; \ } #define SVE_VECTOR_TYPE_MFLOAT(Name, MangledName, Id, SingletonId, NumEls, \ ElBits, NF) \ if (EltTy->isMFloat8Type() && EltTySize == ElBits && \ NumElts == (NumEls * NF) && NumFields == 1) { \ - return SingletonId; \ + return ScalableVecTyMap[K] = SingletonId; \ } #define SVE_PREDICATE_TYPE_ALL(Name, MangledName, Id, SingletonId, NumEls, NF) \ if (EltTy->isBooleanType() && NumElts == (NumEls * NF) && NumFields == 1) \ - return SingletonId; + return ScalableVecTyMap[K] = SingletonId; #include "clang/Basic/AArch64ACLETypes.def" } else if (Target->hasRISCVVTypes()) { uint64_t EltTySize = getTypeSize(EltTy); @@ -4611,10 +4615,10 @@ QualType ASTContext::getScalableVectorType(QualType EltTy, unsigned NumElts, (EltTy->hasFloatingRepresentation() && EltTy->isBFloat16Type() && \ IsBF && !IsFP)) && \ EltTySize == ElBits && NumElts == NumEls && NumFields == NF) \ - return SingletonId; + return ScalableVecTyMap[K] = SingletonId; #define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \ if (EltTy->isBooleanType() && NumElts == NumEls) \ - return SingletonId; + return ScalableVecTyMap[K] = SingletonId; #include "clang/Basic/RISCVVTypes.def" } return QualType();