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

Sean Silva via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 12 15:19:58 PST 2020


silvas updated this revision to Diff 304981.
silvas edited the summary of this revision.
silvas added a comment.

Add SVec<T> as "DefaultSmallVector"


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
@@ -999,4 +999,15 @@
   EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2}));
 }
 
+struct BigElementType {
+  char Arr[10000] = {0};
+};
+template <typename ValueT> struct TestSVecSizeof {
+  static_assert(sizeof(SVec<ValueT>) <= kSVecMaxSizeof, "");
+};
+using instantiateTestSVecSizeof =
+    ::testing::Types<TestSVecSizeof<int8_t>, TestSVecSizeof<int16_t>,
+                     TestSVecSizeof<int32_t>, TestSVecSizeof<int64_t>,
+                     TestSVecSizeof<void *>, TestSVecSizeof<BigElementType>>;
+
 } // end namespace
Index: llvm/include/llvm/ADT/SmallVector.h
===================================================================
--- llvm/include/llvm/ADT/SmallVector.h
+++ llvm/include/llvm/ADT/SmallVector.h
@@ -978,6 +978,43 @@
   return {std::begin(Range), std::end(Range)};
 }
 
+/// Parameter controlling the default number of inlined elements for SVec.
+///
+/// We guarantee that `sizeof(SVec<T>) <= kSVecMaxSizeof`.
+constexpr size_t kSVecMaxSizeof = 64;
+template <typename ElementTy> constexpr size_t calculateSVecInlineElements() {
+  // Discount the size of the header itself when calculating the maximum inline
+  // bytes.
+  size_t MaxInlineBytes = kSVecMaxSizeof - sizeof(SmallVectorImpl<ElementTy>);
+  return MaxInlineBytes / sizeof(ElementTy);
+}
+
+/// SVec is a convenience wrapper around SmallVector with a default number of
+/// inlined elements.
+///
+/// One major reason to use SVec over SmallVector is convenience -- there is no
+/// need to choose the number of inlined elements, or to write that number in
+/// the type. Also, SVec is a shorter name than SmallVector which helps as well.
+///
+/// SVec adjusts the number of inlined elements with a policy that bounds the
+/// total `sizeof(SVec)` to never exceed a fixed size (currently 64 bytes).
+/// This prevents a number of the most pathological cases of SmallVector usage.
+/// For example, `SVec<SVec<SVec<T>>>` works fine and doesn't result in an
+/// excessive `sizeof`.
+///
+/// For small types like `char`, the number of inlined elements will be larger.
+/// For types like large structs, the number of inlined elements will be
+/// smaller, including possibly having zero inlined elements in the extreme
+/// case!
+///
+/// Over time, we have found that most choices of the number of inlined elements
+/// for SmallVector are chosen semi-arbitrarily or cargo-culted. It is expected
+/// that by tuning SVec default sizes in aggregate by adjusting the policy here,
+/// we can realize codebase-wide gains that would not be measurable if done
+/// by tuning individual SmallVector sizes across the codebase.
+template <typename T>
+using SVec = SmallVector<T, calculateSVecInlineElements<T>()>;
+
 } // end namespace llvm
 
 namespace std {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D90884.304981.patch
Type: text/x-patch
Size: 2948 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201112/9d687f02/attachment.bin>


More information about the llvm-commits mailing list