From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Thu, 5 May 2022 23:18:34 -0400 Subject: [PATCH 10/35] Detemplatize SmallVectorBase --- llvm/include/llvm/ADT/SmallVector.h | 35 ++++++++++------------------- llvm/lib/Support/SmallVector.cpp | 34 +++++----------------------- 2 files changed, 17 insertions(+), 52 deletions(-) diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h index 3cab284f5b6105956d6fff49a27d37482a3c321d..b8981ab67322f7888ad63d953ba72dbfa53b2939 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -56,19 +56,19 @@ using EnableIfConvertibleToInputIterator = std::enable_if_t, where a /// 32 bit size would limit the vector to ~4GB. SmallVectors are used for /// buffering bitcode output - which can exceed 4GB. -template class SmallVectorBase { +class SmallVectorBase { protected: void *BeginX; - Size_T Size = 0, Capacity; + unsigned Size = 0, Capacity; - /// The maximum value of the Size_T used. + /// The maximum value of the unsigned used. static constexpr size_t SizeTypeMax() { - return (std::numeric_limits::max)(); + return (std::numeric_limits::max)(); } SmallVectorBase() = delete; SmallVectorBase(void *FirstEl, size_t TotalCapacity) - : BeginX(FirstEl), Capacity(static_cast(TotalCapacity)) {} + : BeginX(FirstEl), Capacity(static_cast(TotalCapacity)) {} /// This is a helper for \a grow() that's out of line to reduce code /// duplication. This function will report a fatal error if it can't grow at @@ -94,7 +94,7 @@ protected: /// This does not construct or destroy any elements in the vector. void set_size(size_t N) { assert(N <= capacity()); // implies no overflow in assignment - Size = static_cast(N); + Size = static_cast(N); } /// Set the array data pointer to \p Begin and capacity to \p N. @@ -104,19 +104,14 @@ protected: void set_allocation_range(void *Begin, size_t N) { assert(N <= SizeTypeMax()); BeginX = Begin; - Capacity = static_cast(N); + Capacity = static_cast(N); } }; -template -using SmallVectorSizeType = - std::conditional_t= 8, uint64_t, - uint32_t>; - /// Figure out the offset of the first element. template struct SmallVectorAlignmentAndSize { - alignas(SmallVectorBase>) char Base[sizeof( - SmallVectorBase>)]; + alignas(SmallVectorBase) char Base[sizeof( + SmallVectorBase)]; alignas(T) char FirstEl[sizeof(T)]; }; @@ -125,8 +120,8 @@ template struct SmallVectorAlignmentAndSize { /// to avoid unnecessarily requiring T to be complete. template class SmallVectorTemplateCommon - : public SmallVectorBase> { - using Base = SmallVectorBase>; + : public SmallVectorBase { + using Base = SmallVectorBase; protected: /// Find the address of the first element. For this pointer math to be valid @@ -448,7 +443,7 @@ template T *SmallVectorTemplateBase::mallocForGrow( size_t MinSize, size_t &NewCapacity) { return static_cast( - SmallVectorBase>::mallocForGrow( + SmallVectorBase::mallocForGrow( this->getFirstEl(), MinSize, sizeof(T), NewCapacity)); } @@ -1320,12 +1315,6 @@ template SmallVector to_vector_of(R &&Range) { return {std::begin(Range), std::end(Range)}; } -// Explicit instantiations -extern template class llvm::SmallVectorBase; -#if SIZE_MAX > UINT32_MAX -extern template class llvm::SmallVectorBase; -#endif - } // end namespace llvm namespace std { diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp index fba8fcb7cf56f4914e6ab6ede78eb8d8c8bf3424..5fe82c223193e7353d0576b84897422bed26186b 100644 --- a/llvm/lib/Support/SmallVector.cpp +++ b/llvm/lib/Support/SmallVector.cpp @@ -51,10 +51,6 @@ static_assert(sizeof(SmallVector) == sizeof(unsigned) * 2 + sizeof(void *) * 2, "wasted space in SmallVector size 1"); -static_assert(sizeof(SmallVector) == - sizeof(void *) * 2 + sizeof(void *), - "1 byte elements have word-sized type for size and capacity"); - /// Report that MinSize doesn't fit into this vector's size type. Throws /// std::length_error or calls report_fatal_error. [[noreturn]] static void report_size_overflow(size_t MinSize, size_t MaxSize); @@ -85,9 +81,8 @@ static void report_at_maximum_capacity(size_t MaxSize) { } // Note: Moving this function into the header may cause performance regression. -template static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) { - constexpr size_t MaxSize = std::numeric_limits::max(); + constexpr size_t MaxSize = std::numeric_limits::max(); // Ensure we can fit the new capacity. // This is only going to be applicable when the capacity is 32 bit. @@ -127,11 +122,10 @@ static void *replaceAllocation(void *NewElts, size_t TSize, size_t NewCapacity, } // Note: Moving this function into the header may cause performance regression. -template -void *SmallVectorBase::mallocForGrow(void *FirstEl, size_t MinSize, +void *SmallVectorBase::mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize, size_t &NewCapacity) { - NewCapacity = getNewCapacity(MinSize, TSize, this->capacity()); + NewCapacity = getNewCapacity(MinSize, TSize, this->capacity()); // Even if capacity is not 0 now, if the vector was originally created with // capacity 0, it's possible for the malloc to return FirstEl. void *NewElts = llvm::safe_malloc(NewCapacity * TSize); @@ -141,10 +135,9 @@ void *SmallVectorBase::mallocForGrow(void *FirstEl, size_t MinSize, } // Note: Moving this function into the header may cause performance regression. -template -void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSize, +void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSize, size_t TSize) { - size_t NewCapacity = getNewCapacity(MinSize, TSize, this->capacity()); + size_t NewCapacity = getNewCapacity(MinSize, TSize, this->capacity()); void *NewElts; if (BeginX == FirstEl) { NewElts = llvm::safe_malloc(NewCapacity * TSize); @@ -162,20 +155,3 @@ void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSize, this->set_allocation_range(NewElts, NewCapacity); } - -template class llvm::SmallVectorBase; - -// Disable the uint64_t instantiation for 32-bit builds. -// Both uint32_t and uint64_t instantiations are needed for 64-bit builds. -// This instantiation will never be used in 32-bit builds, and will cause -// warnings when sizeof(Size_T) > sizeof(size_t). -#if SIZE_MAX > UINT32_MAX -template class llvm::SmallVectorBase; - -// Assertions to ensure this #if stays in sync with SmallVectorSizeType. -static_assert(sizeof(SmallVectorSizeType) == sizeof(uint64_t), - "Expected SmallVectorBase variant to be in use."); -#else -static_assert(sizeof(SmallVectorSizeType) == sizeof(uint32_t), - "Expected SmallVectorBase variant to be in use."); -#endif