[llvm] 333f501 - [SmallVector] Optimize move assignment operator for N==0 case

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 29 11:03:47 PST 2022


Author: Fangrui Song
Date: 2022-01-29T11:03:42-08:00
New Revision: 333f5019300c6e56782374627e64da0b62ffa3bc

URL: https://github.com/llvm/llvm-project/commit/333f5019300c6e56782374627e64da0b62ffa3bc
DIFF: https://github.com/llvm/llvm-project/commit/333f5019300c6e56782374627e64da0b62ffa3bc.diff

LOG: [SmallVector] Optimize move assignment operator for N==0 case

Due to the SmallVector hierarchy, N==0 cannot be leveraged by functions defined
in base classes. This patch special cases N==0 for SmallVector to save code size
and be slightly more efficient.

In a Release build of x86 only clang, .text is -3.34KiB smaller. In lld .text is
7.17KiB smaller.

Reviewed By: lichray

Differential Revision: https://reviews.llvm.org/D117976

Added: 
    

Modified: 
    llvm/include/llvm/ADT/SmallVector.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
index dd2ae0b240d86..a4a790323a6b8 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/include/llvm/ADT/SmallVector.h
@@ -568,6 +568,16 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> {
   explicit SmallVectorImpl(unsigned N)
       : SmallVectorTemplateBase<T>(N) {}
 
+  void assignRemote(SmallVectorImpl &&RHS) {
+    this->destroy_range(this->begin(), this->end());
+    if (!this->isSmall())
+      free(this->begin());
+    this->BeginX = RHS.BeginX;
+    this->Size = RHS.Size;
+    this->Capacity = RHS.Capacity;
+    RHS.resetToSmall();
+  }
+
 public:
   SmallVectorImpl(const SmallVectorImpl &) = delete;
 
@@ -1032,12 +1042,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
 
   // If the RHS isn't small, clear this vector and then steal its buffer.
   if (!RHS.isSmall()) {
-    this->destroy_range(this->begin(), this->end());
-    if (!this->isSmall()) free(this->begin());
-    this->BeginX = RHS.BeginX;
-    this->Size = RHS.Size;
-    this->Capacity = RHS.Capacity;
-    RHS.resetToSmall();
+    this->assignRemote(std::move(RHS));
     return *this;
   }
 
@@ -1228,7 +1233,20 @@ class LLVM_GSL_OWNER SmallVector : public SmallVectorImpl<T>,
   }
 
   SmallVector &operator=(SmallVector &&RHS) {
-    SmallVectorImpl<T>::operator=(::std::move(RHS));
+    if (N) {
+      SmallVectorImpl<T>::operator=(::std::move(RHS));
+      return *this;
+    }
+    // SmallVectorImpl<T>::operator= does not leverage N==0. Optimize the
+    // case.
+    if (this == &RHS)
+      return *this;
+    if (RHS.empty()) {
+      this->destroy_range(this->begin(), this->end());
+      this->Size = 0;
+    } else {
+      this->assignRemote(std::move(RHS));
+    }
     return *this;
   }
 


        


More information about the llvm-commits mailing list