blob: 8d28e0fadeaa5d4ccf3ae76f705f03c31d85b7b5 [file] [log] [blame]
James Kuszmaulb13e13f2023-11-22 20:44:04 -08001From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
James Kuszmaulcf324122023-01-14 14:07:17 -08002From: PJ Reiniger <pj.reiniger@gmail.com>
3Date: Thu, 5 May 2022 23:18:34 -0400
James Kuszmaulb13e13f2023-11-22 20:44:04 -08004Subject: [PATCH 10/31] Detemplatize SmallVectorBase
James Kuszmaulcf324122023-01-14 14:07:17 -08005
6---
James Kuszmaulb13e13f2023-11-22 20:44:04 -08007 llvm/include/llvm/ADT/SmallVector.h | 27 +++++++--------------
8 llvm/lib/Support/SmallVector.cpp | 37 +++++------------------------
9 2 files changed, 14 insertions(+), 50 deletions(-)
James Kuszmaulcf324122023-01-14 14:07:17 -080010
11diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
James Kuszmaulb13e13f2023-11-22 20:44:04 -080012index b42438a9b16c273f9ef5b5cce6192873c78cb964..7775ed7e8e083908f033529c30b1e4beae91b10a 100644
James Kuszmaulcf324122023-01-14 14:07:17 -080013--- a/llvm/include/llvm/ADT/SmallVector.h
14+++ b/llvm/include/llvm/ADT/SmallVector.h
James Kuszmaulb13e13f2023-11-22 20:44:04 -080015@@ -56,14 +56,14 @@ using EnableIfConvertibleToInputIterator = std::enable_if_t<std::is_convertible<
James Kuszmaulcf324122023-01-14 14:07:17 -080016 /// Using 64 bit size is desirable for cases like SmallVector<char>, where a
17 /// 32 bit size would limit the vector to ~4GB. SmallVectors are used for
18 /// buffering bitcode output - which can exceed 4GB.
19-template <class Size_T> class SmallVectorBase {
20+class SmallVectorBase {
21 protected:
22 void *BeginX;
23- Size_T Size = 0, Capacity;
24+ unsigned Size = 0, Capacity;
25
26 /// The maximum value of the Size_T used.
27 static constexpr size_t SizeTypeMax() {
28- return (std::numeric_limits<Size_T>::max)();
29+ return (std::numeric_limits<unsigned>::max)();
30 }
31
32 SmallVectorBase() = delete;
James Kuszmaulb13e13f2023-11-22 20:44:04 -080033@@ -111,15 +111,10 @@ protected:
James Kuszmaulcf324122023-01-14 14:07:17 -080034 }
35 };
36
37-template <class T>
38-using SmallVectorSizeType =
James Kuszmaulb13e13f2023-11-22 20:44:04 -080039- std::conditional_t<sizeof(T) < 4 && sizeof(void *) >= 8, uint64_t,
40- uint32_t>;
James Kuszmaulcf324122023-01-14 14:07:17 -080041-
42 /// Figure out the offset of the first element.
43 template <class T, typename = void> struct SmallVectorAlignmentAndSize {
44- alignas(SmallVectorBase<SmallVectorSizeType<T>>) char Base[sizeof(
45- SmallVectorBase<SmallVectorSizeType<T>>)];
46+ alignas(SmallVectorBase) char Base[sizeof(
47+ SmallVectorBase)];
48 alignas(T) char FirstEl[sizeof(T)];
49 };
50
James Kuszmaulb13e13f2023-11-22 20:44:04 -080051@@ -128,8 +123,8 @@ template <class T, typename = void> struct SmallVectorAlignmentAndSize {
James Kuszmaulcf324122023-01-14 14:07:17 -080052 /// to avoid unnecessarily requiring T to be complete.
53 template <typename T, typename = void>
54 class SmallVectorTemplateCommon
55- : public SmallVectorBase<SmallVectorSizeType<T>> {
56- using Base = SmallVectorBase<SmallVectorSizeType<T>>;
57+ : public SmallVectorBase {
58+ using Base = SmallVectorBase;
59
James Kuszmaulb13e13f2023-11-22 20:44:04 -080060 protected:
James Kuszmaulcf324122023-01-14 14:07:17 -080061 /// Find the address of the first element. For this pointer math to be valid
James Kuszmaulb13e13f2023-11-22 20:44:04 -080062@@ -451,7 +446,7 @@ template <typename T, bool TriviallyCopyable>
63 T *SmallVectorTemplateBase<T, TriviallyCopyable>::mallocForGrow(
64 size_t MinSize, size_t &NewCapacity) {
65 return static_cast<T *>(
66- SmallVectorBase<SmallVectorSizeType<T>>::mallocForGrow(
67+ SmallVectorBase::mallocForGrow(
68 this->getFirstEl(), MinSize, sizeof(T), NewCapacity));
69 }
James Kuszmaulcf324122023-01-14 14:07:17 -080070
James Kuszmaulb13e13f2023-11-22 20:44:04 -080071@@ -1324,12 +1319,6 @@ template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
72 return {std::begin(Range), std::end(Range)};
73 }
74
75-// Explicit instantiations
76-extern template class llvm::SmallVectorBase<uint32_t>;
77-#if SIZE_MAX > UINT32_MAX
78-extern template class llvm::SmallVectorBase<uint64_t>;
79-#endif
80-
81 } // end namespace llvm
82
83 namespace std {
James Kuszmaulcf324122023-01-14 14:07:17 -080084diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp
James Kuszmaulb13e13f2023-11-22 20:44:04 -080085index 6cefdff7c28060ca18b522acf5279af3a206e23a..ae64a36dcf4b9ceaf8767adbf8100f164f3738ac 100644
James Kuszmaulcf324122023-01-14 14:07:17 -080086--- a/llvm/lib/Support/SmallVector.cpp
87+++ b/llvm/lib/Support/SmallVector.cpp
88@@ -51,10 +51,6 @@ static_assert(sizeof(SmallVector<void *, 1>) ==
89 sizeof(unsigned) * 2 + sizeof(void *) * 2,
90 "wasted space in SmallVector size 1");
91
92-static_assert(sizeof(SmallVector<char, 0>) ==
93- sizeof(void *) * 2 + sizeof(void *),
94- "1 byte elements have word-sized type for size and capacity");
95-
96 /// Report that MinSize doesn't fit into this vector's size type. Throws
97 /// std::length_error or calls report_fatal_error.
98 [[noreturn]] static void report_size_overflow(size_t MinSize, size_t MaxSize);
99@@ -85,9 +81,8 @@ static void report_at_maximum_capacity(size_t MaxSize) {
100 }
101
102 // Note: Moving this function into the header may cause performance regression.
103-template <class Size_T>
104 static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) {
105- constexpr size_t MaxSize = std::numeric_limits<Size_T>::max();
106+ constexpr size_t MaxSize = std::numeric_limits<unsigned>::max();
107
108 // Ensure we can fit the new capacity.
109 // This is only going to be applicable when the capacity is 32 bit.
James Kuszmaulb13e13f2023-11-22 20:44:04 -0800110@@ -107,8 +102,7 @@ static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) {
111 return std::clamp(NewCapacity, MinSize, MaxSize);
112 }
113
114-template <class Size_T>
115-void *SmallVectorBase<Size_T>::replaceAllocation(void *NewElts, size_t TSize,
116+void *SmallVectorBase::replaceAllocation(void *NewElts, size_t TSize,
117 size_t NewCapacity,
118 size_t VSize) {
119 void *NewEltsReplace = llvm::safe_malloc(NewCapacity * TSize);
120@@ -119,11 +113,10 @@ void *SmallVectorBase<Size_T>::replaceAllocation(void *NewElts, size_t TSize,
James Kuszmaulcf324122023-01-14 14:07:17 -0800121 }
122
123 // Note: Moving this function into the header may cause performance regression.
124-template <class Size_T>
James Kuszmaulb13e13f2023-11-22 20:44:04 -0800125-void *SmallVectorBase<Size_T>::mallocForGrow(void *FirstEl, size_t MinSize,
126+void *SmallVectorBase::mallocForGrow(void *FirstEl, size_t MinSize,
127 size_t TSize,
James Kuszmaulcf324122023-01-14 14:07:17 -0800128 size_t &NewCapacity) {
129- NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
130+ NewCapacity = getNewCapacity(MinSize, TSize, this->capacity());
James Kuszmaulb13e13f2023-11-22 20:44:04 -0800131 // Even if capacity is not 0 now, if the vector was originally created with
132 // capacity 0, it's possible for the malloc to return FirstEl.
133 void *NewElts = llvm::safe_malloc(NewCapacity * TSize);
134@@ -133,10 +126,9 @@ void *SmallVectorBase<Size_T>::mallocForGrow(void *FirstEl, size_t MinSize,
James Kuszmaulcf324122023-01-14 14:07:17 -0800135 }
136
137 // Note: Moving this function into the header may cause performance regression.
138-template <class Size_T>
139-void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
140+void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSize,
141 size_t TSize) {
142- size_t NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
143+ size_t NewCapacity = getNewCapacity(MinSize, TSize, this->capacity());
144 void *NewElts;
145 if (BeginX == FirstEl) {
James Kuszmaulb13e13f2023-11-22 20:44:04 -0800146 NewElts = llvm::safe_malloc(NewCapacity * TSize);
147@@ -155,20 +147,3 @@ void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
James Kuszmaulcf324122023-01-14 14:07:17 -0800148 this->BeginX = NewElts;
149 this->Capacity = NewCapacity;
150 }
151-
152-template class llvm::SmallVectorBase<uint32_t>;
153-
154-// Disable the uint64_t instantiation for 32-bit builds.
155-// Both uint32_t and uint64_t instantiations are needed for 64-bit builds.
156-// This instantiation will never be used in 32-bit builds, and will cause
157-// warnings when sizeof(Size_T) > sizeof(size_t).
158-#if SIZE_MAX > UINT32_MAX
159-template class llvm::SmallVectorBase<uint64_t>;
160-
161-// Assertions to ensure this #if stays in sync with SmallVectorSizeType.
162-static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint64_t),
163- "Expected SmallVectorBase<uint64_t> variant to be in use.");
164-#else
165-static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint32_t),
166- "Expected SmallVectorBase<uint32_t> variant to be in use.");
167-#endif