[PATCH] D87606: [ADT] Remove unnecessary copies in SmallVectorImpl::swap

Nathan James via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 14 05:39:50 PDT 2020


njames93 created this revision.
njames93 added reviewers: dblaikie, chandlerc.
Herald added subscribers: llvm-commits, dexonsmith.
Herald added a project: LLVM.
njames93 requested review of this revision.

If one of the containers needs to grow to accomodate the amount of items in the other container, but the other container is in big mode, We can just swap the buffers over.
This saves copying the items between 2 known heap allocated buffers.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D87606

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


Index: llvm/include/llvm/ADT/SmallVector.h
===================================================================
--- llvm/include/llvm/ADT/SmallVector.h
+++ llvm/include/llvm/ADT/SmallVector.h
@@ -721,21 +721,35 @@
 void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
   if (this == &RHS) return;
 
-  // We can only avoid copying elements if neither vector is small.
-  if (!this->isSmall() && !RHS.isSmall()) {
+  auto SwapBuffers = [&] {
     std::swap(this->BeginX, RHS.BeginX);
     std::swap(this->Size, RHS.Size);
     std::swap(this->Capacity, RHS.Capacity);
+  };
+
+  // We can only avoid copying elements if neither vector is small.
+  if (!this->isSmall() && !RHS.isSmall()) {
+    SwapBuffers();
     return;
   }
-  if (RHS.size() > this->capacity())
+  if (RHS.size() > this->capacity()) {
     this->grow(RHS.size());
-  if (this->size() > RHS.capacity())
+    if (!RHS.isSmall()) {
+      // Neither are small now, so swap the buffers.
+      SwapBuffers();
+      return;
+    }
+  } else if (this->size() > RHS.capacity()) {
     RHS.grow(this->size());
+    if (!this->isSmall()) {
+      // Neither are small now, so swap the buffers.
+      SwapBuffers();
+      return;
+    }
+  }
 
   // Swap the shared elements.
-  size_t NumShared = this->size();
-  if (NumShared > RHS.size()) NumShared = RHS.size();
+  size_t NumShared = std::min(this->size(), RHS.size());
   for (size_type i = 0; i != NumShared; ++i)
     std::swap((*this)[i], RHS[i]);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87606.291549.patch
Type: text/x-patch
Size: 1475 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200914/a065618c/attachment.bin>


More information about the llvm-commits mailing list