https://github.com/sunshaoce updated 
https://github.com/llvm/llvm-project/pull/160108

>From beb8b36b348437a8722a3f86cb9261351b568ca2 Mon Sep 17 00:00:00 2001
From: Shaoce SUN <sunsha...@outlook.com>
Date: Mon, 22 Sep 2025 21:36:23 +0800
Subject: [PATCH 1/2] [Clang][RVV][SVE]Cache getScalableVectorType lookups

Currently, RVV/SVE intrinsics are cached, but the corresponding type 
construction is not. As a result, `ASTContext::getScalableVectorType`
can become a performance hotspot, since every query must run through a long
sequence of type checks and macro expansions.
---
 clang/include/clang/AST/ASTContext.h | 33 ++++++++++++++++++++++++++++
 clang/lib/AST/ASTContext.cpp         | 19 ++++++++++------
 2 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a2c55c71e09ae..402d3324e2918 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -29,6 +29,7 @@
 #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 +52,35 @@ class FixedPointSemantics;
 struct fltSemantics;
 template <typename T, unsigned N> class SmallPtrSet;
 
+struct ScalableVecTyKey {
+  uintptr_t 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<ScalableVecTyKey> {
+  static inline ScalableVecTyKey getEmptyKey() {
+    return {DenseMapInfo<uintptr_t>::getEmptyKey(), ~0U, ~0U};
+  }
+  static inline ScalableVecTyKey getTombstoneKey() {
+    return {DenseMapInfo<uintptr_t>::getTombstoneKey(), ~0U, ~0U};
+  }
+  static unsigned getHashValue(const ScalableVecTyKey &Val) {
+    return hash_combine(Val.EltTy, Val.NumElts, Val.NumFields);
+  }
+  static bool isEqual(const ScalableVecTyKey &LHS,
+                      const ScalableVecTyKey &RHS) {
+    return LHS == RHS;
+  }
+};
+
 } // namespace llvm
 
 namespace clang {
@@ -505,6 +535,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
                  SmallVector<const ObjCInterfaceDecl *, 4>>
       ObjCSubClasses;
 
+  // A mapping from Scalable Vector Type keys to their corresponding QualType.
+  mutable llvm::DenseMap<llvm::ScalableVecTyKey, QualType> ScalableVecTyMap;
+
   ASTContext &this_() { return *this; }
 
 public:
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 97c59b2ceec2f..e979b268b246e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -4567,6 +4567,11 @@ QualType ASTContext::getWebAssemblyExternrefType() const 
{
 /// type.
 QualType ASTContext::getScalableVectorType(QualType EltTy, unsigned NumElts,
                                            unsigned NumFields) const {
+  auto K = llvm::ScalableVecTyKey{
+      reinterpret_cast<uintptr_t>(EltTy.getAsOpaquePtr()), NumElts, NumFields};
+  if (auto It = ScalableVecTyMap.find(K); It != ScalableVecTyMap.end())
+    return It->second;
+
   if (Target->hasAArch64ACLETypes()) {
     uint64_t EltTySize = getTypeSize(EltTy);
 
@@ -4575,29 +4580,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 +4616,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();

>From da90102363396d949d34f096694e9dfed28c4562 Mon Sep 17 00:00:00 2001
From: Shaoce SUN <sunsha...@outlook.com>
Date: Fri, 26 Sep 2025 00:01:32 +0800
Subject: [PATCH 2/2] Use QualType in ScalableVecTyKey

---
 clang/include/clang/AST/ASTContext.h | 10 ++++++----
 clang/lib/AST/ASTContext.cpp         |  3 +--
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 402d3324e2918..12351e98e5a2b 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -25,6 +25,7 @@
 #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"
@@ -53,7 +54,7 @@ struct fltSemantics;
 template <typename T, unsigned N> class SmallPtrSet;
 
 struct ScalableVecTyKey {
-  uintptr_t EltTy;
+  clang::QualType EltTy;
   unsigned NumElts;
   unsigned NumFields;
 
@@ -67,13 +68,14 @@ struct ScalableVecTyKey {
 // as a key in DenseMap.
 template <> struct DenseMapInfo<ScalableVecTyKey> {
   static inline ScalableVecTyKey getEmptyKey() {
-    return {DenseMapInfo<uintptr_t>::getEmptyKey(), ~0U, ~0U};
+    return {DenseMapInfo<clang::QualType>::getEmptyKey(), ~0U, ~0U};
   }
   static inline ScalableVecTyKey getTombstoneKey() {
-    return {DenseMapInfo<uintptr_t>::getTombstoneKey(), ~0U, ~0U};
+    return {DenseMapInfo<clang::QualType>::getTombstoneKey(), ~0U, ~0U};
   }
   static unsigned getHashValue(const ScalableVecTyKey &Val) {
-    return hash_combine(Val.EltTy, Val.NumElts, Val.NumFields);
+    return hash_combine(DenseMapInfo<clang::QualType>::getHashValue(Val.EltTy),
+                        Val.NumElts, Val.NumFields);
   }
   static bool isEqual(const ScalableVecTyKey &LHS,
                       const ScalableVecTyKey &RHS) {
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index e979b268b246e..07d42e7e2f3b3 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -4567,8 +4567,7 @@ QualType ASTContext::getWebAssemblyExternrefType() const {
 /// type.
 QualType ASTContext::getScalableVectorType(QualType EltTy, unsigned NumElts,
                                            unsigned NumFields) const {
-  auto K = llvm::ScalableVecTyKey{
-      reinterpret_cast<uintptr_t>(EltTy.getAsOpaquePtr()), NumElts, NumFields};
+  auto K = llvm::ScalableVecTyKey{EltTy, NumElts, NumFields};
   if (auto It = ScalableVecTyMap.find(K); It != ScalableVecTyMap.end())
     return It->second;
 

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to