[clang] [RISCV][clang] Optimize memory usage of intrinsic lookup table (PR #77487)

Brandon Wu via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 25 04:44:49 PST 2024


https://github.com/4vtomat updated https://github.com/llvm/llvm-project/pull/77487

>From 84ea759c43d8e9cb450d95d00fd802be622153a2 Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Sun, 7 Jan 2024 18:10:59 -0800
Subject: [PATCH 1/2] [RISCV][clang] Optimize memory usage of intrinsic lookup
 table

This patch optimize:
  1. Reduce string size of RVVIntrinsicDef.
  2. Reduce the type size of the index of intrinsics.

I use valgrind --tool=massif to analyze a simple program:
```
#include <riscv_vector.h>
vint32m1_t test(vint32m1_t v1, vint32m1_t v2, size_t vl) {
  return __riscv_vadd(v1, v2, vl);
}
```
and before optimization, the peak memory usage is 15.68MB,
after optimization, the peak memory usage is 13.69MB.
---
 clang/include/clang/Support/RISCVVIntrinsicUtils.h |  6 ++++--
 clang/lib/Sema/SemaRISCVVectorLookup.cpp           | 13 +++++++------
 clang/lib/Support/RISCVVIntrinsicUtils.cpp         |  5 -----
 3 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Support/RISCVVIntrinsicUtils.h b/clang/include/clang/Support/RISCVVIntrinsicUtils.h
index c525d3443331e0b..7e20f022c28b551 100644
--- a/clang/include/clang/Support/RISCVVIntrinsicUtils.h
+++ b/clang/include/clang/Support/RISCVVIntrinsicUtils.h
@@ -416,8 +416,10 @@ class RVVIntrinsic {
   RVVTypePtr getOutputType() const { return OutputType; }
   const RVVTypes &getInputTypes() const { return InputTypes; }
   llvm::StringRef getBuiltinName() const { return BuiltinName; }
-  llvm::StringRef getName() const { return Name; }
-  llvm::StringRef getOverloadedName() const { return OverloadedName; }
+  llvm::StringRef getName() const { return "__riscv_" + Name; }
+  llvm::StringRef getOverloadedName() const {
+    return "__riscv_" + OverloadedName;
+  }
   bool hasMaskedOffOperand() const { return HasMaskedOffOperand; }
   bool hasVL() const { return HasVL; }
   bool hasPolicy() const { return Scheme != PolicyScheme::SchemeNone; }
diff --git a/clang/lib/Sema/SemaRISCVVectorLookup.cpp b/clang/lib/Sema/SemaRISCVVectorLookup.cpp
index 3ed3e6195441893..e9523871e9cd1fb 100644
--- a/clang/lib/Sema/SemaRISCVVectorLookup.cpp
+++ b/clang/lib/Sema/SemaRISCVVectorLookup.cpp
@@ -43,7 +43,7 @@ struct RVVIntrinsicDef {
 
 struct RVVOverloadIntrinsicDef {
   // Indexes of RISCVIntrinsicManagerImpl::IntrinsicList.
-  SmallVector<uint32_t, 8> Indexes;
+  SmallVector<uint16_t, 8> Indexes;
 };
 
 } // namespace
@@ -162,7 +162,7 @@ class RISCVIntrinsicManagerImpl : public sema::RISCVIntrinsicManager {
   // List of all RVV intrinsic.
   std::vector<RVVIntrinsicDef> IntrinsicList;
   // Mapping function name to index of IntrinsicList.
-  StringMap<uint32_t> Intrinsics;
+  StringMap<uint16_t> Intrinsics;
   // Mapping function name to RVVOverloadIntrinsicDef.
   StringMap<RVVOverloadIntrinsicDef> OverloadIntrinsics;
 
@@ -380,14 +380,14 @@ void RISCVIntrinsicManagerImpl::InitRVVIntrinsic(
     OverloadedName += "_" + OverloadedSuffixStr.str();
 
   // clang built-in function name, e.g. __builtin_rvv_vadd.
-  std::string BuiltinName = "__builtin_rvv_" + std::string(Record.Name);
+  std::string BuiltinName = std::string(Record.Name);
 
   RVVIntrinsic::updateNamesAndPolicy(IsMasked, HasPolicy, Name, BuiltinName,
                                      OverloadedName, PolicyAttrs,
                                      Record.HasFRMRoundModeOp);
 
   // Put into IntrinsicList.
-  uint32_t Index = IntrinsicList.size();
+  uint16_t Index = IntrinsicList.size();
   IntrinsicList.push_back({BuiltinName, Signature});
 
   // Creating mapping to Intrinsics.
@@ -452,7 +452,8 @@ void RISCVIntrinsicManagerImpl::CreateRVVIntrinsicDecl(LookupResult &LR,
     RVVIntrinsicDecl->addAttr(OverloadableAttr::CreateImplicit(Context));
 
   // Setup alias to __builtin_rvv_*
-  IdentifierInfo &IntrinsicII = PP.getIdentifierTable().get(IDef.BuiltinName);
+  IdentifierInfo &IntrinsicII =
+      PP.getIdentifierTable().get("__builtin_rvv_" + IDef.BuiltinName);
   RVVIntrinsicDecl->addAttr(
       BuiltinAliasAttr::CreateImplicit(S.Context, &IntrinsicII));
 
@@ -463,7 +464,7 @@ void RISCVIntrinsicManagerImpl::CreateRVVIntrinsicDecl(LookupResult &LR,
 bool RISCVIntrinsicManagerImpl::CreateIntrinsicIfFound(LookupResult &LR,
                                                        IdentifierInfo *II,
                                                        Preprocessor &PP) {
-  StringRef Name = II->getName();
+  StringRef Name = II->getName().substr(8);
 
   // Lookup the function name from the overload intrinsics first.
   auto OvIItr = OverloadIntrinsics.find(Name);
diff --git a/clang/lib/Support/RISCVVIntrinsicUtils.cpp b/clang/lib/Support/RISCVVIntrinsicUtils.cpp
index 2de977a3dc720bd..7d2a2d7e826f9cd 100644
--- a/clang/lib/Support/RISCVVIntrinsicUtils.cpp
+++ b/clang/lib/Support/RISCVVIntrinsicUtils.cpp
@@ -1150,11 +1150,6 @@ void RVVIntrinsic::updateNamesAndPolicy(
     OverloadedName += suffix;
   };
 
-  // This follows the naming guideline under riscv-c-api-doc to add the
-  // `__riscv_` suffix for all RVV intrinsics.
-  Name = "__riscv_" + Name;
-  OverloadedName = "__riscv_" + OverloadedName;
-
   if (HasFRMRoundModeOp) {
     Name += "_rm";
     BuiltinName += "_rm";

>From 59041ff8932b55d09182307f7d2dfff90b2a05bb Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Sun, 14 Jan 2024 23:43:31 -0800
Subject: [PATCH 2/2] fixup! [RISCV][clang] Optimize memory usage of intrinsic
 lookup table

---
 clang/include/clang/Support/RISCVVIntrinsicUtils.h | 4 ----
 clang/lib/Sema/SemaRISCVVectorLookup.cpp           | 5 ++++-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Support/RISCVVIntrinsicUtils.h b/clang/include/clang/Support/RISCVVIntrinsicUtils.h
index 7e20f022c28b551..b10269abfdbc93b 100644
--- a/clang/include/clang/Support/RISCVVIntrinsicUtils.h
+++ b/clang/include/clang/Support/RISCVVIntrinsicUtils.h
@@ -416,10 +416,6 @@ class RVVIntrinsic {
   RVVTypePtr getOutputType() const { return OutputType; }
   const RVVTypes &getInputTypes() const { return InputTypes; }
   llvm::StringRef getBuiltinName() const { return BuiltinName; }
-  llvm::StringRef getName() const { return "__riscv_" + Name; }
-  llvm::StringRef getOverloadedName() const {
-    return "__riscv_" + OverloadedName;
-  }
   bool hasMaskedOffOperand() const { return HasMaskedOffOperand; }
   bool hasVL() const { return HasVL; }
   bool hasPolicy() const { return Scheme != PolicyScheme::SchemeNone; }
diff --git a/clang/lib/Sema/SemaRISCVVectorLookup.cpp b/clang/lib/Sema/SemaRISCVVectorLookup.cpp
index e9523871e9cd1fb..b70665b47ce19df 100644
--- a/clang/lib/Sema/SemaRISCVVectorLookup.cpp
+++ b/clang/lib/Sema/SemaRISCVVectorLookup.cpp
@@ -388,6 +388,8 @@ void RISCVIntrinsicManagerImpl::InitRVVIntrinsic(
 
   // Put into IntrinsicList.
   uint16_t Index = IntrinsicList.size();
+  assert(IntrinsicList.size() == (size_t)Index &&
+         "Intrinsics indices overflow.");
   IntrinsicList.push_back({BuiltinName, Signature});
 
   // Creating mapping to Intrinsics.
@@ -464,7 +466,8 @@ void RISCVIntrinsicManagerImpl::CreateRVVIntrinsicDecl(LookupResult &LR,
 bool RISCVIntrinsicManagerImpl::CreateIntrinsicIfFound(LookupResult &LR,
                                                        IdentifierInfo *II,
                                                        Preprocessor &PP) {
-  StringRef Name = II->getName().substr(8);
+  StringRef Name = II->getName();
+  Name.consume_front("__riscv_");
 
   // Lookup the function name from the overload intrinsics first.
   auto OvIItr = OverloadIntrinsics.find(Name);



More information about the cfe-commits mailing list