[PATCH] D90884: [SmallVector] Add a default small size.

Sean Silva via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 5 14:47:57 PST 2020


silvas updated this revision to Diff 303269.
silvas added a comment.

Address typo


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90884/new/

https://reviews.llvm.org/D90884

Files:
  llvm/include/llvm/ADT/SmallVector.h
  llvm/unittests/ADT/SmallVectorTest.cpp


Index: llvm/unittests/ADT/SmallVectorTest.cpp
===================================================================
--- llvm/unittests/ADT/SmallVectorTest.cpp
+++ llvm/unittests/ADT/SmallVectorTest.cpp
@@ -1029,4 +1029,29 @@
   EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2}));
 }
 
+struct BigElementType {
+  char Arr[10000] = {0};
+};
+typedef ::testing::Types<SmallVector<int8_t>, SmallVector<int16_t>,
+                         SmallVector<int32_t>, SmallVector<int64_t>,
+                         SmallVector<void *>, SmallVector<BigElementType>>
+    SmallVectorDefaultSmallSizeTestTypes;
+// Test fixture class
+template <typename VectorT>
+class SmallVectorDefaultSmallSizeTest : public testing::Test {
+protected:
+  VectorT theVector;
+};
+
+TYPED_TEST_CASE(SmallVectorDefaultSmallSizeTest,
+                SmallVectorDefaultSmallSizeTestTypes);
+
+TYPED_TEST(SmallVectorDefaultSmallSizeTest, DefaultSmallSize) {
+  using ValueT = typename decltype(this->theVector)::value_type;
+  static_assert(sizeof(this->theVector) <=
+                    kDefaultSmallSizeHeaderSizeMultiplier *
+                        sizeof(SmallVectorImpl<ValueT>),
+                "");
+}
+
 } // end namespace
Index: llvm/include/llvm/ADT/SmallVector.h
===================================================================
--- llvm/include/llvm/ADT/SmallVector.h
+++ llvm/include/llvm/ADT/SmallVector.h
@@ -892,6 +892,21 @@
 /// well-defined.
 template <typename T> struct alignas(T) SmallVectorStorage<T, 0> {};
 
+// Parameter controlling the default small size for SmallVector.
+//
+// We guarantee that a default-small-sized SmallVector has sizeof no more than
+// kDefaultSmallSizeHeaderSizeMultiplier times bigger than just the header.
+//
+// This prevents unexpected variation based on `sizeof(value_type)`.
+constexpr size_t kDefaultSmallSizeHeaderSizeMultiplier = 3;
+template <typename ElementTy> constexpr size_t calculateDefaultSmallSize() {
+  // Discount the size of the header itself when calculating the maximum inline
+  // bytes, so subtract one from the multiplier.
+  size_t MaxInlineBytes = (kDefaultSmallSizeHeaderSizeMultiplier - 1) *
+                          sizeof(SmallVectorImpl<ElementTy>);
+  return MaxInlineBytes / sizeof(ElementTy);
+}
+
 /// This is a 'vector' (really, a variable-sized array), optimized
 /// for the case when the array is small.  It contains some number of elements
 /// in-place, which allows it to avoid heap allocation when the actual number of
@@ -900,7 +915,7 @@
 ///
 /// Note that this does not attempt to be exception safe.
 ///
-template <typename T, unsigned N>
+template <typename T, unsigned N = calculateDefaultSmallSize<T>()>
 class LLVM_GSL_OWNER SmallVector : public SmallVectorImpl<T>,
                                    SmallVectorStorage<T, N> {
 public:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D90884.303269.patch
Type: text/x-patch
Size: 2819 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201105/fbb2c623/attachment.bin>


More information about the llvm-commits mailing list