mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
Semiwrap / meson / robotpy define `NDEBUG` when building their software in all modes, while `allwplib` only does it when building debug. This causes the size of `DenseMap` to differ between the shared libraries built here, and the extension modules built in `mostrobotpy`, causing segfaults when you try to execute code that uses `DenseMap`. This is not a problem with the robotpy code in `allwpilib`, because bazel uses the exact same compiler flags when building the shared libraries and pybind11 extensions.
179 lines
7.7 KiB
Diff
179 lines
7.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: PJ Reiniger <pj.reiniger@gmail.com>
|
|
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<std::is_convertible<
|
|
/// Using 64 bit size is desirable for cases like SmallVector<char>, where a
|
|
/// 32 bit size would limit the vector to ~4GB. SmallVectors are used for
|
|
/// buffering bitcode output - which can exceed 4GB.
|
|
-template <class Size_T> 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<Size_T>::max)();
|
|
+ return (std::numeric_limits<unsigned>::max)();
|
|
}
|
|
|
|
SmallVectorBase() = delete;
|
|
SmallVectorBase(void *FirstEl, size_t TotalCapacity)
|
|
- : BeginX(FirstEl), Capacity(static_cast<Size_T>(TotalCapacity)) {}
|
|
+ : BeginX(FirstEl), Capacity(static_cast<unsigned>(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<Size_T>(N);
|
|
+ Size = static_cast<unsigned>(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<Size_T>(N);
|
|
+ Capacity = static_cast<unsigned>(N);
|
|
}
|
|
};
|
|
|
|
-template <class T>
|
|
-using SmallVectorSizeType =
|
|
- std::conditional_t<sizeof(T) < 4 && sizeof(void *) >= 8, uint64_t,
|
|
- uint32_t>;
|
|
-
|
|
/// Figure out the offset of the first element.
|
|
template <class T, typename = void> struct SmallVectorAlignmentAndSize {
|
|
- alignas(SmallVectorBase<SmallVectorSizeType<T>>) char Base[sizeof(
|
|
- SmallVectorBase<SmallVectorSizeType<T>>)];
|
|
+ alignas(SmallVectorBase) char Base[sizeof(
|
|
+ SmallVectorBase)];
|
|
alignas(T) char FirstEl[sizeof(T)];
|
|
};
|
|
|
|
@@ -125,8 +120,8 @@ template <class T, typename = void> struct SmallVectorAlignmentAndSize {
|
|
/// to avoid unnecessarily requiring T to be complete.
|
|
template <typename T, typename = void>
|
|
class SmallVectorTemplateCommon
|
|
- : public SmallVectorBase<SmallVectorSizeType<T>> {
|
|
- using Base = SmallVectorBase<SmallVectorSizeType<T>>;
|
|
+ : 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 <typename T, bool TriviallyCopyable>
|
|
T *SmallVectorTemplateBase<T, TriviallyCopyable>::mallocForGrow(
|
|
size_t MinSize, size_t &NewCapacity) {
|
|
return static_cast<T *>(
|
|
- SmallVectorBase<SmallVectorSizeType<T>>::mallocForGrow(
|
|
+ SmallVectorBase::mallocForGrow(
|
|
this->getFirstEl(), MinSize, sizeof(T), NewCapacity));
|
|
}
|
|
|
|
@@ -1320,12 +1315,6 @@ template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
|
|
return {std::begin(Range), std::end(Range)};
|
|
}
|
|
|
|
-// Explicit instantiations
|
|
-extern template class llvm::SmallVectorBase<uint32_t>;
|
|
-#if SIZE_MAX > UINT32_MAX
|
|
-extern template class llvm::SmallVectorBase<uint64_t>;
|
|
-#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<void *, 1>) ==
|
|
sizeof(unsigned) * 2 + sizeof(void *) * 2,
|
|
"wasted space in SmallVector size 1");
|
|
|
|
-static_assert(sizeof(SmallVector<char, 0>) ==
|
|
- 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 <class Size_T>
|
|
static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) {
|
|
- constexpr size_t MaxSize = std::numeric_limits<Size_T>::max();
|
|
+ constexpr size_t MaxSize = std::numeric_limits<unsigned>::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 <class Size_T>
|
|
-void *SmallVectorBase<Size_T>::mallocForGrow(void *FirstEl, size_t MinSize,
|
|
+void *SmallVectorBase::mallocForGrow(void *FirstEl, size_t MinSize,
|
|
size_t TSize,
|
|
size_t &NewCapacity) {
|
|
- NewCapacity = getNewCapacity<Size_T>(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<Size_T>::mallocForGrow(void *FirstEl, size_t MinSize,
|
|
}
|
|
|
|
// Note: Moving this function into the header may cause performance regression.
|
|
-template <class Size_T>
|
|
-void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
|
|
+void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSize,
|
|
size_t TSize) {
|
|
- size_t NewCapacity = getNewCapacity<Size_T>(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<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
|
|
|
|
this->set_allocation_range(NewElts, NewCapacity);
|
|
}
|
|
-
|
|
-template class llvm::SmallVectorBase<uint32_t>;
|
|
-
|
|
-// 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<uint64_t>;
|
|
-
|
|
-// Assertions to ensure this #if stays in sync with SmallVectorSizeType.
|
|
-static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint64_t),
|
|
- "Expected SmallVectorBase<uint64_t> variant to be in use.");
|
|
-#else
|
|
-static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint32_t),
|
|
- "Expected SmallVectorBase<uint32_t> variant to be in use.");
|
|
-#endif
|