[upstream_utils] Upgrade to LLVM 20.1.7 (#8033)

Also removes xxhash, Hashing, and MapVector to reduce the size of the patches and to speed up compile times by a smidge.
This commit is contained in:
Gold856
2025-06-25 01:36:22 -04:00
committed by GitHub
parent a77441b78a
commit 22b58c1853
73 changed files with 1154 additions and 3813 deletions

View File

@@ -56,8 +56,8 @@ jobs:
fail-fast: false
matrix:
include:
- { name: "Linux (native)", os: ubuntu-24.04, container: "wpilib/ubuntu-base:22.04", action: "test", config: "--config=linux", }
- { name: "Linux (systemcore)", os: ubuntu-24.04, container: "wpilib/ubuntu-base:22.04", action: "build", config: "--config=systemcore", }
- { name: "Linux (native)", os: ubuntu-24.04, container: "wpilib/ubuntu-base:24.04", action: "test", config: "--config=linux", }
- { name: "Linux (systemcore)", os: ubuntu-24.04, container: "wpilib/ubuntu-base:24.04", action: "build", config: "--config=systemcore", }
name: "${{ matrix.name }}"
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}

View File

@@ -45,11 +45,9 @@ macro(add_doxygen_docs)
"wpi/fs.h"
"wpi/FunctionExtras.h"
"wpi/function_ref.h"
"wpi/Hashing.h"
"wpi/iterator.h"
"wpi/iterator_range.h"
"wpi/ManagedStatic.h"
"wpi/MapVector.h"
"wpi/MathExtras.h"
"wpi/MemAlloc.h"
"wpi/PointerIntPair.h"

View File

@@ -98,11 +98,9 @@ doxygen {
exclude 'wpi/fs.h'
exclude 'wpi/FunctionExtras.h'
exclude 'wpi/function_ref.h'
exclude 'wpi/Hashing.h'
exclude 'wpi/iterator.h'
exclude 'wpi/iterator_range.h'
exclude 'wpi/ManagedStatic.h'
exclude 'wpi/MapVector.h'
exclude 'wpi/MathExtras.h'
exclude 'wpi/MemAlloc.h'
exclude 'wpi/PointerIntPair.h'

View File

@@ -47,6 +47,7 @@ def run_global_replacements(wpiutil_llvm_files: list[Path]):
content = content.replace('#include "wpi/Error.h"\n', "")
content = content.replace('#include "wpi/Format.h"\n', "")
content = content.replace('#include "wpi/FormatVariadic.h"\n', "")
content = content.replace('#include "wpi/Hashing.h"\n', "")
content = content.replace('#include "wpi/NativeFormatting.h"\n', "")
content = content.replace('#include "wpi/Threading.h"\n', "")
content = content.replace('#include "wpi/DataTypes.h"\n', "")
@@ -179,7 +180,7 @@ def copy_upstream_src(wpilib_root: Path):
def main():
name = "llvm"
url = "https://github.com/llvm/llvm-project"
tag = "llvmorg-19.1.6"
tag = "llvmorg-20.1.7"
patch_options = {
"use_threeway": True,

View File

@@ -1,38 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sat, 7 May 2022 22:09:18 -0400
Subject: [PATCH 01/37] Remove StringRef, ArrayRef, and Optional
Subject: [PATCH 01/36] Remove StringRef, ArrayRef, and Optional
---
llvm/include/llvm/ADT/PointerUnion.h | 1 -
llvm/include/llvm/ADT/SmallSet.h | 2 +-
llvm/include/llvm/ADT/SmallString.h | 101 ++++++++++--------
llvm/include/llvm/ADT/SmallVector.h | 7 +-
llvm/include/llvm/Support/Chrono.h | 10 +-
llvm/include/llvm/Support/Compiler.h | 2 +-
llvm/include/llvm/Support/ConvertUTF.h | 31 +++---
llvm/include/llvm/Support/ErrorHandling.h | 9 +-
.../llvm/Support/SmallVectorMemoryBuffer.h | 6 +-
llvm/include/llvm/Support/VersionTuple.h | 6 --
.../llvm/Support/Windows/WindowsSupport.h | 4 +-
llvm/include/llvm/Support/raw_ostream.h | 46 ++++----
llvm/include/llvm/Support/xxhash.h | 18 ++--
llvm/lib/Support/ConvertUTFWrapper.cpp | 38 +++----
llvm/lib/Support/ConvertUTFWrapper.cpp | 39 +++----
llvm/lib/Support/ErrorHandling.cpp | 13 ++-
llvm/lib/Support/SmallVector.cpp | 5 +-
llvm/lib/Support/raw_ostream.cpp | 25 +++--
llvm/lib/Support/xxhash.cpp | 12 +--
llvm/unittests/ADT/DenseMapTest.cpp | 29 +----
llvm/unittests/ADT/FunctionExtrasTest.cpp | 12 +--
llvm/unittests/ADT/SmallPtrSetTest.cpp | 1 -
llvm/unittests/ADT/SmallStringTest.cpp | 50 ++++-----
llvm/unittests/ADT/SmallVectorTest.cpp | 30 ++----
llvm/unittests/Support/ConvertUTFTest.cpp | 41 ++++---
llvm/unittests/Support/xxhashTest.cpp | 6 +-
25 files changed, 232 insertions(+), 273 deletions(-)
llvm/unittests/Support/ConvertUTFTest.cpp | 42 ++++----
20 files changed, 211 insertions(+), 252 deletions(-)
diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h
index 7d4ed02b622626bb8043acb57b8ce7ed97a5f949..8ac68dbc0a791b8ac0e0ca865e69024cb642aa70 100644
index cdbd76d7f505be277c3886cc821fb60336cbec59..23394db93cfed492bb1747eb9c8c55ed9230120d 100644
--- a/llvm/include/llvm/ADT/PointerUnion.h
+++ b/llvm/include/llvm/ADT/PointerUnion.h
@@ -17,7 +17,6 @@
@@ -43,24 +38,6 @@ index 7d4ed02b622626bb8043acb57b8ce7ed97a5f949..8ac68dbc0a791b8ac0e0ca865e69024c
#include "llvm/Support/Casting.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <algorithm>
diff --git a/llvm/include/llvm/ADT/SmallSet.h b/llvm/include/llvm/ADT/SmallSet.h
index a16e8ac6f07552d98250e808190b00ee270f12b3..aeee5f97799aea7e7588d7afba1e47b4fa3d8c7b 100644
--- a/llvm/include/llvm/ADT/SmallSet.h
+++ b/llvm/include/llvm/ADT/SmallSet.h
@@ -16,12 +16,12 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <cstddef>
#include <functional>
+#include <optional>
#include <set>
#include <type_traits>
#include <utility>
diff --git a/llvm/include/llvm/ADT/SmallString.h b/llvm/include/llvm/ADT/SmallString.h
index be3193c6ef9beba622f39e3e76cd0f0c6dd422b0..9fab1a7726bc6745296f5ebb24aee4055408e5f5 100644
--- a/llvm/include/llvm/ADT/SmallString.h
@@ -329,10 +306,10 @@ index be3193c6ef9beba622f39e3e76cd0f0c6dd422b0..9fab1a7726bc6745296f5ebb24aee405
return *this;
}
diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
index 17444147b102a9636fe4f0f48cfb647aaaf3ed6b..94d8da059f4f8bad50039b0d0b7993396707829c 100644
index bd3e887e36bce4129d95099e84e833adc6a82cee..be06bb817e24e723265f9a8038d94123de1fc53c 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/include/llvm/ADT/SmallVector.h
@@ -28,13 +28,12 @@
@@ -27,13 +27,12 @@
#include <limits>
#include <memory>
#include <new>
@@ -347,7 +324,7 @@ index 17444147b102a9636fe4f0f48cfb647aaaf3ed6b..94d8da059f4f8bad50039b0d0b799339
template <typename IteratorT> class iterator_range;
template <class Iterator>
@@ -128,7 +127,7 @@ template <class T, typename = void> struct SmallVectorAlignmentAndSize {
@@ -114,7 +113,7 @@ template <class T, typename = void> struct SmallVectorAlignmentAndSize {
};
/// This is the part of SmallVectorTemplateBase which does not depend on whether
@@ -356,7 +333,7 @@ index 17444147b102a9636fe4f0f48cfb647aaaf3ed6b..94d8da059f4f8bad50039b0d0b799339
/// to avoid unnecessarily requiring T to be complete.
template <typename T, typename = void>
class SmallVectorTemplateCommon
@@ -1243,7 +1242,7 @@ public:
@@ -1229,7 +1228,7 @@ public:
template <typename U,
typename = std::enable_if_t<std::is_convertible<U, T>::value>>
@@ -409,10 +386,10 @@ index 71859af7c7e4a595140475daf356744f52d14d24..9c9ba7002310eba5113c14957f769702
bool show_unit = consumeShowUnit(Style);
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index d8e3794babc7449b436fa1d0bd858dab5198664b..7710bd9a08148289b5ba3b1f2dae5cccc4f26d4d 100644
index dc8b5389069ebfe217d323fb9c75d6e0fe7d5b8e..021d1d29368deb330418ff4e08fbf3931e4b7453 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -327,7 +327,7 @@
@@ -406,7 +406,7 @@
#endif
/// LLVM_GSL_POINTER - Apply this to non-owning classes like
@@ -565,30 +542,6 @@ index 9c8e3448f3a03e3540adb8b9dd730c77dd9b20ba..68c27a8c67c4f378b92cfa726659ef78
bool gen_crash_diag = true);
/// Installs a new bad alloc error handler that should be used whenever a
diff --git a/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h b/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h
index f7f2d4e54e705d6f29812dc93d1fb0a3ca2dee12..b5e321b5f74ce35940649b9d1342b3cdf0c4931f 100644
--- a/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h
+++ b/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h
@@ -35,8 +35,8 @@ public:
RequiresNullTerminator) {}
/// Construct a named SmallVectorMemoryBuffer from the given SmallVector
- /// r-value and StringRef.
- SmallVectorMemoryBuffer(SmallVectorImpl<char> &&SV, StringRef Name,
+ /// r-value and std::string_view.
+ SmallVectorMemoryBuffer(SmallVectorImpl<char> &&SV, std::string_view Name,
bool RequiresNullTerminator = true)
: SV(std::move(SV)), BufferName(std::string(Name)) {
if (RequiresNullTerminator) {
@@ -49,7 +49,7 @@ public:
// Key function.
~SmallVectorMemoryBuffer() override;
- StringRef getBufferIdentifier() const override { return BufferName; }
+ std::string_view getBufferIdentifier() const override { return BufferName; }
BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; }
diff --git a/llvm/include/llvm/Support/VersionTuple.h b/llvm/include/llvm/Support/VersionTuple.h
index 0a4623f049d28825530bf50c8acfe85deaed96ba..e1cdce77ce8659305c99a21e01f9b3cc3481a5fd 100644
--- a/llvm/include/llvm/Support/VersionTuple.h
@@ -614,10 +567,10 @@ index 0a4623f049d28825530bf50c8acfe85deaed96ba..e1cdce77ce8659305c99a21e01f9b3cc
/// Print a version number.
diff --git a/llvm/include/llvm/Support/Windows/WindowsSupport.h b/llvm/include/llvm/Support/Windows/WindowsSupport.h
index d3aacd14b2097b1e7e13c1003987c1fd52e0cf76..aabdb2f14668a990329b57f5454a0d7db73e12ce 100644
index 6f5aae2485c525f100eace5316b3e53e7b4fa544..83d5586ae8a77ec585e7e59df3075ca59cfb9d0c 100644
--- a/llvm/include/llvm/Support/Windows/WindowsSupport.h
+++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h
@@ -35,8 +35,6 @@
@@ -33,8 +33,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -626,7 +579,7 @@ index d3aacd14b2097b1e7e13c1003987c1fd52e0cf76..aabdb2f14668a990329b57f5454a0d7d
#include "llvm/Config/llvm-config.h" // Get build system configuration settings
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Chrono.h"
@@ -74,7 +72,7 @@ bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix);
@@ -72,7 +70,7 @@ bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix);
[[noreturn]] inline void ReportLastErrorFatal(const char *Msg) {
std::string ErrMsg;
MakeErrMsg(&ErrMsg, Msg);
@@ -636,7 +589,7 @@ index d3aacd14b2097b1e7e13c1003987c1fd52e0cf76..aabdb2f14668a990329b57f5454a0d7d
template <typename HandleTraits>
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index df9ee2e5a78586d2a2e0eb6e0698953169f7bc58..18bdf4b7d3b96d42d93ca1e4800233b34be42a78 100644
index d3b411590e7fd796913aca8517020d02aa2559cc..c43c68c9114d8cd564484b190456b0069818dc87 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -14,13 +14,12 @@
@@ -747,7 +700,7 @@ index df9ee2e5a78586d2a2e0eb6e0698953169f7bc58..18bdf4b7d3b96d42d93ca1e4800233b3
SmallVectorImpl<char> &buffer() { return OS; }
void reserveExtraSpace(uint64_t ExtraSize) override {
@@ -777,7 +787,7 @@ class Error;
@@ -835,7 +845,7 @@ class Error;
/// for other names. For raw_fd_ostream instances, the stream writes to
/// a temporary file. The final output file is atomically replaced with the
/// temporary file after the \p Write function is finished.
@@ -756,51 +709,11 @@ index df9ee2e5a78586d2a2e0eb6e0698953169f7bc58..18bdf4b7d3b96d42d93ca1e4800233b3
std::function<Error(raw_ostream &)> Write);
raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t);
diff --git a/llvm/include/llvm/Support/xxhash.h b/llvm/include/llvm/Support/xxhash.h
index 5f8a7ab360abe24e86286b2bd6b83df7ca5fa7d3..5267e22a45f6c0c6e3bc9ca1966ed9842772918e 100644
--- a/llvm/include/llvm/Support/xxhash.h
+++ b/llvm/include/llvm/Support/xxhash.h
@@ -38,17 +38,19 @@
#ifndef LLVM_SUPPORT_XXHASH_H
#define LLVM_SUPPORT_XXHASH_H
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
+#include <stdint.h>
+
+#include <span>
+#include <string_view>
namespace llvm {
-uint64_t xxHash64(llvm::StringRef Data);
-uint64_t xxHash64(llvm::ArrayRef<uint8_t> Data);
+uint64_t xxHash64(std::string_view Data);
+uint64_t xxHash64(span<const uint8_t> Data);
-uint64_t xxh3_64bits(ArrayRef<uint8_t> data);
-inline uint64_t xxh3_64bits(StringRef data) {
- return xxh3_64bits(ArrayRef(data.bytes_begin(), data.size()));
+uint64_t xxh3_64bits(span<const uint8_t> data);
+inline uint64_t xxh3_64bits(std::string_view data) {
+ return xxh3_64bits(span(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
}
/*-**********************************************************************
@@ -72,7 +74,7 @@ struct XXH128_hash_t {
};
/// XXH3's 128-bit variant.
-XXH128_hash_t xxh3_128bits(ArrayRef<uint8_t> data);
+XXH128_hash_t xxh3_128bits(span<const uint8_t> data);
} // namespace llvm
diff --git a/llvm/lib/Support/ConvertUTFWrapper.cpp b/llvm/lib/Support/ConvertUTFWrapper.cpp
index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa63772e78a8a 100644
index 4952fe65d77675aeae8f4f5fdad7b47863e36ca5..d53462e742e61d3476915d5b2c5aa63772e78a8a 100644
--- a/llvm/lib/Support/ConvertUTFWrapper.cpp
+++ b/llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -6,24 +6,24 @@
@@ -6,23 +6,24 @@
//
//===----------------------------------------------------------------------===//
@@ -808,7 +721,7 @@ index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa637
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SwapByteOrder.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include <span>
#include <string>
+#include <string_view>
@@ -830,7 +743,7 @@ index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa637
result = sourceIllegal;
ErrorPtr = Pos;
} else {
@@ -76,12 +76,12 @@ bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) {
@@ -75,12 +76,12 @@ bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) {
return true;
}
@@ -845,7 +758,7 @@ index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa637
assert(Out.empty());
// Error out on an uneven byte count.
@@ -132,14 +132,14 @@ bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out) {
@@ -131,14 +132,14 @@ bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out) {
return true;
}
@@ -863,7 +776,7 @@ index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa637
assert(Out.empty());
// Error out on an uneven byte count.
@@ -190,14 +190,14 @@ bool convertUTF32ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out) {
@@ -189,14 +190,14 @@ bool convertUTF32ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out) {
return true;
}
@@ -881,7 +794,7 @@ index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa637
SmallVectorImpl<UTF16> &DstUTF16) {
assert(DstUTF16.empty());
@@ -208,8 +208,8 @@ bool convertUTF8ToUTF16String(StringRef SrcUTF8,
@@ -207,8 +208,8 @@ bool convertUTF8ToUTF16String(StringRef SrcUTF8,
return true;
}
@@ -892,7 +805,7 @@ index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa637
// Allocate the same number of UTF-16 code units as UTF-8 code units. Encoding
// as UTF-16 should always require the same amount or less code units than the
@@ -240,7 +240,7 @@ static_assert(sizeof(wchar_t) == 1 || sizeof(wchar_t) == 2 ||
@@ -239,7 +240,7 @@ static_assert(sizeof(wchar_t) == 1 || sizeof(wchar_t) == 2 ||
"Expected wchar_t to be 1, 2, or 4 bytes");
template <typename TResult>
@@ -901,7 +814,7 @@ index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa637
TResult &Result) {
// Even in the case of UTF-16, the number of bytes in a UTF-8 string is
// at least as large as the number of elements in the resulting wide
@@ -256,7 +256,7 @@ static inline bool ConvertUTF8toWideInternal(llvm::StringRef Source,
@@ -255,7 +256,7 @@ static inline bool ConvertUTF8toWideInternal(llvm::StringRef Source,
return true;
}
@@ -910,7 +823,7 @@ index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa637
return ConvertUTF8toWideInternal(Source, Result);
}
@@ -265,7 +265,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result) {
@@ -264,7 +265,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result) {
Result.clear();
return true;
}
@@ -919,7 +832,7 @@ index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa637
}
bool convertWideToUTF8(const std::wstring &Source, std::string &Result) {
@@ -280,7 +280,7 @@ bool convertWideToUTF8(const std::wstring &Source, std::string &Result) {
@@ -279,7 +280,7 @@ bool convertWideToUTF8(const std::wstring &Source, std::string &Result) {
return true;
} else if (sizeof(wchar_t) == 2) {
return convertUTF16ToUTF8String(
@@ -929,7 +842,7 @@ index 3fa7365e72d34a5db941d1cbe2b1beebad5c10e6..d53462e742e61d3476915d5b2c5aa637
Result);
} else if (sizeof(wchar_t) == 4) {
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index cb42e28c04a86dd60deae6fdb0b87850c1bf3727..561509e0efdf15f6e534f0621a5964d92511114c 100644
index afe3b37cc343195e9ea12a68077d6b9d7506d5bb..d4ca266f3c1f98337499fba4fd0675e49a7dcf18 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -14,7 +14,6 @@
@@ -938,9 +851,9 @@ index cb42e28c04a86dd60deae6fdb0b87850c1bf3727..561509e0efdf15f6e534f0621a5964d9
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
#include "llvm/Support/Debug.h"
#include "llvm/Support/Errc.h"
@@ -80,14 +79,14 @@ void llvm::remove_fatal_error_handler() {
@@ -81,14 +80,14 @@ void llvm::remove_fatal_error_handler() {
}
void llvm::report_fatal_error(const char *Reason, bool GenCrashDiag) {
@@ -959,7 +872,7 @@ index cb42e28c04a86dd60deae6fdb0b87850c1bf3727..561509e0efdf15f6e534f0621a5964d9
llvm::fatal_error_handler_t handler = nullptr;
void* handlerData = nullptr;
{
@@ -101,7 +100,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
@@ -102,7 +101,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
}
if (handler) {
@@ -968,7 +881,7 @@ index cb42e28c04a86dd60deae6fdb0b87850c1bf3727..561509e0efdf15f6e534f0621a5964d9
} else {
// Blast the result out to stderr. We don't try hard to make sure this
// succeeds (e.g. handling EINTR) and we can't use errs() here because
@@ -109,7 +108,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
@@ -110,7 +109,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
SmallVector<char, 64> Buffer;
raw_svector_ostream OS(Buffer);
OS << "LLVM ERROR: " << Reason << "\n";
@@ -978,7 +891,7 @@ index cb42e28c04a86dd60deae6fdb0b87850c1bf3727..561509e0efdf15f6e534f0621a5964d9
(void)written; // If something went wrong, we deliberately just give up.
}
diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp
index b6ce37842040b36fc79770ca0296255f2bb42a1a..4f6fee18b659adcbfd79822832f914170cbb1635 100644
index dceea4fbc630e85a869458af8b35ee1066c5866d..fba8fcb7cf56f4914e6ab6ede78eb8d8c8bf3424 100644
--- a/llvm/lib/Support/SmallVector.cpp
+++ b/llvm/lib/Support/SmallVector.cpp
@@ -11,7 +11,6 @@
@@ -1008,10 +921,10 @@ index b6ce37842040b36fc79770ca0296255f2bb42a1a..4f6fee18b659adcbfd79822832f91417
}
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 2ce54faa9857e68d9c7de4ad28f6cfa5bae86908..2dbb0674406e1860fdd0c266df64003e45b12fa3 100644
index e75ddc66b7d1629a4e71c53d891ae0d3edf90813..681b6fdc95eb4fda4f23d0b381b83417d82b3b78 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -167,7 +167,7 @@ raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) {
@@ -165,7 +165,7 @@ raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) {
}
@@ -1020,7 +933,7 @@ index 2ce54faa9857e68d9c7de4ad28f6cfa5bae86908..2dbb0674406e1860fdd0c266df64003e
bool UseHexEscapes) {
for (unsigned char c : Str) {
switch (c) {
@@ -564,7 +564,7 @@ void format_object_base::home() {
@@ -562,7 +562,7 @@ void format_object_base::home() {
// raw_fd_ostream
//===----------------------------------------------------------------------===//
@@ -1029,7 +942,7 @@ index 2ce54faa9857e68d9c7de4ad28f6cfa5bae86908..2dbb0674406e1860fdd0c266df64003e
sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
sys::fs::OpenFlags Flags) {
assert((Access & sys::fs::FA_Write) &&
@@ -590,25 +590,25 @@ static int getFD(StringRef Filename, std::error_code &EC,
@@ -588,25 +588,25 @@ static int getFD(StringRef Filename, std::error_code &EC,
return FD;
}
@@ -1060,7 +973,7 @@ index 2ce54faa9857e68d9c7de4ad28f6cfa5bae86908..2dbb0674406e1860fdd0c266df64003e
sys::fs::CreationDisposition Disp,
sys::fs::FileAccess Access,
sys::fs::OpenFlags Flags)
@@ -680,8 +680,7 @@ raw_fd_ostream::~raw_fd_ostream() {
@@ -678,8 +678,7 @@ raw_fd_ostream::~raw_fd_ostream() {
// has_error() and clear the error flag with clear_error() before
// destructing raw_ostream objects which may have errors.
if (has_error())
@@ -1070,7 +983,7 @@ index 2ce54faa9857e68d9c7de4ad28f6cfa5bae86908..2dbb0674406e1860fdd0c266df64003e
/*gen_crash_diag=*/false);
}
@@ -700,7 +699,7 @@ raw_fd_ostream::~raw_fd_ostream() {
@@ -698,7 +697,7 @@ raw_fd_ostream::~raw_fd_ostream() {
// the input is UTF-8 or transcode from the local codepage to UTF-8 before
// quoting it. If they don't, this may mess up the encoding, but this is still
// probably the best compromise we can make.
@@ -1079,7 +992,7 @@ index 2ce54faa9857e68d9c7de4ad28f6cfa5bae86908..2dbb0674406e1860fdd0c266df64003e
SmallVector<wchar_t, 256> WideText;
// Fall back to ::write if it wasn't valid UTF-8.
@@ -746,7 +745,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
@@ -744,7 +743,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
// If this is a Windows console device, try re-encoding from UTF-8 to UTF-16
// and using WriteConsoleW. If that fails, fall back to plain write().
if (IsWindowsConsole)
@@ -1088,7 +1001,7 @@ index 2ce54faa9857e68d9c7de4ad28f6cfa5bae86908..2dbb0674406e1860fdd0c266df64003e
return;
#endif
@@ -922,7 +921,7 @@ raw_ostream &llvm::nulls() {
@@ -924,7 +923,7 @@ raw_ostream &llvm::nulls() {
// File Streams
//===----------------------------------------------------------------------===//
@@ -1097,7 +1010,7 @@ index 2ce54faa9857e68d9c7de4ad28f6cfa5bae86908..2dbb0674406e1860fdd0c266df64003e
: raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways,
sys::fs::FA_Write | sys::fs::FA_Read,
sys::fs::OF_None),
@@ -1007,7 +1006,7 @@ void buffer_ostream::anchor() {}
@@ -1009,7 +1008,7 @@ void buffer_ostream::anchor() {}
void buffer_unique_ostream::anchor() {}
@@ -1106,52 +1019,6 @@ index 2ce54faa9857e68d9c7de4ad28f6cfa5bae86908..2dbb0674406e1860fdd0c266df64003e
std::function<Error(raw_ostream &)> Write) {
if (OutputFileName == "-")
return Write(outs());
diff --git a/llvm/lib/Support/xxhash.cpp b/llvm/lib/Support/xxhash.cpp
index cdb76d57e2c1df67e07c39f5e59284ab0ce07984..2496050eef7349ad82b54ffa6fb6bff8278c8364 100644
--- a/llvm/lib/Support/xxhash.cpp
+++ b/llvm/lib/Support/xxhash.cpp
@@ -100,11 +100,11 @@ static uint64_t XXH64_avalanche(uint64_t hash) {
return hash;
}
-uint64_t llvm::xxHash64(StringRef Data) {
+uint64_t llvm::xxHash64(std::string_view Data) {
size_t Len = Data.size();
uint64_t Seed = 0;
- const unsigned char *P = Data.bytes_begin();
- const unsigned char *const BEnd = Data.bytes_end();
+ const unsigned char *P = reinterpret_cast<const unsigned char*>(Data.data());
+ const unsigned char *const BEnd = P + Data.size();
uint64_t H64;
if (Len >= 32) {
@@ -160,7 +160,7 @@ uint64_t llvm::xxHash64(StringRef Data) {
return XXH64_avalanche(H64);
}
-uint64_t llvm::xxHash64(ArrayRef<uint8_t> Data) {
+uint64_t llvm::xxHash64(span<const uint8_t> Data) {
return xxHash64({(const char *)Data.data(), Data.size()});
}
@@ -550,7 +550,7 @@ static uint64_t XXH3_hashLong_64b(const uint8_t *input, size_t len,
(uint64_t)len * PRIME64_1);
}
-uint64_t llvm::xxh3_64bits(ArrayRef<uint8_t> data) {
+uint64_t llvm::xxh3_64bits(span<const uint8_t> data) {
auto *in = data.data();
size_t len = data.size();
if (len <= 16)
@@ -1020,7 +1020,7 @@ XXH3_hashLong_128b(const uint8_t *input, size_t len, const uint8_t *secret,
return h128;
}
-llvm::XXH128_hash_t llvm::xxh3_128bits(ArrayRef<uint8_t> data) {
+llvm::XXH128_hash_t llvm::xxh3_128bits(span<const uint8_t> data) {
size_t len = data.size();
const uint8_t *input = data.data();
diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp
index d1bbdde8dfc267770b9d98808de54381571f2785..e93e18423507655ce8275a0718d8e5d01915985f 100644
--- a/llvm/unittests/ADT/DenseMapTest.cpp
@@ -1211,10 +1078,10 @@ index d1bbdde8dfc267770b9d98808de54381571f2785..e93e18423507655ce8275a0718d8e5d0
}
diff --git a/llvm/unittests/ADT/FunctionExtrasTest.cpp b/llvm/unittests/ADT/FunctionExtrasTest.cpp
index fc856a976946bf6decda9b6724cac66afc7bdcd6..aff9d61c7f0d48834123b04b74a2e4f7c86a56d8 100644
index 9809a92daac72468ed5bbd1762798523c2c3d628..777c5784949fd3c07bbbcef8dc3fc8e5764896a9 100644
--- a/llvm/unittests/ADT/FunctionExtrasTest.cpp
+++ b/llvm/unittests/ADT/FunctionExtrasTest.cpp
@@ -249,23 +249,23 @@ TEST(UniqueFunctionTest, Const) {
@@ -250,23 +250,23 @@ TEST(UniqueFunctionTest, Const) {
// Overloaded call operator correctly resolved.
struct ChooseCorrectOverload {
@@ -1245,7 +1112,7 @@ index fc856a976946bf6decda9b6724cac66afc7bdcd6..aff9d61c7f0d48834123b04b74a2e4f7
TEST(UniqueFunctionTest, SFINAE) {
EXPECT_EQ("not a function", returns("boo!"));
diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp
index b45318d076a3d846b7810ce8cdaed7d2d97eca87..a39b11b9f82156a78b9ad7ce7b8c28855829e611 100644
index 1d9a0d1725a92ffd1bddcddf0a9ede28a1a74969..88be2b68915573a3b3a343ff53a84d86604d7bfd 100644
--- a/llvm/unittests/ADT/SmallPtrSetTest.cpp
+++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp
@@ -12,7 +12,6 @@
@@ -1254,8 +1121,8 @@ index b45318d076a3d846b7810ce8cdaed7d2d97eca87..a39b11b9f82156a78b9ad7ce7b8c2885
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
diff --git a/llvm/unittests/ADT/SmallStringTest.cpp b/llvm/unittests/ADT/SmallStringTest.cpp
index 2f4df8afeafa592cb9616bb78feb4964187786f2..6cf14700b34739420cd3dc4ff8a4c16ce162f715 100644
--- a/llvm/unittests/ADT/SmallStringTest.cpp
@@ -1465,7 +1332,7 @@ index 137dd43b473068eae34b39edc4b9b8b9633bab95..7029038d18d433cef987bedbfa4fda26
llvm::SmallVector<To> Vector(Array);
diff --git a/llvm/unittests/Support/ConvertUTFTest.cpp b/llvm/unittests/Support/ConvertUTFTest.cpp
index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b8a4fa472 100644
index 4c35a7e06df142cab79636df7769e556a42e1646..3b07d344f15a555f11ad5f8177a0a65b8a4fa472 100644
--- a/llvm/unittests/Support/ConvertUTFTest.cpp
+++ b/llvm/unittests/Support/ConvertUTFTest.cpp
@@ -7,7 +7,6 @@
@@ -1521,7 +1388,7 @@ index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b
SmallVector<UTF16, 5> Result;
bool Success = convertUTF8ToUTF16String(Ref, Result);
EXPECT_TRUE(Success);
@@ -75,38 +74,38 @@ TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
@@ -75,37 +74,38 @@ TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
TEST(ConvertUTFTest, OddLengthInput) {
std::string Result;
@@ -1532,8 +1399,8 @@ index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b
TEST(ConvertUTFTest, Empty) {
std::string Result;
bool Success =
- convertUTF16ToUTF8String(llvm::ArrayRef<char>(std::nullopt), Result);
- bool Success = convertUTF16ToUTF8String(llvm::ArrayRef<char>(), Result);
+ bool Success =
+ convertUTF16ToUTF8String(span<const char>(), Result);
EXPECT_TRUE(Success);
EXPECT_TRUE(Result.empty());
@@ -1553,7 +1420,7 @@ index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b
+ HasBOM = hasUTF16ByteOrderMark("\xfe\xff\x00asdf");
EXPECT_TRUE(HasBOM);
- HasBOM = hasUTF16ByteOrderMark(std::nullopt);
- HasBOM = hasUTF16ByteOrderMark({});
+ HasBOM = hasUTF16ByteOrderMark("");
EXPECT_FALSE(HasBOM);
- HasBOM = hasUTF16ByteOrderMark(ArrayRef("\xfe", 1));
@@ -1569,7 +1436,7 @@ index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b
std::string Result;
bool Success = convertUTF16ToUTF8String(SrcRef, Result);
EXPECT_TRUE(Success);
@@ -123,7 +122,7 @@ TEST(ConvertUTFTest, ConvertUTF8toWide) {
@@ -122,7 +122,7 @@ TEST(ConvertUTFTest, ConvertUTF8toWide) {
std::wstring Expected(L"\x0ca0_\x0ca0");
EXPECT_EQ(Expected, Result);
Result.clear();
@@ -1578,7 +1445,7 @@ index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b
EXPECT_TRUE(Success);
EXPECT_EQ(Expected, Result);
}
@@ -172,7 +171,7 @@ struct ConvertUTFResultContainer {
@@ -171,7 +171,7 @@ struct ConvertUTFResultContainer {
};
std::pair<ConversionResult, std::vector<unsigned>>
@@ -1587,7 +1454,7 @@ index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b
const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(S.data());
const UTF8 *SourceNext = SourceStart;
@@ -189,7 +188,7 @@ ConvertUTF8ToUnicodeScalarsLenient(StringRef S) {
@@ -188,7 +188,7 @@ ConvertUTF8ToUnicodeScalarsLenient(StringRef S) {
}
std::pair<ConversionResult, std::vector<unsigned>>
@@ -1596,7 +1463,7 @@ index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b
const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(S.data());
const UTF8 *SourceNext = SourceStart;
@@ -207,7 +206,7 @@ ConvertUTF8ToUnicodeScalarsPartialLenient(StringRef S) {
@@ -206,7 +206,7 @@ ConvertUTF8ToUnicodeScalarsPartialLenient(StringRef S) {
::testing::AssertionResult
CheckConvertUTF8ToUnicodeScalars(ConvertUTFResultContainer Expected,
@@ -1605,7 +1472,7 @@ index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b
ConversionResult ErrorCode;
std::vector<unsigned> Decoded;
if (!Partial)
@@ -302,7 +301,7 @@ TEST(ConvertUTFTest, UTF8ToUTF32Lenient) {
@@ -301,7 +301,7 @@ TEST(ConvertUTFTest, UTF8ToUTF32Lenient) {
// U+0000 NULL
EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
ConvertUTFResultContainer(conversionOK).withScalars(0x0000),
@@ -1614,7 +1481,7 @@ index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b
// U+0080 PADDING CHARACTER
EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
@@ -1076,7 +1075,7 @@ TEST(ConvertUTFTest, UTF8ToUTF32Lenient) {
@@ -1075,7 +1075,7 @@ TEST(ConvertUTFTest, UTF8ToUTF32Lenient) {
// U+0000 NULL
EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
ConvertUTFResultContainer(conversionOK).withScalars(0x0000),
@@ -1623,34 +1490,3 @@ index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b
// Overlong sequences of the above.
EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
diff --git a/llvm/unittests/Support/xxhashTest.cpp b/llvm/unittests/Support/xxhashTest.cpp
index 84308ce130e72818b553ea4185e8542d13182b3c..ef9a43690974ba586acc681e9f8ac49d4661031e 100644
--- a/llvm/unittests/Support/xxhashTest.cpp
+++ b/llvm/unittests/Support/xxhashTest.cpp
@@ -32,7 +32,7 @@ static void fillTestBuffer(uint8_t *buffer, size_t len) {
}
TEST(xxhashTest, Basic) {
- EXPECT_EQ(0xef46db3751d8e999U, xxHash64(StringRef()));
+ EXPECT_EQ(0xef46db3751d8e999U, xxHash64(std::string_view()));
EXPECT_EQ(0x33bf00a859c4ba3fU, xxHash64("foo"));
EXPECT_EQ(0x48a37c90ad27a659U, xxHash64("bar"));
EXPECT_EQ(0x69196c1b3af0bff9U,
@@ -51,7 +51,7 @@ TEST(xxhashTest, xxh3) {
}
#define F(len, expected) \
- EXPECT_EQ(uint64_t(expected), xxh3_64bits(ArrayRef(a, size_t(len))))
+ EXPECT_EQ(uint64_t(expected), xxh3_64bits(span(a, size_t(len))))
F(0, 0x2d06800538d394c2);
F(1, 0xd0d496e05c553485);
F(2, 0x84d625edb7055eac);
@@ -90,7 +90,7 @@ TEST(xxhashTest, xxh3_128bits) {
#define F(len, expected) \
EXPECT_EQ(XXH128_hash_t(expected), \
- xxh3_128bits(ArrayRef(sanityBuffer, size_t(len))))
+ xxh3_128bits(span(sanityBuffer, size_t(len))))
F(0, (XXH128_hash_t{0x6001C324468D497FULL,
0x99AA06D3014798D8ULL})); /* empty string */

View File

@@ -1,20 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sat, 7 May 2022 22:12:41 -0400
Subject: [PATCH 02/37] Wrap std::min/max calls in parens, for Windows warnings
Subject: [PATCH 02/36] Wrap std::min/max calls in parens, for Windows warnings
---
llvm/include/llvm/ADT/DenseMap.h | 4 ++--
llvm/include/llvm/ADT/SmallPtrSet.h | 2 +-
llvm/include/llvm/ADT/SmallVector.h | 6 +++---
llvm/include/llvm/Support/ConvertUTF.h | 2 +-
llvm/include/llvm/Support/MathExtras.h | 20 ++++++++++----------
4 files changed, 16 insertions(+), 16 deletions(-)
5 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index 7ccc9445c0a7b882b424b2431858ea596d0eb58f..c4764fffa845a7f9eb69f262aa0ee728d08b1655 100644
index f0f992f8eac389e36156e369ea24e0387bdf0057..4c852d2b142b4a3de76a1ce4049822cc449287f7 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -432,7 +432,7 @@ protected:
@@ -400,7 +400,7 @@ protected:
return 0;
// +1 is required because of the strict equality.
// For example if NumEntries is 48, we need to return 401.
@@ -23,7 +24,7 @@ index 7ccc9445c0a7b882b424b2431858ea596d0eb58f..c4764fffa845a7f9eb69f262aa0ee728
}
void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) {
@@ -868,7 +868,7 @@ public:
@@ -837,7 +837,7 @@ public:
// Reduce the number of buckets.
unsigned NewNumBuckets = 0;
if (OldNumEntries)
@@ -32,11 +33,24 @@ index 7ccc9445c0a7b882b424b2431858ea596d0eb58f..c4764fffa845a7f9eb69f262aa0ee728
if (NewNumBuckets == NumBuckets) {
this->BaseT::initEmpty();
return;
diff --git a/llvm/include/llvm/ADT/SmallPtrSet.h b/llvm/include/llvm/ADT/SmallPtrSet.h
index cf6abc9129b40eed6749213eb23439ec91621005..9115fc74363a9cccd0579427d88fa9edf5baae1b 100644
--- a/llvm/include/llvm/ADT/SmallPtrSet.h
+++ b/llvm/include/llvm/ADT/SmallPtrSet.h
@@ -126,7 +126,7 @@ public:
size_type NewSize = NumEntries + (NumEntries / 3);
NewSize = 1 << (Log2_32_Ceil(NewSize) + 1);
// Like insert_imp_big, always allocate at least 128 elements.
- NewSize = std::max(128u, NewSize);
+ NewSize = (std::max)(128u, NewSize);
Grow(NewSize);
}
diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
index 94d8da059f4f8bad50039b0d0b7993396707829c..85bf5172e419b1b58f53d3cf00d4aabb58877c33 100644
index be06bb817e24e723265f9a8038d94123de1fc53c..2232b741d5359a129adb0e5b3f0f70110c38e90d 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/include/llvm/ADT/SmallVector.h
@@ -56,7 +56,7 @@ protected:
@@ -55,7 +55,7 @@ protected:
/// The maximum value of the Size_T used.
static constexpr size_t SizeTypeMax() {
@@ -45,7 +59,7 @@ index 94d8da059f4f8bad50039b0d0b7993396707829c..85bf5172e419b1b58f53d3cf00d4aabb
}
SmallVectorBase() = delete;
@@ -290,7 +290,7 @@ public:
@@ -276,7 +276,7 @@ public:
size_type size_in_bytes() const { return size() * sizeof(T); }
size_type max_size() const {
@@ -54,7 +68,7 @@ index 94d8da059f4f8bad50039b0d0b7993396707829c..85bf5172e419b1b58f53d3cf00d4aabb
}
size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
@@ -722,7 +722,7 @@ public:
@@ -708,7 +708,7 @@ public:
}
// Assign over existing elements.
@@ -77,10 +91,10 @@ index 5c0e3009c25446a34882fb98329b1d955231bb39..72321022beb373945f7935ed72944fd6
/* Some fundamental constants */
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index e568e42afcf4d20dba137346953ff4be9d27ffc7..d9de2e92d5b07bce1d02ffcfda614b9079d2df91 100644
index 5a6f51adc07f3976bdf8f3412bdb119b220a0e9b..5db59bb848024fca622b2919efd773d185a93f1e 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -338,26 +338,26 @@ template <> constexpr size_t CTLog2<1>() { return 0; }
@@ -339,26 +339,26 @@ template <> constexpr size_t CTLog2<1>() { return 0; }
/// (32 bit edition.)
/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
inline unsigned Log2_32(uint32_t Value) {
@@ -111,7 +125,7 @@ index e568e42afcf4d20dba137346953ff4be9d27ffc7..d9de2e92d5b07bce1d02ffcfda614b90
}
/// A and B are either alignments or offsets. Return the minimum alignment that
@@ -417,7 +417,7 @@ constexpr uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) {
@@ -418,7 +418,7 @@ constexpr uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) {
// happens only when Numerator = INT_MIN and Denominator = -1.
template <typename U, typename V>
constexpr bool divideSignedWouldOverflow(U Numerator, V Denominator) {
@@ -120,7 +134,7 @@ index e568e42afcf4d20dba137346953ff4be9d27ffc7..d9de2e92d5b07bce1d02ffcfda614b90
}
/// Returns the integer ceil(Numerator / Denominator). Signed version.
@@ -605,7 +605,7 @@ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
@@ -614,7 +614,7 @@ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
T Z = X + Y;
Overflowed = (Z < X || Z < Y);
if (Overflowed)
@@ -129,7 +143,7 @@ index e568e42afcf4d20dba137346953ff4be9d27ffc7..d9de2e92d5b07bce1d02ffcfda614b90
else
return Z;
}
@@ -618,7 +618,7 @@ std::enable_if_t<std::is_unsigned_v<T>, T> SaturatingAdd(T X, T Y, T Z,
@@ -627,7 +627,7 @@ std::enable_if_t<std::is_unsigned_v<T>, T> SaturatingAdd(T X, T Y, T Z,
bool Overflowed = false;
T XY = SaturatingAdd(X, Y, &Overflowed);
if (Overflowed)
@@ -138,7 +152,7 @@ index e568e42afcf4d20dba137346953ff4be9d27ffc7..d9de2e92d5b07bce1d02ffcfda614b90
return SaturatingAdd(XY, Z, Args...);
}
@@ -642,7 +642,7 @@ SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
@@ -651,7 +651,7 @@ SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
// Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z
// will necessarily be less than Log2Max as desired.
int Log2Z = Log2_64(X) + Log2_64(Y);
@@ -147,7 +161,7 @@ index e568e42afcf4d20dba137346953ff4be9d27ffc7..d9de2e92d5b07bce1d02ffcfda614b90
int Log2Max = Log2_64(Max);
if (Log2Z < Log2Max) {
return X * Y;
@@ -764,9 +764,9 @@ std::enable_if_t<std::is_signed_v<T>, T> MulOverflow(T X, T Y, T &Result) {
@@ -773,9 +773,9 @@ std::enable_if_t<std::is_signed_v<T>, T> MulOverflow(T X, T Y, T &Result) {
// Check how the max allowed absolute value (2^n for negative, 2^(n-1) for
// positive) divided by an argument compares to the other.
if (IsNegative)

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sat, 7 May 2022 22:13:55 -0400
Subject: [PATCH 03/37] Change unique_function storage size
Subject: [PATCH 03/36] Change unique_function storage size
---
llvm/include/llvm/ADT/FunctionExtras.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h
index 49e0e8ab0db400d0a362746342099578257b2eea..3ce85530b718666afa1dafbf60699c1add423ea6 100644
index d92868e3715f40e1c2c305a784afc55726e3a812..df7fe3e19462ebecd30f7a9d006027c75751de5b 100644
--- a/llvm/include/llvm/ADT/FunctionExtras.h
+++ b/llvm/include/llvm/ADT/FunctionExtras.h
@@ -79,7 +79,7 @@ using EnableIfCallable = std::enable_if_t<std::disjunction<
@@ -17,10 +17,10 @@ index 49e0e8ab0db400d0a362746342099578257b2eea..3ce85530b718666afa1dafbf60699c1a
protected:
- static constexpr size_t InlineStorageSize = sizeof(void *) * 3;
+ static constexpr size_t InlineStorageSize = sizeof(void *) * 4;
static constexpr size_t InlineStorageAlign = alignof(void *);
template <typename T, class = void>
struct IsSizeLessThanThresholdT : std::false_type {};
@@ -158,7 +158,7 @@ protected:
@@ -159,7 +159,7 @@ protected:
"Should always use all of the out-of-line storage for inline storage!");
// For in-line storage, we just provide an aligned character buffer. We
@@ -28,4 +28,4 @@ index 49e0e8ab0db400d0a362746342099578257b2eea..3ce85530b718666afa1dafbf60699c1a
+ // provide four pointers worth of storage here.
// This is mutable as an inlined `const unique_function<void() const>` may
// still modify its own mutable members.
alignas(void *) mutable std::byte InlineStorage[InlineStorageSize];
alignas(InlineStorageAlign) mutable std::byte

View File

@@ -1,21 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sat, 7 May 2022 22:17:19 -0400
Subject: [PATCH 04/37] Threading updates
Subject: [PATCH 04/36] Threading updates
- Remove guards for threads and exception
- Prefer scope gaurd over lock gaurd
---
llvm/include/llvm/Support/Compiler.h | 6 -----
llvm/lib/Support/ErrorHandling.cpp | 38 +++++-----------------------
llvm/lib/Support/ManagedStatic.cpp | 10 ++++----
3 files changed, 11 insertions(+), 43 deletions(-)
llvm/lib/Support/ErrorHandling.cpp | 39 +++++-----------------------
llvm/lib/Support/ManagedStatic.cpp | 10 +++----
3 files changed, 11 insertions(+), 44 deletions(-)
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index 7710bd9a08148289b5ba3b1f2dae5cccc4f26d4d..2a6accec1e74c9869d724c7733cc75ab6af9dc8d 100644
index 021d1d29368deb330418ff4e08fbf3931e4b7453..586242b53bbf4ceb9bad5c9c8b495f83cb088cda 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -563,7 +563,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
@@ -648,7 +648,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
/// initialize to some constant value. In almost all circumstances this is most
/// appropriate for use with a pointer, integer, or small aggregation of
/// pointers and integers.
@@ -23,7 +23,7 @@ index 7710bd9a08148289b5ba3b1f2dae5cccc4f26d4d..2a6accec1e74c9869d724c7733cc75ab
#if __has_feature(cxx_thread_local) || defined(_MSC_VER)
#define LLVM_THREAD_LOCAL thread_local
#else
@@ -571,11 +570,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
@@ -656,11 +655,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
// we only need the restricted functionality that provides.
#define LLVM_THREAD_LOCAL __thread
#endif
@@ -36,10 +36,18 @@ index 7710bd9a08148289b5ba3b1f2dae5cccc4f26d4d..2a6accec1e74c9869d724c7733cc75ab
/// \macro LLVM_ENABLE_EXCEPTIONS
/// Whether LLVM is built with exception support.
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index 561509e0efdf15f6e534f0621a5964d92511114c..89829dc4faff0b2667ded462444e0eaeec53fd01 100644
index d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780ca021bf2 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -44,7 +44,6 @@ static void *ErrorHandlerUserData = nullptr;
@@ -15,7 +15,6 @@
#include "llvm-c/ErrorHandling.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Config/config.h"
-#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
#include "llvm/Support/Debug.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
@@ -45,7 +44,6 @@ static void *ErrorHandlerUserData = nullptr;
static fatal_error_handler_t BadAllocErrorHandler = nullptr;
static void *BadAllocErrorHandlerUserData = nullptr;
@@ -47,7 +55,7 @@ index 561509e0efdf15f6e534f0621a5964d92511114c..89829dc4faff0b2667ded462444e0eae
// Mutexes to synchronize installing error handlers and calling error handlers.
// Do not use ManagedStatic, or that may allocate memory while attempting to
// report an OOM.
@@ -58,22 +57,17 @@ static void *BadAllocErrorHandlerUserData = nullptr;
@@ -59,22 +57,17 @@ static void *BadAllocErrorHandlerUserData = nullptr;
// builds. We can remove these ifdefs if that script goes away.
static std::mutex ErrorHandlerMutex;
static std::mutex BadAllocErrorHandlerMutex;
@@ -72,7 +80,7 @@ index 561509e0efdf15f6e534f0621a5964d92511114c..89829dc4faff0b2667ded462444e0eae
ErrorHandler = nullptr;
ErrorHandlerUserData = nullptr;
}
@@ -92,9 +86,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {
@@ -93,9 +86,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {
{
// Only acquire the mutex while reading the handler, so as not to invoke a
// user-supplied callback under a lock.
@@ -83,7 +91,7 @@ index 561509e0efdf15f6e534f0621a5964d92511114c..89829dc4faff0b2667ded462444e0eae
handler = ErrorHandler;
handlerData = ErrorHandlerUserData;
}
@@ -126,9 +118,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {
@@ -127,9 +118,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {
void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler,
void *user_data) {
@@ -94,7 +102,7 @@ index 561509e0efdf15f6e534f0621a5964d92511114c..89829dc4faff0b2667ded462444e0eae
assert(!BadAllocErrorHandler &&
"Bad alloc error handler already registered!\n");
BadAllocErrorHandler = handler;
@@ -136,9 +126,7 @@ void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler,
@@ -137,9 +126,7 @@ void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler,
}
void llvm::remove_bad_alloc_error_handler() {
@@ -105,7 +113,7 @@ index 561509e0efdf15f6e534f0621a5964d92511114c..89829dc4faff0b2667ded462444e0eae
BadAllocErrorHandler = nullptr;
BadAllocErrorHandlerUserData = nullptr;
}
@@ -149,9 +137,7 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
@@ -150,9 +137,7 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
{
// Only acquire the mutex while reading the handler, so as not to invoke a
// user-supplied callback under a lock.
@@ -116,7 +124,7 @@ index 561509e0efdf15f6e534f0621a5964d92511114c..89829dc4faff0b2667ded462444e0eae
Handler = BadAllocErrorHandler;
HandlerData = BadAllocErrorHandlerUserData;
}
@@ -161,10 +147,6 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
@@ -162,10 +147,6 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
llvm_unreachable("bad alloc handler should not return");
}
@@ -127,7 +135,7 @@ index 561509e0efdf15f6e534f0621a5964d92511114c..89829dc4faff0b2667ded462444e0eae
// Don't call the normal error handler. It may allocate memory. Directly write
// an OOM to stderr and abort.
const char *OOMMessage = "LLVM ERROR: out of memory\n";
@@ -173,15 +155,8 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
@@ -174,15 +155,8 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
(void)!::write(2, Reason, strlen(Reason));
(void)!::write(2, Newline, strlen(Newline));
abort();
@@ -143,7 +151,7 @@ index 561509e0efdf15f6e534f0621a5964d92511114c..89829dc4faff0b2667ded462444e0eae
// Causes crash on allocation failure. It is called prior to the handler set by
// 'install_bad_alloc_error_handler'.
static void out_of_memory_new_handler() {
@@ -196,7 +171,6 @@ void llvm::install_out_of_memory_new_handler() {
@@ -197,7 +171,6 @@ void llvm::install_out_of_memory_new_handler() {
assert((old == nullptr || old == out_of_memory_new_handler) &&
"new-handler already installed");
}

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sat, 7 May 2022 22:28:13 -0400
Subject: [PATCH 05/37] \#ifdef guard safety
Subject: [PATCH 05/36] \#ifdef guard safety
Prevents redefinition if someone is pulling in real LLVM, since the macros are in global namespace
---
@@ -9,10 +9,10 @@ Prevents redefinition if someone is pulling in real LLVM, since the macros are i
1 file changed, 42 insertions(+)
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28998bcbe9 100644
index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48c55b18eb 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -90,6 +90,7 @@
@@ -86,6 +86,7 @@
/// * 1928: VS2019, version 16.8 + 16.9
/// * 1929: VS2019, version 16.10 + 16.11
/// * 1930: VS2022, version 17.0
@@ -20,7 +20,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#ifdef _MSC_VER
#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
@@ -103,6 +104,7 @@
@@ -99,6 +100,7 @@
#else
#define LLVM_MSC_PREREQ(version) 0
#endif
@@ -28,8 +28,8 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
/// into a shared library, then the class should be private to the library and
@@ -139,17 +141,21 @@
#define LLVM_EXTERNAL_VISIBILITY
@@ -218,17 +220,21 @@
#define LLVM_C_ABI LLVM_ABI
#endif
+#ifndef LLVM_PREFETCH
@@ -50,7 +50,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if defined(__clang__)
#define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX)))
@@ -197,11 +203,13 @@
@@ -276,11 +282,13 @@
// more portable solution:
// (void)unused_var_name;
// Prefer cast-to-void wherever it is sufficient.
@@ -64,7 +64,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
// FIXME: Provide this for PE/COFF targets.
#if __has_attribute(weak) && !defined(__MINGW32__) && !defined(__CYGWIN__) && \
@@ -211,6 +219,7 @@
@@ -290,6 +298,7 @@
#define LLVM_ATTRIBUTE_WEAK
#endif
@@ -72,7 +72,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
// Prior to clang 3.2, clang did not accept any spelling of
// __has_attribute(const), so assume it is supported.
#if defined(__clang__) || defined(__GNUC__)
@@ -219,13 +228,16 @@
@@ -298,13 +307,16 @@
#else
#define LLVM_READNONE
#endif
@@ -89,7 +89,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if __has_attribute(minsize)
#define LLVM_ATTRIBUTE_MINSIZE __attribute__((minsize))
@@ -233,6 +245,7 @@
@@ -312,6 +324,7 @@
#define LLVM_ATTRIBUTE_MINSIZE
#endif
@@ -97,7 +97,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if __has_builtin(__builtin_expect) || defined(__GNUC__)
#define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
#define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
@@ -240,9 +253,11 @@
@@ -319,9 +332,11 @@
#define LLVM_LIKELY(EXPR) (EXPR)
#define LLVM_UNLIKELY(EXPR) (EXPR)
#endif
@@ -109,7 +109,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if __has_attribute(noinline)
#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER)
@@ -250,9 +265,11 @@
@@ -329,9 +344,11 @@
#else
#define LLVM_ATTRIBUTE_NOINLINE
#endif
@@ -121,7 +121,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if __has_attribute(always_inline)
#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
#elif defined(_MSC_VER)
@@ -260,6 +277,7 @@
@@ -339,6 +356,7 @@
#else
#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline
#endif
@@ -129,7 +129,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
/// LLVM_ATTRIBUTE_NO_DEBUG - On compilers where we have a directive to do
/// so, mark a method "no debug" because debug info makes the debugger
@@ -270,6 +288,7 @@
@@ -349,6 +367,7 @@
#define LLVM_ATTRIBUTE_NODEBUG
#endif
@@ -137,7 +137,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if __has_attribute(returns_nonnull)
#define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
#elif defined(_MSC_VER)
@@ -277,6 +296,7 @@
@@ -356,6 +375,7 @@
#else
#define LLVM_ATTRIBUTE_RETURNS_NONNULL
#endif
@@ -145,7 +145,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
/// LLVM_ATTRIBUTE_RESTRICT - Annotates a pointer to tell the compiler that
/// it is not aliased in the current scope.
@@ -288,6 +308,7 @@
@@ -367,6 +387,7 @@
/// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a
/// pointer that does not alias any other valid pointer.
@@ -153,7 +153,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#ifdef __GNUC__
#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
#elif defined(_MSC_VER)
@@ -295,8 +316,10 @@
@@ -374,8 +395,10 @@
#else
#define LLVM_ATTRIBUTE_RETURNS_NOALIAS
#endif
@@ -164,7 +164,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough)
#define LLVM_FALLTHROUGH [[fallthrough]]
#elif LLVM_HAS_CPP_ATTRIBUTE(gnu::fallthrough)
@@ -308,6 +331,7 @@
@@ -387,6 +410,7 @@
#else
#define LLVM_FALLTHROUGH
#endif
@@ -172,7 +172,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
/// LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that
/// they are constant initialized.
@@ -342,11 +366,13 @@
@@ -427,11 +451,13 @@
/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
/// pedantic diagnostics.
@@ -186,7 +186,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
/// to an expression which states that it is undefined behavior for the
@@ -355,14 +381,17 @@
@@ -440,14 +466,17 @@
/// '#else' is intentionally left out so that other macro logic (e.g.,
/// LLVM_ASSUME_ALIGNED and llvm_unreachable()) can detect whether
/// LLVM_BUILTIN_UNREACHABLE has a definition.
@@ -204,7 +204,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if __has_builtin(__builtin_trap) || defined(__GNUC__)
# define LLVM_BUILTIN_TRAP __builtin_trap()
#elif defined(_MSC_VER)
@@ -374,10 +403,12 @@
@@ -459,10 +488,12 @@
#else
# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
#endif
@@ -217,7 +217,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if __has_builtin(__builtin_debugtrap)
# define LLVM_BUILTIN_DEBUGTRAP __builtin_debugtrap()
#elif defined(_MSC_VER)
@@ -391,9 +422,11 @@
@@ -476,9 +507,11 @@
// program to abort if encountered.
# define LLVM_BUILTIN_DEBUGTRAP
#endif
@@ -229,7 +229,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if __has_builtin(__builtin_assume_aligned) || defined(__GNUC__)
# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
#elif defined(LLVM_BUILTIN_UNREACHABLE)
@@ -402,6 +435,7 @@
@@ -487,6 +520,7 @@
#else
# define LLVM_ASSUME_ALIGNED(p, a) (p)
#endif
@@ -237,7 +237,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
/// \macro LLVM_PACKED
/// Used to specify a packed structure.
@@ -421,6 +455,7 @@
@@ -506,6 +540,7 @@
/// long long l;
/// };
/// LLVM_PACKED_END
@@ -245,7 +245,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#ifdef _MSC_VER
# define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop))
# define LLVM_PACKED_START __pragma(pack(push, 1))
@@ -430,6 +465,7 @@
@@ -515,6 +550,7 @@
# define LLVM_PACKED_START _Pragma("pack(push, 1)")
# define LLVM_PACKED_END _Pragma("pack(pop)")
#endif
@@ -253,7 +253,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
/// \macro LLVM_MEMORY_SANITIZER_BUILD
/// Whether LLVM itself is built with MemorySanitizer instrumentation.
@@ -521,11 +557,13 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
@@ -606,11 +642,13 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
/// \macro LLVM_NO_SANITIZE
/// Disable a particular sanitizer for a function.
@@ -267,7 +267,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
/// Mark debug helper function definitions like dump() that should not be
/// stripped from debug builds.
@@ -533,17 +571,20 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
@@ -618,17 +656,20 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
/// `#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)` so they do always
/// get stripped in release builds.
// FIXME: Move this to a private config.h as it's not usable in public headers.
@@ -288,7 +288,7 @@ index 2a6accec1e74c9869d724c7733cc75ab6af9dc8d..cb99bf5efe87d98fd73108c189182a28
#if defined(_MSC_VER)
#define LLVM_PRETTY_FUNCTION __FUNCSIG__
#elif defined(__GNUC__) || defined(__clang__)
@@ -551,6 +592,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
@@ -636,6 +677,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
#else
#define LLVM_PRETTY_FUNCTION __func__
#endif

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sat, 7 May 2022 22:37:34 -0400
Subject: [PATCH 06/37] Explicitly use std::
Subject: [PATCH 06/36] Explicitly use std::
---
llvm/include/llvm/ADT/SmallSet.h | 2 +-
@@ -11,10 +11,10 @@ Subject: [PATCH 06/37] Explicitly use std::
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/ADT/SmallSet.h b/llvm/include/llvm/ADT/SmallSet.h
index aeee5f97799aea7e7588d7afba1e47b4fa3d8c7b..4969dfb0d61c2fad805c9cb7bc0184ea6d47bf23 100644
index ed3c6bfd3418d70a92eb602d0eb3e5d88da2a095..c62a3a55d9bda188670e7d6042867943dcd44c68 100644
--- a/llvm/include/llvm/ADT/SmallSet.h
+++ b/llvm/include/llvm/ADT/SmallSet.h
@@ -269,7 +269,7 @@ bool operator==(const SmallSet<T, LN, C> &LHS, const SmallSet<T, RN, C> &RHS) {
@@ -280,7 +280,7 @@ bool operator==(const SmallSet<T, LN, C> &LHS, const SmallSet<T, RN, C> &RHS) {
return false;
// All elements in LHS must also be in RHS
@@ -24,7 +24,7 @@ index aeee5f97799aea7e7588d7afba1e47b4fa3d8c7b..4969dfb0d61c2fad805c9cb7bc0184ea
/// Inequality comparison for SmallSet.
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index 89829dc4faff0b2667ded462444e0eaeec53fd01..ea8d60426ead7163550b73e0fdc32cb11bb089cb 100644
index 4e1dca80a21881bfb8fa886a5921c780ca021bf2..4de36d969b3776b72ff85888355b64f7f3262ccc 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -249,7 +249,7 @@ std::error_code llvm::mapLastWindowsError() {
@@ -37,10 +37,10 @@ index 89829dc4faff0b2667ded462444e0eaeec53fd01..ea8d60426ead7163550b73e0fdc32cb1
std::error_code llvm::mapWindowsError(unsigned EV) {
switch (EV) {
diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp
index a39b11b9f82156a78b9ad7ce7b8c28855829e611..a6c2b329f072639706aa221feb8c08e33533f813 100644
index 88be2b68915573a3b3a343ff53a84d86604d7bfd..65c0c564e91a40a98432d985c6949d3d4aa0717d 100644
--- a/llvm/unittests/ADT/SmallPtrSetTest.cpp
+++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp
@@ -259,7 +259,7 @@ TEST(SmallPtrSetTest, dereferenceAndIterate) {
@@ -261,7 +261,7 @@ TEST(SmallPtrSetTest, dereferenceAndIterate) {
// Sort. We should hit the first element just once and the final element N
// times.
@@ -50,20 +50,21 @@ index a39b11b9f82156a78b9ad7ce7b8c28855829e611..a6c2b329f072639706aa221feb8c08e3
EXPECT_EQ(F - Found + 1, *F);
}
diff --git a/llvm/unittests/ADT/SmallSetTest.cpp b/llvm/unittests/ADT/SmallSetTest.cpp
index b50b368ae663614f050c220432c05b32c201db00..f9d84fa8a42a7feaaffa3aa080e84574dc3671b3 100644
index 2feb0b1feb421bf734e6433ccce3d94dd2b0aeca..65d5998c63d9d7dd69c5a7054bcd82c4ce5d725f 100644
--- a/llvm/unittests/ADT/SmallSetTest.cpp
+++ b/llvm/unittests/ADT/SmallSetTest.cpp
@@ -11,8 +11,8 @@
@@ -11,9 +11,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/STLExtras.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include <algorithm>
#include <string>
using namespace llvm;
@@ -94,7 +94,7 @@ TEST(SmallSetTest, IteratorInt) {
@@ -180,7 +180,7 @@ TEST(SmallSetTest, IteratorInt) {
std::vector<int> V(s1.begin(), s1.end());
// Make sure the elements are in the expected order.
@@ -72,7 +73,7 @@ index b50b368ae663614f050c220432c05b32c201db00..f9d84fa8a42a7feaaffa3aa080e84574
for (int i = 0; i < 3; i++)
EXPECT_EQ(i, V[i]);
@@ -105,7 +105,7 @@ TEST(SmallSetTest, IteratorInt) {
@@ -191,7 +191,7 @@ TEST(SmallSetTest, IteratorInt) {
V.assign(s1.begin(), s1.end());
// Make sure the elements are in the expected order.
@@ -81,7 +82,7 @@ index b50b368ae663614f050c220432c05b32c201db00..f9d84fa8a42a7feaaffa3aa080e84574
for (int i = 0; i < 6; i++)
EXPECT_EQ(i, V[i]);
}
@@ -120,7 +120,7 @@ TEST(SmallSetTest, IteratorString) {
@@ -206,7 +206,7 @@ TEST(SmallSetTest, IteratorString) {
s1.insert("str 1");
std::vector<std::string> V(s1.begin(), s1.end());
@@ -90,7 +91,7 @@ index b50b368ae663614f050c220432c05b32c201db00..f9d84fa8a42a7feaaffa3aa080e84574
EXPECT_EQ(2u, s1.size());
EXPECT_EQ("str 1", V[0]);
EXPECT_EQ("str 2", V[1]);
@@ -131,7 +131,7 @@ TEST(SmallSetTest, IteratorString) {
@@ -217,7 +217,7 @@ TEST(SmallSetTest, IteratorString) {
V.assign(s1.begin(), s1.end());
// Make sure the elements are in the expected order.

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sat, 7 May 2022 22:53:50 -0400
Subject: [PATCH 07/37] Remove format_provider
Subject: [PATCH 07/36] Remove format_provider
---
llvm/include/llvm/Support/Chrono.h | 114 ------------------------
@@ -142,7 +142,7 @@ index 9c9ba7002310eba5113c14957f769702c61f4326..b269ff8bb5db7bb3c62c3a87daf255b1
#endif // LLVM_SUPPORT_CHRONO_H
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index 18bdf4b7d3b96d42d93ca1e4800233b34be42a78..6c2eedf99d003a29243fbb2a9a280fe12dd49d8a 100644
index c43c68c9114d8cd564484b190456b0069818dc87..96b7a2463e2336a0f61a03ce11cf643bc253f422 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -27,12 +27,6 @@
@@ -159,7 +159,7 @@ index 18bdf4b7d3b96d42d93ca1e4800233b34be42a78..6c2eedf99d003a29243fbb2a9a280fe1
namespace sys {
diff --git a/llvm/unittests/Support/Chrono.cpp b/llvm/unittests/Support/Chrono.cpp
index 7dfc5dd2c29348ea8df9ce87c80f357aaad1a73b..a4d166d435d6d679f773dcf3eab985f0631e12d2 100644
index 3e3e5517a0aedbd72605adbdde932a5e5e92693b..a4d166d435d6d679f773dcf3eab985f0631e12d2 100644
--- a/llvm/unittests/Support/Chrono.cpp
+++ b/llvm/unittests/Support/Chrono.cpp
@@ -29,43 +29,6 @@ TEST(Chrono, TimeTConversion) {
@@ -185,10 +185,10 @@ index 7dfc5dd2c29348ea8df9ce87c80f357aaad1a73b..a4d166d435d6d679f773dcf3eab985f0
- std::string S;
- raw_string_ostream OS(S);
- OS << T;
- EXPECT_EQ("2006-01-02 15:04:05.123456789", OS.str());
- EXPECT_EQ("2006-01-02 15:04:05.123456789", S);
- S.clear();
- OS << T2;
- EXPECT_EQ("2006-01-02 15:04:05.023456789", OS.str());
- EXPECT_EQ("2006-01-02 15:04:05.023456789", S);
-
- // formatv default style matches operator<<.
- EXPECT_EQ("2006-01-02 15:04:05.123456789", formatv("{0}", T).str());

View File

@@ -1,23 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sun, 8 May 2022 13:34:07 -0400
Subject: [PATCH 08/37] Add compiler warning pragmas
Subject: [PATCH 08/36] Add compiler warning pragmas
---
llvm/include/llvm/ADT/FunctionExtras.h | 11 +++++++++++
llvm/include/llvm/ADT/Hashing.h | 9 +++++++++
llvm/include/llvm/ADT/SmallVector.h | 8 ++++++++
llvm/include/llvm/Support/MathExtras.h | 9 +++++++++
llvm/include/llvm/Support/MemAlloc.h | 13 +++++++++++++
llvm/lib/Support/raw_ostream.cpp | 4 ++++
llvm/unittests/ADT/DenseMapTest.cpp | 4 ++++
llvm/unittests/ADT/MapVectorTest.cpp | 7 +++++++
llvm/unittests/ADT/SmallVectorTest.cpp | 4 ++++
llvm/unittests/Support/AlignOfTest.cpp | 7 +++----
10 files changed, 72 insertions(+), 4 deletions(-)
llvm/include/llvm/ADT/FunctionExtras.h | 11 +++++++++++
llvm/include/llvm/ADT/SmallVector.h | 8 ++++++++
llvm/include/llvm/Support/MathExtras.h | 9 +++++++++
llvm/include/llvm/Support/MemAlloc.h | 13 +++++++++++++
llvm/lib/Support/raw_ostream.cpp | 4 ++++
llvm/unittests/ADT/DenseMapTest.cpp | 4 ++++
llvm/unittests/ADT/FunctionExtrasTest.cpp | 6 ++++++
llvm/unittests/ADT/SmallVectorTest.cpp | 4 ++++
llvm/unittests/Support/AlignOfTest.cpp | 7 +++----
9 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h
index 3ce85530b718666afa1dafbf60699c1add423ea6..da61b606eb44bdbdeb4674c9c7eab9f691124f9c 100644
index df7fe3e19462ebecd30f7a9d006027c75751de5b..28a9ba756a4075987fbee28c6ed6387e99dfd14b 100644
--- a/llvm/include/llvm/ADT/FunctionExtras.h
+++ b/llvm/include/llvm/ADT/FunctionExtras.h
@@ -56,6 +56,13 @@ namespace llvm {
@@ -34,7 +33,7 @@ index 3ce85530b718666afa1dafbf60699c1add423ea6..da61b606eb44bdbdeb4674c9c7eab9f6
namespace detail {
template <typename T>
@@ -411,6 +418,10 @@ public:
@@ -414,6 +421,10 @@ public:
}
};
@@ -45,33 +44,8 @@ index 3ce85530b718666afa1dafbf60699c1add423ea6..da61b606eb44bdbdeb4674c9c7eab9f6
} // end namespace llvm
#endif // LLVM_ADT_FUNCTIONEXTRAS_H
diff --git a/llvm/include/llvm/ADT/Hashing.h b/llvm/include/llvm/ADT/Hashing.h
index 109966257b51c015754f6410aec5fa9b8de435ae..a33c6eec308c8722f88b09f73f954d39558c3d62 100644
--- a/llvm/include/llvm/ADT/Hashing.h
+++ b/llvm/include/llvm/ADT/Hashing.h
@@ -57,6 +57,11 @@
#include <tuple>
#include <utility>
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable : 26495)
+#endif
+
namespace llvm {
template <typename T, typename Enable> struct DenseMapInfo;
@@ -677,4 +682,8 @@ struct hash<llvm::hash_code> {
} // namespace std;
+#ifdef _WIN32
+#pragma warning(pop)
+#endif
+
#endif
diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
index 85bf5172e419b1b58f53d3cf00d4aabb58877c33..ec340afd4519f4070389434006bf7f2afdbf2993 100644
index 2232b741d5359a129adb0e5b3f0f70110c38e90d..3cab284f5b6105956d6fff49a27d37482a3c321d 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/include/llvm/ADT/SmallVector.h
@@ -14,6 +14,14 @@
@@ -87,13 +61,13 @@ index 85bf5172e419b1b58f53d3cf00d4aabb58877c33..ec340afd4519f4070389434006bf7f2a
+#endif
+
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cassert>
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index d9de2e92d5b07bce1d02ffcfda614b9079d2df91..6028ba8ead7627b4821aa8642f5069b305605c5e 100644
index 5db59bb848024fca622b2919efd773d185a93f1e..b2c62d833038f92d2621ca2e6838d0d6b3b48760 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -231,6 +231,11 @@ inline uint64_t maxUIntN(uint64_t N) {
@@ -232,6 +232,11 @@ inline uint64_t maxUIntN(uint64_t N) {
return UINT64_MAX >> (64 - N);
}
@@ -105,7 +79,7 @@ index d9de2e92d5b07bce1d02ffcfda614b9079d2df91..6028ba8ead7627b4821aa8642f5069b3
/// Gets the minimum value for a N-bit signed integer.
inline int64_t minIntN(int64_t N) {
assert(N <= 64 && "integer width out of range");
@@ -240,6 +245,10 @@ inline int64_t minIntN(int64_t N) {
@@ -241,6 +246,10 @@ inline int64_t minIntN(int64_t N) {
return UINT64_C(1) + ~(UINT64_C(1) << (N - 1));
}
@@ -146,7 +120,7 @@ index f3f378b7697a18f57b189c5322b080fe23d45bec..0028e871f6a05baf6172c60c602b8b26
+
#endif
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 2dbb0674406e1860fdd0c266df64003e45b12fa3..e248eb67df9144bb4cf14e3d3acab161a95d1ce3 100644
index 681b6fdc95eb4fda4f23d0b381b83417d82b3b78..a75abb7a4abf71e214ea6342352cfbaa5ce3ea27 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -10,6 +10,10 @@
@@ -175,24 +149,23 @@ index e93e18423507655ce8275a0718d8e5d01915985f..b930a21f8b43b64835436fcd27f4802a
#include "llvm/ADT/DenseMap.h"
#include "CountCopyAndMove.h"
#include "llvm/ADT/DenseMapInfo.h"
diff --git a/llvm/unittests/ADT/MapVectorTest.cpp b/llvm/unittests/ADT/MapVectorTest.cpp
index e0f11b60a0223da7c00a47c20b61136bd608bae6..9c802ab30721c9ce58ed65052a6ab467039226ff 100644
--- a/llvm/unittests/ADT/MapVectorTest.cpp
+++ b/llvm/unittests/ADT/MapVectorTest.cpp
@@ -6,6 +6,13 @@
//
//===----------------------------------------------------------------------===//
diff --git a/llvm/unittests/ADT/FunctionExtrasTest.cpp b/llvm/unittests/ADT/FunctionExtrasTest.cpp
index 777c5784949fd3c07bbbcef8dc3fc8e5764896a9..3777eedff54639f0380218eaad767f27f1958a67 100644
--- a/llvm/unittests/ADT/FunctionExtrasTest.cpp
+++ b/llvm/unittests/ADT/FunctionExtrasTest.cpp
@@ -330,6 +330,12 @@ TEST(UniqueFunctionTest, InlineStorageWorks) {
UniqueFunctionWithInlineStorage(&UniqueFunctionWithInlineStorage);
}
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wpedantic"
+#if !defined(__clang__)
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+#endif
+
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/iterator_range.h"
#include "gtest/gtest.h"
+// GCC warns that val in CountCopyAndMove is uninitialized
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#endif
// Check that the moved-from captured state is properly destroyed during
// move construction/assignment.
TEST(UniqueFunctionTest, MovedFromStateIsDestroyedCorrectly) {
diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp
index 7029038d18d433cef987bedbfa4fda269b24fb8f..f8c37820ef9fdfe0af067f5aa8d2297ed15e73bc 100644
--- a/llvm/unittests/ADT/SmallVectorTest.cpp

View File

@@ -1,15 +1,15 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sun, 8 May 2022 13:43:50 -0400
Subject: [PATCH 09/37] Remove unused functions
Subject: [PATCH 09/36] Remove unused functions
---
llvm/include/llvm/ADT/SmallString.h | 77 ------
llvm/include/llvm/Support/Errno.h | 9 -
llvm/include/llvm/Support/VersionTuple.h | 39 ---
llvm/include/llvm/Support/raw_ostream.h | 129 +--------
llvm/include/llvm/Support/raw_ostream.h | 187 +------------
llvm/lib/Support/raw_ostream.cpp | 332 -----------------------
5 files changed, 8 insertions(+), 578 deletions(-)
5 files changed, 8 insertions(+), 636 deletions(-)
diff --git a/llvm/include/llvm/ADT/SmallString.h b/llvm/include/llvm/ADT/SmallString.h
index 9fab1a7726bc6745296f5ebb24aee4055408e5f5..cb6136d8fd1886e8dc444cb807b33a5f1e18aa44 100644
@@ -184,7 +184,7 @@ index e1cdce77ce8659305c99a21e01f9b3cc3481a5fd..9102ff063afedc03bd524b2805cba98e
} // end namespace llvm
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index 6c2eedf99d003a29243fbb2a9a280fe12dd49d8a..cbeb712e2a69426d83457cb1065fff4ca80a669d 100644
index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d74819e794a3c 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -274,32 +274,6 @@ public:
@@ -354,10 +354,68 @@ index 6c2eedf99d003a29243fbb2a9a280fe12dd49d8a..cbeb712e2a69426d83457cb1065fff4c
/// Check if \p OS is a pointer of type raw_fd_stream*.
static bool classof(const raw_ostream *OS);
};
@@ -773,29 +683,6 @@ public:
@@ -773,87 +683,6 @@ public:
~buffer_unique_ostream() override { *OS << str(); }
};
-// Helper struct to add indentation to raw_ostream. Instead of
-// OS.indent(6) << "more stuff";
-// you can use
-// OS << indent(6) << "more stuff";
-// which has better ergonomics (and clang-formats better as well).
-//
-// If indentation is always in increments of a fixed value, you can use Scale
-// to set that value once. So indent(1, 2) will add 2 spaces and
-// indent(1,2) + 1 will add 4 spaces.
-struct indent {
- // Indentation is represented as `NumIndents` steps of size `Scale` each.
- unsigned NumIndents;
- unsigned Scale;
-
- explicit indent(unsigned NumIndents, unsigned Scale = 1)
- : NumIndents(NumIndents), Scale(Scale) {}
-
- // These arithmeric operators preserve scale.
- void operator+=(unsigned N) { NumIndents += N; }
- void operator-=(unsigned N) {
- assert(NumIndents >= N && "Indentation underflow");
- NumIndents -= N;
- }
- indent operator+(unsigned N) const { return indent(NumIndents + N, Scale); }
- indent operator-(unsigned N) const {
- assert(NumIndents >= N && "Indentation undeflow");
- return indent(NumIndents - N, Scale);
- }
- indent &operator++() { // Prefix ++.
- ++NumIndents;
- return *this;
- }
- indent operator++(int) { // Postfix ++.
- indent Old = *this;
- ++NumIndents;
- return Old;
- }
- indent &operator--() { // Prefix --.
- assert(NumIndents >= 1);
- --NumIndents;
- return *this;
- }
- indent operator--(int) { // Postfix --.
- indent Old = *this;
- assert(NumIndents >= 1);
- --NumIndents;
- return Old;
- }
- indent &operator=(unsigned N) {
- NumIndents = N;
- return *this;
- }
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const indent &Indent) {
- return OS.indent(Indent.NumIndents * Indent.Scale);
-}
-
-class Error;
-
-/// This helper creates an output stream and then passes it to \p Write.
@@ -385,7 +443,7 @@ index 6c2eedf99d003a29243fbb2a9a280fe12dd49d8a..cbeb712e2a69426d83457cb1065fff4c
#endif // LLVM_SUPPORT_RAW_OSTREAM_H
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index e248eb67df9144bb4cf14e3d3acab161a95d1ce3..ee9d2b0cda0a4f338e4b089304203f220a5ed1c4 100644
index a75abb7a4abf71e214ea6342352cfbaa5ce3ea27..e06253e8f3a16dc09573cdec74cf54e0e3fcf848 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -19,7 +19,6 @@
@@ -396,7 +454,7 @@ index e248eb67df9144bb4cf14e3d3acab161a95d1ce3..ee9d2b0cda0a4f338e4b089304203f22
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
@@ -128,49 +127,6 @@ void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
@@ -126,49 +125,6 @@ void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
assert(OutBufStart <= OutBufEnd && "Invalid size!");
}
@@ -446,7 +504,7 @@ index e248eb67df9144bb4cf14e3d3acab161a95d1ce3..ee9d2b0cda0a4f338e4b089304203f22
raw_ostream &raw_ostream::write_escaped(std::string_view Str,
bool UseHexEscapes) {
for (unsigned char c : Str) {
@@ -310,173 +266,6 @@ void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
@@ -308,173 +264,6 @@ void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
OutBufCur += Size;
}
@@ -620,7 +678,7 @@ index e248eb67df9144bb4cf14e3d3acab161a95d1ce3..ee9d2b0cda0a4f338e4b089304203f22
template <char C>
static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) {
static const char Chars[] = {C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
@@ -507,63 +296,8 @@ raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) {
@@ -505,63 +294,8 @@ raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) {
return write_padding<'\0'>(*this, NumZeros);
}
@@ -684,7 +742,7 @@ index e248eb67df9144bb4cf14e3d3acab161a95d1ce3..ee9d2b0cda0a4f338e4b089304203f22
//===----------------------------------------------------------------------===//
// raw_fd_ostream
//===----------------------------------------------------------------------===//
@@ -862,31 +596,6 @@ size_t raw_fd_ostream::preferred_buffer_size() const {
@@ -864,31 +598,6 @@ size_t raw_fd_ostream::preferred_buffer_size() const {
#endif
}
@@ -716,7 +774,7 @@ index e248eb67df9144bb4cf14e3d3acab161a95d1ce3..ee9d2b0cda0a4f338e4b089304203f22
void raw_fd_ostream::anchor() {}
//===----------------------------------------------------------------------===//
@@ -937,19 +646,6 @@ raw_fd_stream::raw_fd_stream(std::string_view Filename, std::error_code &EC)
@@ -939,19 +648,6 @@ raw_fd_stream::raw_fd_stream(std::string_view Filename, std::error_code &EC)
EC = std::make_error_code(std::errc::invalid_argument);
}
@@ -736,7 +794,7 @@ index e248eb67df9144bb4cf14e3d3acab161a95d1ce3..ee9d2b0cda0a4f338e4b089304203f22
bool raw_fd_stream::classof(const raw_ostream *OS) {
return OS->get_kind() == OStreamKind::OK_FDStream;
}
@@ -1009,31 +705,3 @@ void raw_pwrite_stream::anchor() {}
@@ -1011,31 +707,3 @@ void raw_pwrite_stream::anchor() {}
void buffer_ostream::anchor() {}
void buffer_unique_ostream::anchor() {}

View File

@@ -1,18 +1,18 @@
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/37] Detemplatize SmallVectorBase
Subject: [PATCH 10/36] Detemplatize SmallVectorBase
---
llvm/include/llvm/ADT/SmallVector.h | 35 ++++++++++-----------------
llvm/lib/Support/SmallVector.cpp | 37 +++++------------------------
2 files changed, 18 insertions(+), 54 deletions(-)
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 ec340afd4519f4070389434006bf7f2afdbf2993..6b12ea17aaa894dc9a719ade4c41a3f7df4304e9 100644
index 3cab284f5b6105956d6fff49a27d37482a3c321d..b8981ab67322f7888ad63d953ba72dbfa53b2939 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/include/llvm/ADT/SmallVector.h
@@ -57,19 +57,19 @@ using EnableIfConvertibleToInputIterator = std::enable_if_t<std::is_convertible<
@@ -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.
@@ -37,7 +37,7 @@ index ec340afd4519f4070389434006bf7f2afdbf2993..6b12ea17aaa894dc9a719ade4c41a3f7
/// 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
@@ -108,7 +108,7 @@ protected:
@@ -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
@@ -46,7 +46,7 @@ index ec340afd4519f4070389434006bf7f2afdbf2993..6b12ea17aaa894dc9a719ade4c41a3f7
}
/// Set the array data pointer to \p Begin and capacity to \p N.
@@ -118,19 +118,14 @@ protected:
@@ -104,19 +104,14 @@ protected:
void set_allocation_range(void *Begin, size_t N) {
assert(N <= SizeTypeMax());
BeginX = Begin;
@@ -69,7 +69,7 @@ index ec340afd4519f4070389434006bf7f2afdbf2993..6b12ea17aaa894dc9a719ade4c41a3f7
alignas(T) char FirstEl[sizeof(T)];
};
@@ -139,8 +134,8 @@ template <class T, typename = void> struct SmallVectorAlignmentAndSize {
@@ -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
@@ -80,7 +80,7 @@ index ec340afd4519f4070389434006bf7f2afdbf2993..6b12ea17aaa894dc9a719ade4c41a3f7
protected:
/// Find the address of the first element. For this pointer math to be valid
@@ -462,7 +457,7 @@ template <typename T, bool TriviallyCopyable>
@@ -448,7 +443,7 @@ template <typename T, bool TriviallyCopyable>
T *SmallVectorTemplateBase<T, TriviallyCopyable>::mallocForGrow(
size_t MinSize, size_t &NewCapacity) {
return static_cast<T *>(
@@ -89,7 +89,7 @@ index ec340afd4519f4070389434006bf7f2afdbf2993..6b12ea17aaa894dc9a719ade4c41a3f7
this->getFirstEl(), MinSize, sizeof(T), NewCapacity));
}
@@ -1334,12 +1329,6 @@ template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
@@ -1320,12 +1315,6 @@ template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
return {std::begin(Range), std::end(Range)};
}
@@ -103,7 +103,7 @@ index ec340afd4519f4070389434006bf7f2afdbf2993..6b12ea17aaa894dc9a719ade4c41a3f7
namespace std {
diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp
index 4f6fee18b659adcbfd79822832f914170cbb1635..7ef023084d791cf746c346cb1655c9da36a6beb5 100644
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>) ==
@@ -128,17 +128,7 @@ index 4f6fee18b659adcbfd79822832f914170cbb1635..7ef023084d791cf746c346cb1655c9da
// Ensure we can fit the new capacity.
// This is only going to be applicable when the capacity is 32 bit.
@@ -107,8 +102,7 @@ static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) {
return std::clamp(NewCapacity, MinSize, MaxSize);
}
-template <class Size_T>
-void *SmallVectorBase<Size_T>::replaceAllocation(void *NewElts, size_t TSize,
+void *SmallVectorBase::replaceAllocation(void *NewElts, size_t TSize,
size_t NewCapacity,
size_t VSize) {
void *NewEltsReplace = llvm::safe_malloc(NewCapacity * TSize);
@@ -119,11 +113,10 @@ void *SmallVectorBase<Size_T>::replaceAllocation(void *NewElts, size_t TSize,
@@ -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.
@@ -152,7 +142,7 @@ index 4f6fee18b659adcbfd79822832f914170cbb1635..7ef023084d791cf746c346cb1655c9da
// 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);
@@ -133,10 +126,9 @@ void *SmallVectorBase<Size_T>::mallocForGrow(void *FirstEl, size_t MinSize,
@@ -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.
@@ -165,7 +155,7 @@ index 4f6fee18b659adcbfd79822832f914170cbb1635..7ef023084d791cf746c346cb1655c9da
void *NewElts;
if (BeginX == FirstEl) {
NewElts = llvm::safe_malloc(NewCapacity * TSize);
@@ -154,20 +146,3 @@ void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
@@ -162,20 +155,3 @@ void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
this->set_allocation_range(NewElts, NewCapacity);
}

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sun, 8 May 2022 13:48:59 -0400
Subject: [PATCH 11/37] Add vectors to raw_ostream
Subject: [PATCH 11/36] Add vectors to raw_ostream
---
llvm/include/llvm/Support/raw_ostream.h | 115 ++++++++++++++++++++++++
@@ -9,7 +9,7 @@ Subject: [PATCH 11/37] Add vectors to raw_ostream
2 files changed, 162 insertions(+)
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index cbeb712e2a69426d83457cb1065fff4ca80a669d..a6799603a0106262520ba1c9fda14a7967b12a63 100644
index fed78518c3b6c44b366d04f45a1d74819e794a3c..2c37ff9c0966506c53d15d7cb84abc82335b9913 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -24,6 +24,7 @@
@@ -155,10 +155,10 @@ index cbeb712e2a69426d83457cb1065fff4ca80a669d..a6799603a0106262520ba1c9fda14a79
class raw_null_ostream : public raw_pwrite_stream {
/// See raw_ostream::write_impl.
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index ee9d2b0cda0a4f338e4b089304203f220a5ed1c4..6c330c92e7dbeb27310b053d1a82de73b42ee6f8 100644
index e06253e8f3a16dc09573cdec74cf54e0e3fcf848..a74b6b00d616828a8e5ab25c1fd15f2528b4d76d 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -677,6 +677,53 @@ bool raw_svector_ostream::classof(const raw_ostream *OS) {
@@ -679,6 +679,53 @@ bool raw_svector_ostream::classof(const raw_ostream *OS) {
return OS->get_kind() == OStreamKind::OK_SVecStream;
}

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Wed, 4 May 2022 00:01:00 -0400
Subject: [PATCH 13/37] EpochTracker ABI macro
Subject: [PATCH 12/36] EpochTracker ABI macro
---
llvm/include/llvm/ADT/EpochTracker.h | 2 +-

View File

@@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Tue, 3 May 2022 22:16:10 -0400
Subject: [PATCH 12/37] Extra collections features
---
llvm/lib/Support/raw_ostream.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 6c330c92e7dbeb27310b053d1a82de73b42ee6f8..7086368a3598ccad9502112f734c9ad81252ebec 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -77,6 +77,14 @@ constexpr raw_ostream::Colors raw_ostream::WHITE;
constexpr raw_ostream::Colors raw_ostream::SAVEDCOLOR;
constexpr raw_ostream::Colors raw_ostream::RESET;
+namespace {
+// Find the length of an array.
+template <class T, std::size_t N>
+constexpr inline size_t array_lengthof(T (&)[N]) {
+ return N;
+}
+} // namespace
+
raw_ostream::~raw_ostream() {
// raw_ostream's subclasses should take care to flush the buffer
// in their destructors.

View File

@@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Thu, 5 May 2022 18:09:45 -0400
Subject: [PATCH 13/36] Delete numbers from MathExtras
---
llvm/include/llvm/Support/MathExtras.h | 37 --------------------------
1 file changed, 37 deletions(-)
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index b2c62d833038f92d2621ca2e6838d0d6b3b48760..60f8c48031b1809e9de66220103b3a504f32c225 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -40,43 +40,6 @@ template <typename T, typename U, typename = enableif_int<T, U>>
using common_sint =
std::common_type_t<std::make_signed_t<T>, std::make_signed_t<U>>;
-/// Mathematical constants.
-namespace numbers {
-// TODO: Track C++20 std::numbers.
-// clang-format off
-constexpr double e = 0x1.5bf0a8b145769P+1, // (2.7182818284590452354) https://oeis.org/A001113
- egamma = 0x1.2788cfc6fb619P-1, // (.57721566490153286061) https://oeis.org/A001620
- ln2 = 0x1.62e42fefa39efP-1, // (.69314718055994530942) https://oeis.org/A002162
- ln10 = 0x1.26bb1bbb55516P+1, // (2.3025850929940456840) https://oeis.org/A002392
- log2e = 0x1.71547652b82feP+0, // (1.4426950408889634074)
- log10e = 0x1.bcb7b1526e50eP-2, // (.43429448190325182765)
- pi = 0x1.921fb54442d18P+1, // (3.1415926535897932385) https://oeis.org/A000796
- inv_pi = 0x1.45f306dc9c883P-2, // (.31830988618379067154) https://oeis.org/A049541
- sqrtpi = 0x1.c5bf891b4ef6bP+0, // (1.7724538509055160273) https://oeis.org/A002161
- inv_sqrtpi = 0x1.20dd750429b6dP-1, // (.56418958354775628695) https://oeis.org/A087197
- sqrt2 = 0x1.6a09e667f3bcdP+0, // (1.4142135623730950488) https://oeis.org/A00219
- inv_sqrt2 = 0x1.6a09e667f3bcdP-1, // (.70710678118654752440)
- sqrt3 = 0x1.bb67ae8584caaP+0, // (1.7320508075688772935) https://oeis.org/A002194
- inv_sqrt3 = 0x1.279a74590331cP-1, // (.57735026918962576451)
- phi = 0x1.9e3779b97f4a8P+0; // (1.6180339887498948482) https://oeis.org/A001622
-constexpr float ef = 0x1.5bf0a8P+1F, // (2.71828183) https://oeis.org/A001113
- egammaf = 0x1.2788d0P-1F, // (.577215665) https://oeis.org/A001620
- ln2f = 0x1.62e430P-1F, // (.693147181) https://oeis.org/A002162
- ln10f = 0x1.26bb1cP+1F, // (2.30258509) https://oeis.org/A002392
- log2ef = 0x1.715476P+0F, // (1.44269504)
- log10ef = 0x1.bcb7b2P-2F, // (.434294482)
- pif = 0x1.921fb6P+1F, // (3.14159265) https://oeis.org/A000796
- inv_pif = 0x1.45f306P-2F, // (.318309886) https://oeis.org/A049541
- sqrtpif = 0x1.c5bf8aP+0F, // (1.77245385) https://oeis.org/A002161
- inv_sqrtpif = 0x1.20dd76P-1F, // (.564189584) https://oeis.org/A087197
- sqrt2f = 0x1.6a09e6P+0F, // (1.41421356) https://oeis.org/A002193
- inv_sqrt2f = 0x1.6a09e6P-1F, // (.707106781)
- sqrt3f = 0x1.bb67aeP+0F, // (1.73205081) https://oeis.org/A002194
- inv_sqrt3f = 0x1.279a74P-1F, // (.577350269)
- phif = 0x1.9e377aP+0F; // (1.61803399) https://oeis.org/A001622
-// clang-format on
-} // namespace numbers
-
/// Create a bitmask with the N right-most bits set to 1, and all other
/// bits set to 0. Only unsigned types are allowed.
template <typename T> T maskTrailingOnes(unsigned N) {

View File

@@ -1,17 +1,17 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Tue, 3 May 2022 22:50:24 -0400
Subject: [PATCH 15/37] Add lerp and sgn
Subject: [PATCH 14/36] Add lerp and sgn
---
llvm/include/llvm/Support/MathExtras.h | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index b9084182158757647cc9896320a353a373b0f9ec..4033e032b5979a4f25b4c16f3988fb11087ed6bb 100644
index 60f8c48031b1809e9de66220103b3a504f32c225..acd16bb0e6cf73f565d44d654c34057d9b97dd95 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -751,6 +751,27 @@ using stack_float_t = volatile float;
@@ -759,6 +759,27 @@ using stack_float_t = volatile float;
using stack_float_t = float;
#endif

View File

@@ -1,56 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Thu, 5 May 2022 18:09:45 -0400
Subject: [PATCH 14/37] Delete numbers from MathExtras
---
llvm/include/llvm/Support/MathExtras.h | 36 --------------------------
1 file changed, 36 deletions(-)
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index 6028ba8ead7627b4821aa8642f5069b305605c5e..b9084182158757647cc9896320a353a373b0f9ec 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -40,42 +40,6 @@ template <typename T, typename U, typename = enableif_int<T, U>>
using common_sint =
std::common_type_t<std::make_signed_t<T>, std::make_signed_t<U>>;
-/// Mathematical constants.
-namespace numbers {
-// TODO: Track C++20 std::numbers.
-// TODO: Favor using the hexadecimal FP constants (requires C++17).
-constexpr double e = 2.7182818284590452354, // (0x1.5bf0a8b145749P+1) https://oeis.org/A001113
- egamma = .57721566490153286061, // (0x1.2788cfc6fb619P-1) https://oeis.org/A001620
- ln2 = .69314718055994530942, // (0x1.62e42fefa39efP-1) https://oeis.org/A002162
- ln10 = 2.3025850929940456840, // (0x1.24bb1bbb55516P+1) https://oeis.org/A002392
- log2e = 1.4426950408889634074, // (0x1.71547652b82feP+0)
- log10e = .43429448190325182765, // (0x1.bcb7b1526e50eP-2)
- pi = 3.1415926535897932385, // (0x1.921fb54442d18P+1) https://oeis.org/A000796
- inv_pi = .31830988618379067154, // (0x1.45f306bc9c883P-2) https://oeis.org/A049541
- sqrtpi = 1.7724538509055160273, // (0x1.c5bf891b4ef6bP+0) https://oeis.org/A002161
- inv_sqrtpi = .56418958354775628695, // (0x1.20dd750429b6dP-1) https://oeis.org/A087197
- sqrt2 = 1.4142135623730950488, // (0x1.6a09e667f3bcdP+0) https://oeis.org/A00219
- inv_sqrt2 = .70710678118654752440, // (0x1.6a09e667f3bcdP-1)
- sqrt3 = 1.7320508075688772935, // (0x1.bb67ae8584caaP+0) https://oeis.org/A002194
- inv_sqrt3 = .57735026918962576451, // (0x1.279a74590331cP-1)
- phi = 1.6180339887498948482; // (0x1.9e3779b97f4a8P+0) https://oeis.org/A001622
-constexpr float ef = 2.71828183F, // (0x1.5bf0a8P+1) https://oeis.org/A001113
- egammaf = .577215665F, // (0x1.2788d0P-1) https://oeis.org/A001620
- ln2f = .693147181F, // (0x1.62e430P-1) https://oeis.org/A002162
- ln10f = 2.30258509F, // (0x1.26bb1cP+1) https://oeis.org/A002392
- log2ef = 1.44269504F, // (0x1.715476P+0)
- log10ef = .434294482F, // (0x1.bcb7b2P-2)
- pif = 3.14159265F, // (0x1.921fb6P+1) https://oeis.org/A000796
- inv_pif = .318309886F, // (0x1.45f306P-2) https://oeis.org/A049541
- sqrtpif = 1.77245385F, // (0x1.c5bf8aP+0) https://oeis.org/A002161
- inv_sqrtpif = .564189584F, // (0x1.20dd76P-1) https://oeis.org/A087197
- sqrt2f = 1.41421356F, // (0x1.6a09e6P+0) https://oeis.org/A002193
- inv_sqrt2f = .707106781F, // (0x1.6a09e6P-1)
- sqrt3f = 1.73205081F, // (0x1.bb67aeP+0) https://oeis.org/A002194
- inv_sqrt3f = .577350269F, // (0x1.279a74P-1)
- phif = 1.61803399F; // (0x1.9e377aP+0) https://oeis.org/A001622
-} // namespace numbers
-
/// Create a bitmask with the N right-most bits set to 1, and all other
/// bits set to 0. Only unsigned types are allowed.
template <typename T> T maskTrailingOnes(unsigned N) {

View File

@@ -1,17 +1,17 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sun, 8 May 2022 16:38:11 -0400
Subject: [PATCH 16/37] Fixup includes
Subject: [PATCH 15/36] Fixup includes
---
llvm/include/llvm/Support/PointerLikeTypeTraits.h | 1 +
llvm/lib/Support/ConvertUTFWrapper.cpp | 1 +
llvm/lib/Support/ErrorHandling.cpp | 9 ++++-----
llvm/lib/Support/raw_ostream.cpp | 11 ++++++-----
llvm/unittests/ADT/SmallPtrSetTest.cpp | 2 ++
llvm/unittests/ADT/SmallVectorTest.cpp | 1 +
llvm/unittests/Support/ConvertUTFTest.cpp | 2 ++
7 files changed, 17 insertions(+), 10 deletions(-)
llvm/include/llvm/Support/PointerLikeTypeTraits.h | 1 +
llvm/lib/Support/ConvertUTFWrapper.cpp | 1 +
llvm/lib/Support/ErrorHandling.cpp | 9 ++++-----
llvm/lib/Support/raw_ostream.cpp | 9 ++++++---
llvm/unittests/ADT/SmallPtrSetTest.cpp | 2 ++
llvm/unittests/ADT/SmallVectorTest.cpp | 1 +
llvm/unittests/Support/ConvertUTFTest.cpp | 2 ++
7 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/Support/PointerLikeTypeTraits.h b/llvm/include/llvm/Support/PointerLikeTypeTraits.h
index 1b15f930bd87d97d51824af5e62ea5f222a6b4c9..acadd5e89a1651cfbad67a5b1b0933d1f288d094 100644
@@ -38,7 +38,7 @@ index d53462e742e61d3476915d5b2c5aa63772e78a8a..34054140489e4d536ace4650207c783d
#include "llvm/Support/SwapByteOrder.h"
#include <span>
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index ea8d60426ead7163550b73e0fdc32cb11bb089cb..5f53ec03a1c1e91659143f12abec145b95627826 100644
index 4de36d969b3776b72ff85888355b64f7f3262ccc..e813fd3faa9f76148f9802c4b7308e517df32269 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -28,12 +28,11 @@
@@ -50,7 +50,7 @@ index ea8d60426ead7163550b73e0fdc32cb11bb089cb..5f53ec03a1c1e91659143f12abec145b
+#ifndef _WIN32
+#include <unistd.h>
#endif
#if defined(_MSC_VER)
#if defined(_WIN32)
-# include <io.h>
-# include <fcntl.h>
+#include <io.h>
@@ -67,7 +67,7 @@ index ea8d60426ead7163550b73e0fdc32cb11bb089cb..5f53ec03a1c1e91659143f12abec145b
#include <ntstatus.h>
#include <winerror.h>
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 7086368a3598ccad9502112f734c9ad81252ebec..e173687cafdd04894c27ccd5efb109a7411f1398 100644
index a74b6b00d616828a8e5ab25c1fd15f2528b4d76d..87c890f7659ae9d59ae70557df464aaff4d2d77a 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -15,6 +15,8 @@
@@ -79,13 +79,9 @@ index 7086368a3598ccad9502112f734c9ad81252ebec..e173687cafdd04894c27ccd5efb109a7
#include "llvm/ADT/StringExtras.h"
#include "llvm/Config/config.h"
#include "llvm/Support/AutoConvert.h"
@@ -33,12 +35,11 @@
#include <sys/stat.h>
@@ -35,8 +37,9 @@
// <fcntl.h> may provide O_BINARY.
-#if defined(HAVE_FCNTL_H)
# include <fcntl.h>
-#endif
-#if defined(HAVE_UNISTD_H)
-# include <unistd.h>
@@ -95,7 +91,7 @@ index 7086368a3598ccad9502112f734c9ad81252ebec..e173687cafdd04894c27ccd5efb109a7
#endif
#if defined(__CYGWIN__)
@@ -61,7 +62,7 @@
@@ -59,7 +62,7 @@
#ifdef _WIN32
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Signals.h"
@@ -105,18 +101,18 @@ index 7086368a3598ccad9502112f734c9ad81252ebec..e173687cafdd04894c27ccd5efb109a7
using namespace llvm;
diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp
index a6c2b329f072639706aa221feb8c08e33533f813..4c1a144a7a52eb38c7af2d20749901974b29f962 100644
index 65c0c564e91a40a98432d985c6949d3d4aa0717d..98045c6349237c620ae7d4d1792bf93c9317e145 100644
--- a/llvm/unittests/ADT/SmallPtrSetTest.cpp
+++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp
@@ -15,6 +15,8 @@
#include "llvm/Support/PointerLikeTypeTraits.h"
@@ -16,6 +16,8 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include <algorithm>
+
using namespace llvm;
using testing::UnorderedElementsAre;
TEST(SmallPtrSetTest, Assignment) {
diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp
index f8c37820ef9fdfe0af067f5aa8d2297ed15e73bc..5e91f71bc9ac0e499a64dd1591e581d0707417f6 100644
--- a/llvm/unittests/ADT/SmallVectorTest.cpp

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sun, 8 May 2022 16:42:09 -0400
Subject: [PATCH 17/37] Use std::is_trivially_copy_constructible
Subject: [PATCH 16/36] Use std::is_trivially_copy_constructible
---
llvm/include/llvm/Support/type_traits.h | 16 ----------------

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Tue, 3 May 2022 20:22:38 -0400
Subject: [PATCH 18/37] Windows support
Subject: [PATCH 17/36] Windows support
---
.../llvm/Support/Windows/WindowsSupport.h | 45 +++++----
@@ -10,10 +10,10 @@ Subject: [PATCH 18/37] Windows support
3 files changed, 124 insertions(+), 17 deletions(-)
diff --git a/llvm/include/llvm/Support/Windows/WindowsSupport.h b/llvm/include/llvm/Support/Windows/WindowsSupport.h
index aabdb2f14668a990329b57f5454a0d7db73e12ce..2ac474092a62d488da1ec7f07a1cd10b0781d938 100644
index 83d5586ae8a77ec585e7e59df3075ca59cfb9d0c..395965bc6fc969ed9a2d92743a0010ddf3923394 100644
--- a/llvm/include/llvm/Support/Windows/WindowsSupport.h
+++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h
@@ -35,8 +35,6 @@
@@ -33,8 +33,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -22,7 +22,7 @@ index aabdb2f14668a990329b57f5454a0d7db73e12ce..2ac474092a62d488da1ec7f07a1cd10b
#include "llvm/Support/Chrono.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -44,18 +42,46 @@
@@ -42,18 +40,46 @@
#include <cassert>
#include <string>
#include <system_error>
@@ -70,7 +70,7 @@ index aabdb2f14668a990329b57f5454a0d7db73e12ce..2ac474092a62d488da1ec7f07a1cd10b
/// Determines if the program is running on Windows 11 or Windows Server 2022.
bool RunningWindows11OrGreater();
@@ -231,19 +257,6 @@ inline FILETIME toFILETIME(TimePoint<> TP) {
@@ -229,19 +255,6 @@ inline FILETIME toFILETIME(TimePoint<> TP) {
return Time;
}
@@ -204,10 +204,10 @@ index bc04c5ab5113563fb82d7b3b168985369b611f4b..57eb64a6017a6964ab14b40b8c6b3563
ConvertUTF_RESTORE_WARNINGS
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index e173687cafdd04894c27ccd5efb109a7411f1398..6ed93793a64c523102626d581656d2f9509f7d5d 100644
index 87c890f7659ae9d59ae70557df464aaff4d2d77a..193ef061867c659e732bb1507b4ff0808f3b5f5c 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -532,7 +532,6 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
@@ -524,7 +524,6 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
DWORD WinLastError = GetLastError();
if (WinLastError == ERROR_BROKEN_PIPE ||
(WinLastError == ERROR_NO_DATA && errno == EINVAL)) {

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Tue, 17 Sep 2024 21:19:52 -0700
Subject: [PATCH 19/37] Remove call to RtlGetLastNtStatus()
Subject: [PATCH 18/36] Remove call to RtlGetLastNtStatus()
---
llvm/lib/Support/ErrorHandling.cpp | 23 -----------------------
1 file changed, 23 deletions(-)
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index 5f53ec03a1c1e91659143f12abec145b95627826..c795f13065c820de772b56be7f59aab63f6ee084 100644
index e813fd3faa9f76148f9802c4b7308e517df32269..d0fd67bd3c0d4cf33922cdda042531424d277951 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -214,34 +214,11 @@ void LLVMResetFatalErrorHandler() {

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sun, 8 May 2022 16:46:20 -0400
Subject: [PATCH 20/37] Prefer fmtlib
Subject: [PATCH 19/36] Prefer fmtlib
---
llvm/lib/Support/ErrorHandling.cpp | 20 ++++++--------------
1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index c795f13065c820de772b56be7f59aab63f6ee084..9b292a51dbd59ad700da22d008a5bcac1c334b26 100644
index d0fd67bd3c0d4cf33922cdda042531424d277951..b66f4a0d71f4897821084dc05a278d7c5194a847 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -22,7 +22,7 @@

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sun, 8 May 2022 16:49:36 -0400
Subject: [PATCH 21/37] Prefer wpi's fs.h
Subject: [PATCH 20/36] Prefer wpi's fs.h
---
llvm/include/llvm/Support/raw_ostream.h | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index a6799603a0106262520ba1c9fda14a7967b12a63..39a600c2ed7cd1cfecb46ff17929ffcb389207d7 100644
index 2c37ff9c0966506c53d15d7cb84abc82335b9913..990d3e4cfe53e025df6ce797f46f9de5af8ca6dc 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -26,18 +26,15 @@

View File

@@ -1,17 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sun, 8 May 2022 19:16:51 -0400
Subject: [PATCH 22/37] Remove unused functions
Subject: [PATCH 21/36] Remove unused functions
---
llvm/include/llvm/Support/raw_ostream.h | 5 +-
llvm/lib/Support/ErrorHandling.cpp | 16 -----
llvm/lib/Support/raw_ostream.cpp | 47 +++++++-------
llvm/unittests/ADT/SmallStringTest.cpp | 81 -------------------------
4 files changed, 23 insertions(+), 126 deletions(-)
llvm/include/llvm/Support/VersionTuple.h | 1 -
llvm/include/llvm/Support/raw_ostream.h | 5 +-
llvm/lib/Support/ErrorHandling.cpp | 16 -----
llvm/lib/Support/raw_ostream.cpp | 47 ++++++--------
llvm/unittests/ADT/SmallStringTest.cpp | 81 ------------------------
5 files changed, 23 insertions(+), 127 deletions(-)
diff --git a/llvm/include/llvm/Support/VersionTuple.h b/llvm/include/llvm/Support/VersionTuple.h
index 9102ff063afedc03bd524b2805cba98ea5afeba8..7638d1ab0d12e22608d4c3e3a14ec8e0ce15d2d5 100644
--- a/llvm/include/llvm/Support/VersionTuple.h
+++ b/llvm/include/llvm/Support/VersionTuple.h
@@ -21,7 +21,6 @@
#include <tuple>
namespace llvm {
-template <typename HasherT, llvm::endianness Endianness> class HashBuilder;
class raw_ostream;
/// Represents a version number in the form major[.minor[.subminor[.build]]].
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index 39a600c2ed7cd1cfecb46ff17929ffcb389207d7..9bb9260eecf35b0f71d144256fc956a80b2da8a3 100644
index 990d3e4cfe53e025df6ce797f46f9de5af8ca6dc..264b8192a0473b94363765995517851cbf30d045 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -71,7 +71,6 @@ private:
@@ -35,7 +48,7 @@ index 39a600c2ed7cd1cfecb46ff17929ffcb389207d7..9bb9260eecf35b0f71d144256fc956a8
//===--------------------------------------------------------------------===//
// Subclass Interface
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index 9b292a51dbd59ad700da22d008a5bcac1c334b26..51cc3edaa7b128725912e51757cd0b443fe064ae 100644
index b66f4a0d71f4897821084dc05a278d7c5194a847..6c2b1c433285d2ec5d124f96919ff27f3328d74c 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -182,22 +182,6 @@ void llvm::llvm_unreachable_internal(const char *msg, const char *file,
@@ -62,10 +75,10 @@ index 9b292a51dbd59ad700da22d008a5bcac1c334b26..51cc3edaa7b128725912e51757cd0b44
#define WIN32_NO_STATUS
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 6ed93793a64c523102626d581656d2f9509f7d5d..7e9a58db056e315cdcec22af0439017dee737c8f 100644
index 193ef061867c659e732bb1507b4ff0808f3b5f5c..3bfebbb41f324d9525290d9105c11fe01502dd87 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -176,16 +176,6 @@ raw_ostream &raw_ostream::write_escaped(std::string_view Str,
@@ -168,16 +168,6 @@ raw_ostream &raw_ostream::write_escaped(std::string_view Str,
return *this;
}
@@ -82,7 +95,7 @@ index 6ed93793a64c523102626d581656d2f9509f7d5d..7e9a58db056e315cdcec22af0439017d
void raw_ostream::flush_nonempty() {
assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
size_t Length = OutBufCur - OutBufStart;
@@ -322,15 +312,22 @@ static int getFD(std::string_view Filename, std::error_code &EC,
@@ -314,15 +304,22 @@ static int getFD(std::string_view Filename, std::error_code &EC,
if (Filename == "-") {
EC = std::error_code();
// Change stdout's text/binary mode based on the Flags.
@@ -110,7 +123,7 @@ index 6ed93793a64c523102626d581656d2f9509f7d5d..7e9a58db056e315cdcec22af0439017d
if (EC)
return -1;
@@ -390,12 +387,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
@@ -382,12 +379,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
// Get the starting position.
off_t loc = ::lseek(FD, 0, SEEK_CUR);
@@ -124,7 +137,7 @@ index 6ed93793a64c523102626d581656d2f9509f7d5d..7e9a58db056e315cdcec22af0439017d
#else
SupportsSeeking = !EC && loc != (off_t)-1;
#endif
@@ -408,10 +401,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
@@ -400,10 +393,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
raw_fd_ostream::~raw_fd_ostream() {
if (FD >= 0) {
flush();
@@ -137,7 +150,7 @@ index 6ed93793a64c523102626d581656d2f9509f7d5d..7e9a58db056e315cdcec22af0439017d
}
#ifdef __MINGW32__
@@ -509,7 +500,11 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
@@ -501,7 +492,11 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
do {
size_t ChunkSize = std::min(Size, MaxWriteSize);
@@ -149,7 +162,7 @@ index 6ed93793a64c523102626d581656d2f9509f7d5d..7e9a58db056e315cdcec22af0439017d
if (ret < 0) {
// If it's a recoverable error, swallow it and retry the write.
@@ -552,8 +547,8 @@ void raw_fd_ostream::close() {
@@ -544,8 +539,8 @@ void raw_fd_ostream::close() {
assert(ShouldClose);
ShouldClose = false;
flush();

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sun, 8 May 2022 19:30:43 -0400
Subject: [PATCH 23/37] OS-specific changes
Subject: [PATCH 22/36] OS-specific changes
---
llvm/lib/Support/ErrorHandling.cpp | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index 51cc3edaa7b128725912e51757cd0b443fe064ae..fcfb90a614a99e333f56f8380e63ff89dd1d684f 100644
index 6c2b1c433285d2ec5d124f96919ff27f3328d74c..05e7ee1d125bdd6ce9a8f0db97d4feed3832a7ba 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -96,15 +96,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Mon, 9 May 2022 00:04:30 -0400
Subject: [PATCH 24/37] Use SmallVector for UTF conversion
Subject: [PATCH 23/36] Use SmallVector for UTF conversion
---
llvm/include/llvm/Support/ConvertUTF.h | 6 +++---

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Thu, 19 May 2022 00:58:36 -0400
Subject: [PATCH 25/37] Prefer to use static pointers in raw_ostream
Subject: [PATCH 24/36] Prefer to use static pointers in raw_ostream
See #1401
---
@@ -9,11 +9,11 @@ See #1401
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 7e9a58db056e315cdcec22af0439017dee737c8f..b417bebdef3a2f2e12e46e65ad7885d243b477a7 100644
index 3bfebbb41f324d9525290d9105c11fe01502dd87..47ec87cc8cb9576a443f9e0ea35a753e64411495 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -612,9 +612,9 @@ raw_fd_ostream &llvm::outs() {
EC = enableAutoConversion(STDOUT_FILENO);
@@ -608,9 +608,9 @@ raw_fd_ostream &llvm::outs() {
EC = enablezOSAutoConversion(STDOUT_FILENO);
assert(!EC);
#endif
- static raw_fd_ostream S("-", EC, sys::fs::OF_None);
@@ -24,8 +24,8 @@ index 7e9a58db056e315cdcec22af0439017dee737c8f..b417bebdef3a2f2e12e46e65ad7885d2
}
raw_fd_ostream &llvm::errs() {
@@ -623,8 +623,8 @@ raw_fd_ostream &llvm::errs() {
std::error_code EC = enableAutoConversion(STDERR_FILENO);
@@ -619,8 +619,8 @@ raw_fd_ostream &llvm::errs() {
std::error_code EC = enablezOSAutoConversion(STDERR_FILENO);
assert(!EC);
#endif
- static raw_fd_ostream S(STDERR_FILENO, false, true);

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Fri, 1 Mar 2024 11:56:17 -0800
Subject: [PATCH 26/37] constexpr endian byte swap
Subject: [PATCH 25/36] constexpr endian byte swap
---
llvm/include/llvm/Support/Endian.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Support/Endian.h b/llvm/include/llvm/Support/Endian.h
index 5831fe66a1f7b71f26aac179c4e2c904d0ad4255..62e19c04e5dc565dd94c5c38f7c6b141fbcb56a3 100644
index f86ea8901ae46b8b724b76ac44e0b54b84b9eda8..ca4252fc064d3349d10b7e540aadb885ae96a3b5 100644
--- a/llvm/include/llvm/Support/Endian.h
+++ b/llvm/include/llvm/Support/Endian.h
@@ -50,7 +50,9 @@ template <typename value_type>

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Wed, 10 Aug 2022 17:07:52 -0700
Subject: [PATCH 27/37] Copy type traits from STLExtras.h into PointerUnion.h
Subject: [PATCH 26/36] Copy type traits from STLExtras.h into PointerUnion.h
---
llvm/include/llvm/ADT/PointerUnion.h | 46 ++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h
index 8ac68dbc0a791b8ac0e0ca865e69024cb642aa70..273ba02934bd405ea4f1b911ebb58f7080837ff0 100644
index 23394db93cfed492bb1747eb9c8c55ed9230120d..124b869c6974ac78d908b3c55d89455a471b5185 100644
--- a/llvm/include/llvm/ADT/PointerUnion.h
+++ b/llvm/include/llvm/ADT/PointerUnion.h
@@ -23,9 +23,55 @@

View File

@@ -1,20 +1,20 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leander Schulten <Leander.Schulten@rwth-aachen.de>
Date: Mon, 10 Jul 2023 00:53:43 +0200
Subject: [PATCH 28/37] Unused variable in release mode
Subject: [PATCH 27/36] Unused variable in release mode
---
llvm/include/llvm/ADT/DenseMap.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index c4764fffa845a7f9eb69f262aa0ee728d08b1655..e77fa3bade8133ae73fd271a582d8500269bfe7e 100644
index 4c852d2b142b4a3de76a1ce4049822cc449287f7..69ce7982d732887642c7f46163b753ee17be9b30 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -124,7 +124,7 @@ public:
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P)
@@ -126,7 +126,7 @@ public:
P->getFirst() = EmptyKey;
} else {
const KeyT TombstoneKey = getTombstoneKey();
- unsigned NumEntries = getNumEntries();
+ [[maybe_unused]] unsigned NumEntries = getNumEntries();
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {

View File

@@ -1,17 +1,16 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Tue, 11 Jul 2023 22:56:09 -0700
Subject: [PATCH 29/37] Use C++20 <bit> header
Subject: [PATCH 28/36] Use C++20 <bit> header
---
llvm/include/llvm/ADT/DenseMap.h | 3 +-
llvm/include/llvm/ADT/Hashing.h | 35 +--
llvm/include/llvm/ADT/bit.h | 313 -------------------------
llvm/include/llvm/Support/MathExtras.h | 21 +-
4 files changed, 31 insertions(+), 341 deletions(-)
3 files changed, 13 insertions(+), 324 deletions(-)
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index e77fa3bade8133ae73fd271a582d8500269bfe7e..bf39eaf5ac230221defcdd1b7711b77089d05642 100644
index 69ce7982d732887642c7f46163b753ee17be9b30..927a9c72ec939d268ae7463f7113f051cc92cf3f 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -23,6 +23,7 @@
@@ -22,7 +21,7 @@ index e77fa3bade8133ae73fd271a582d8500269bfe7e..bf39eaf5ac230221defcdd1b7711b770
#include <cassert>
#include <cstddef>
#include <cstring>
@@ -949,7 +950,7 @@ class SmallDenseMap
@@ -906,7 +907,7 @@ class SmallDenseMap
public:
explicit SmallDenseMap(unsigned NumInitBuckets = 0) {
if (NumInitBuckets > InlineBuckets)
@@ -31,97 +30,6 @@ index e77fa3bade8133ae73fd271a582d8500269bfe7e..bf39eaf5ac230221defcdd1b7711b770
init(NumInitBuckets);
}
diff --git a/llvm/include/llvm/ADT/Hashing.h b/llvm/include/llvm/ADT/Hashing.h
index a33c6eec308c8722f88b09f73f954d39558c3d62..36b4d4b58b414bd6f61437fb597cd596cb16e66f 100644
--- a/llvm/include/llvm/ADT/Hashing.h
+++ b/llvm/include/llvm/ADT/Hashing.h
@@ -50,6 +50,7 @@
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
+#include <bit>
#include <cassert>
#include <cstring>
#include <optional>
@@ -208,30 +209,30 @@ inline uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed) {
uint64_t b = fetch64(s + 8);
uint64_t c = fetch64(s + len - 8) * k2;
uint64_t d = fetch64(s + len - 16) * k0;
- return hash_16_bytes(llvm::rotr<uint64_t>(a - b, 43) +
- llvm::rotr<uint64_t>(c ^ seed, 30) + d,
- a + llvm::rotr<uint64_t>(b ^ k3, 20) - c + len + seed);
+ return hash_16_bytes(std::rotr<uint64_t>(a - b, 43) +
+ std::rotr<uint64_t>(c ^ seed, 30) + d,
+ a + std::rotr<uint64_t>(b ^ k3, 20) - c + len + seed);
}
inline uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed) {
uint64_t z = fetch64(s + 24);
uint64_t a = fetch64(s) + (len + fetch64(s + len - 16)) * k0;
- uint64_t b = llvm::rotr<uint64_t>(a + z, 52);
- uint64_t c = llvm::rotr<uint64_t>(a, 37);
+ uint64_t b = std::rotr<uint64_t>(a + z, 52);
+ uint64_t c = std::rotr<uint64_t>(a, 37);
a += fetch64(s + 8);
- c += llvm::rotr<uint64_t>(a, 7);
+ c += std::rotr<uint64_t>(a, 7);
a += fetch64(s + 16);
uint64_t vf = a + z;
- uint64_t vs = b + llvm::rotr<uint64_t>(a, 31) + c;
+ uint64_t vs = b + std::rotr<uint64_t>(a, 31) + c;
a = fetch64(s + 16) + fetch64(s + len - 32);
z = fetch64(s + len - 8);
- b = llvm::rotr<uint64_t>(a + z, 52);
- c = llvm::rotr<uint64_t>(a, 37);
+ b = std::rotr<uint64_t>(a + z, 52);
+ c = std::rotr<uint64_t>(a, 37);
a += fetch64(s + len - 24);
- c += llvm::rotr<uint64_t>(a, 7);
+ c += std::rotr<uint64_t>(a, 7);
a += fetch64(s + len - 16);
uint64_t wf = a + z;
- uint64_t ws = b + llvm::rotr<uint64_t>(a, 31) + c;
+ uint64_t ws = b + std::rotr<uint64_t>(a, 31) + c;
uint64_t r = shift_mix((vf + ws) * k2 + (wf + vs) * k0);
return shift_mix((seed ^ (r * k0)) + vs) * k2;
}
@@ -264,7 +265,7 @@ struct hash_state {
hash_state state = {0,
seed,
hash_16_bytes(seed, k1),
- llvm::rotr<uint64_t>(seed ^ k1, 49),
+ std::rotr<uint64_t>(seed ^ k1, 49),
seed * k1,
shift_mix(seed),
0};
@@ -278,10 +279,10 @@ struct hash_state {
static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) {
a += fetch64(s);
uint64_t c = fetch64(s + 24);
- b = llvm::rotr<uint64_t>(b + a + c, 21);
+ b = std::rotr<uint64_t>(b + a + c, 21);
uint64_t d = a;
a += fetch64(s + 8) + fetch64(s + 16);
- b += llvm::rotr<uint64_t>(a, 44) + d;
+ b += std::rotr<uint64_t>(a, 44) + d;
a += c;
}
@@ -289,11 +290,11 @@ struct hash_state {
/// We mix all 64 bytes even when the chunk length is smaller, but we
/// record the actual length.
void mix(const char *s) {
- h0 = llvm::rotr<uint64_t>(h0 + h1 + h3 + fetch64(s + 8), 37) * k1;
- h1 = llvm::rotr<uint64_t>(h1 + h4 + fetch64(s + 48), 42) * k1;
+ h0 = std::rotr<uint64_t>(h0 + h1 + h3 + fetch64(s + 8), 37) * k1;
+ h1 = std::rotr<uint64_t>(h1 + h4 + fetch64(s + 48), 42) * k1;
h0 ^= h6;
h1 += h3 + fetch64(s + 40);
- h2 = llvm::rotr<uint64_t>(h2 + h5, 33) * k1;
+ h2 = std::rotr<uint64_t>(h2 + h5, 33) * k1;
h3 = h4 * k1;
h4 = h0 + h5;
mix_32_bytes(s, h3, h4);
diff --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h
index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade593b522a08 100644
--- a/llvm/include/llvm/ADT/bit.h
@@ -454,7 +362,7 @@ index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade59
#endif
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index 4033e032b5979a4f25b4c16f3988fb11087ed6bb..219f8894849e80ee70a4b4cf40194682740ec865 100644
index acd16bb0e6cf73f565d44d654c34057d9b97dd95..5191831247ff668f22b6015d5b135fd9701afdd2 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -15,6 +15,7 @@

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Sun, 30 Jul 2023 14:17:37 -0700
Subject: [PATCH 30/37] Remove DenseMap GTest printer test
Subject: [PATCH 29/36] Remove DenseMap GTest printer test
LLVM modifies internal GTest headers to support it, which we can't do.
---

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Johnson <johnson.peter@gmail.com>
Date: Sun, 29 Oct 2023 23:00:08 -0700
Subject: [PATCH 31/37] raw_ostream: Add SetNumBytesInBuffer
Subject: [PATCH 30/36] raw_ostream: Add SetNumBytesInBuffer
---
llvm/include/llvm/Support/raw_ostream.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index 9bb9260eecf35b0f71d144256fc956a80b2da8a3..c5765a05fb493c6a5bb6b619f0fbdb8d986e21ed 100644
index 264b8192a0473b94363765995517851cbf30d045..d0e5ba46a9e748037c2ad444207fc8fc236ec5d5 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -365,6 +365,11 @@ protected:

View File

@@ -1,17 +1,17 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Tue, 17 Sep 2024 15:30:31 -0700
Subject: [PATCH 32/37] raw_ostream: Replace errnoAsErrorCode()
Subject: [PATCH 31/36] raw_ostream: Replace errnoAsErrorCode()
---
llvm/lib/Support/raw_ostream.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index b417bebdef3a2f2e12e46e65ad7885d243b477a7..0330f8da01341a9b78a2e5e73e74d696285fbb51 100644
index 47ec87cc8cb9576a443f9e0ea35a753e64411495..c9e62f5c1c4a194fb12ad604bc7f2a72d421c2e1 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -531,7 +531,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
@@ -523,7 +523,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
}
#endif
// Otherwise it's a non-recoverable error. Note it and quit.
@@ -20,7 +20,7 @@ index b417bebdef3a2f2e12e46e65ad7885d243b477a7..0330f8da01341a9b78a2e5e73e74d696
break;
}
@@ -561,7 +561,7 @@ uint64_t raw_fd_ostream::seek(uint64_t off) {
@@ -553,7 +553,7 @@ uint64_t raw_fd_ostream::seek(uint64_t off) {
pos = ::lseek(FD, off, SEEK_SET);
#endif
if (pos == (uint64_t)-1)

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Johnson <johnson.peter@gmail.com>
Date: Sat, 2 Dec 2023 15:21:32 -0800
Subject: [PATCH 33/37] type_traits.h: Add is_constexpr()
Subject: [PATCH 32/36] type_traits.h: Add is_constexpr()
---
llvm/include/llvm/Support/type_traits.h | 5 +++++

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Sun, 17 Mar 2024 14:51:11 -0700
Subject: [PATCH 34/37] Remove auto-conversion from raw_ostream
Subject: [PATCH 33/36] Remove auto-conversion from raw_ostream
---
llvm/lib/Support/raw_ostream.cpp | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 0330f8da01341a9b78a2e5e73e74d696285fbb51..46c277c461868ee291eedc764f4b5609b3903312 100644
index c9e62f5c1c4a194fb12ad604bc7f2a72d421c2e1..e387577d7a040a1698b14c821eb4197d376fc631 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -19,7 +19,6 @@
@@ -19,12 +19,12 @@ index 0330f8da01341a9b78a2e5e73e74d696285fbb51..46c277c461868ee291eedc764f4b5609
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
@@ -608,21 +607,13 @@ void raw_fd_ostream::anchor() {}
@@ -604,21 +603,13 @@ void raw_fd_ostream::anchor() {}
raw_fd_ostream &llvm::outs() {
// Set buffer settings to model stdout behavior.
std::error_code EC;
-#ifdef __MVS__
- EC = enableAutoConversion(STDOUT_FILENO);
- EC = enablezOSAutoConversion(STDOUT_FILENO);
- assert(!EC);
-#endif
static raw_fd_ostream* S = new raw_fd_ostream("-", EC, sys::fs::OF_None);
@@ -35,7 +35,7 @@ index 0330f8da01341a9b78a2e5e73e74d696285fbb51..46c277c461868ee291eedc764f4b5609
raw_fd_ostream &llvm::errs() {
- // Set standard error to be unbuffered.
-#ifdef __MVS__
- std::error_code EC = enableAutoConversion(STDERR_FILENO);
- std::error_code EC = enablezOSAutoConversion(STDERR_FILENO);
- assert(!EC);
-#endif
+ // Set standard error to be unbuffered and tied to outs() by default.

View File

@@ -1,17 +1,17 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Tue, 18 Jun 2024 09:07:33 -0700
Subject: [PATCH 35/37] Add SmallVector erase_if()
Subject: [PATCH 34/36] Add SmallVector erase_if()
---
llvm/include/llvm/ADT/SmallVector.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
index 6b12ea17aaa894dc9a719ade4c41a3f7df4304e9..2d53728f3ce621beb578a0ad9e8d6176b5d0eb66 100644
index b8981ab67322f7888ad63d953ba72dbfa53b2939..9a22c95aaf84d276b1c097c0997de3e6b04ea05e 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/include/llvm/ADT/SmallVector.h
@@ -1329,6 +1329,14 @@ template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
@@ -1315,6 +1315,14 @@ template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
return {std::begin(Range), std::end(Range)};
}

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Sat, 13 Jul 2024 15:24:30 -0700
Subject: [PATCH 36/37] Fix AlignedCharArrayUnion for C++23
Subject: [PATCH 35/36] Fix AlignedCharArrayUnion for C++23
---
llvm/include/llvm/Support/AlignOf.h | 14 +++++---------

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Mon, 23 Dec 2024 22:56:29 -0800
Subject: [PATCH 37/37] Fix minIntN() and maxIntN() assertions
Subject: [PATCH 36/36] Fix minIntN() and maxIntN() assertions
---
llvm/include/llvm/Support/MathExtras.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index 219f8894849e80ee70a4b4cf40194682740ec865..ce100e643b6a724895774d29c1855c8fb3d90bde 100644
index 5191831247ff668f22b6015d5b135fd9701afdd2..5b2dccf8959856f2c6dbf3cc4d5260d1ad541459 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -203,7 +203,7 @@ inline uint64_t maxUIntN(uint64_t N) {

View File

@@ -24,7 +24,7 @@
#ifndef _WIN32
#include <unistd.h>
#endif
#if defined(_MSC_VER)
#if defined(_WIN32)
#include <io.h>
#endif

View File

@@ -13,12 +13,15 @@
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void *
wpi::allocate_buffer(size_t Size, size_t Alignment) {
return ::operator new(Size
void *Result = ::operator new(Size,
#ifdef __cpp_aligned_new
,
std::align_val_t(Alignment)
std::align_val_t(Alignment),
#endif
);
std::nothrow);
if (Result == nullptr) {
report_bad_alloc_error("Buffer allocation failed");
}
return Result;
}
void wpi::deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) {

View File

@@ -62,7 +62,25 @@ SmallPtrSetImplBase::insert_imp_big(const void *Ptr) {
return std::make_pair(Bucket, true);
}
const void * const *SmallPtrSetImplBase::FindBucketFor(const void *Ptr) const {
const void *const *SmallPtrSetImplBase::doFind(const void *Ptr) const {
unsigned BucketNo =
DenseMapInfo<void *>::getHashValue(Ptr) & (CurArraySize - 1);
unsigned ProbeAmt = 1;
while (true) {
const void *const *Bucket = CurArray + BucketNo;
if (LLVM_LIKELY(*Bucket == Ptr))
return Bucket;
if (LLVM_LIKELY(*Bucket == getEmptyMarker()))
return nullptr;
// Otherwise, it's a hash collision or a tombstone, continue quadratic
// probing.
BucketNo += ProbeAmt++;
BucketNo &= CurArraySize - 1;
}
}
const void *const *SmallPtrSetImplBase::FindBucketFor(const void *Ptr) const {
unsigned Bucket = DenseMapInfo<void *>::getHashValue(Ptr) & (CurArraySize-1);
unsigned ArraySize = CurArraySize;
unsigned ProbeAmt = 1;
@@ -116,32 +134,33 @@ void SmallPtrSetImplBase::Grow(unsigned NewSize) {
free(OldBuckets);
NumNonEmpty -= NumTombstones;
NumTombstones = 0;
IsSmall = false;
}
SmallPtrSetImplBase::SmallPtrSetImplBase(const void **SmallStorage,
const SmallPtrSetImplBase &that) {
SmallArray = SmallStorage;
// If we're becoming small, prepare to insert into our stack space
if (that.isSmall()) {
CurArray = SmallArray;
// Otherwise, allocate new heap space (unless we were the same size)
IsSmall = that.isSmall();
if (IsSmall) {
// If we're becoming small, prepare to insert into our stack space
CurArray = SmallStorage;
} else {
// Otherwise, allocate new heap space (unless we were the same size)
CurArray = (const void**)safe_malloc(sizeof(void*) * that.CurArraySize);
}
// Copy over the that array.
CopyHelper(that);
copyHelper(that);
}
SmallPtrSetImplBase::SmallPtrSetImplBase(const void **SmallStorage,
unsigned SmallSize,
const void **RHSSmallStorage,
SmallPtrSetImplBase &&that) {
SmallArray = SmallStorage;
MoveHelper(SmallSize, std::move(that));
moveHelper(SmallStorage, SmallSize, RHSSmallStorage, std::move(that));
}
void SmallPtrSetImplBase::CopyFrom(const SmallPtrSetImplBase &RHS) {
void SmallPtrSetImplBase::copyFrom(const void **SmallStorage,
const SmallPtrSetImplBase &RHS) {
assert(&RHS != this && "Self-copy should be handled by the caller.");
if (isSmall() && RHS.isSmall())
@@ -152,8 +171,9 @@ void SmallPtrSetImplBase::CopyFrom(const SmallPtrSetImplBase &RHS) {
if (RHS.isSmall()) {
if (!isSmall())
free(CurArray);
CurArray = SmallArray;
// Otherwise, allocate new heap space (unless we were the same size)
CurArray = SmallStorage;
IsSmall = true;
// Otherwise, allocate new heap space (unless we were the same size)
} else if (CurArraySize != RHS.CurArraySize) {
if (isSmall())
CurArray = (const void**)safe_malloc(sizeof(void*) * RHS.CurArraySize);
@@ -162,12 +182,13 @@ void SmallPtrSetImplBase::CopyFrom(const SmallPtrSetImplBase &RHS) {
sizeof(void*) * RHS.CurArraySize);
CurArray = T;
}
IsSmall = false;
}
CopyHelper(RHS);
copyHelper(RHS);
}
void SmallPtrSetImplBase::CopyHelper(const SmallPtrSetImplBase &RHS) {
void SmallPtrSetImplBase::copyHelper(const SmallPtrSetImplBase &RHS) {
// Copy over the new array size
CurArraySize = RHS.CurArraySize;
@@ -178,39 +199,46 @@ void SmallPtrSetImplBase::CopyHelper(const SmallPtrSetImplBase &RHS) {
NumTombstones = RHS.NumTombstones;
}
void SmallPtrSetImplBase::MoveFrom(unsigned SmallSize,
void SmallPtrSetImplBase::moveFrom(const void **SmallStorage,
unsigned SmallSize,
const void **RHSSmallStorage,
SmallPtrSetImplBase &&RHS) {
if (!isSmall())
free(CurArray);
MoveHelper(SmallSize, std::move(RHS));
moveHelper(SmallStorage, SmallSize, RHSSmallStorage, std::move(RHS));
}
void SmallPtrSetImplBase::MoveHelper(unsigned SmallSize,
void SmallPtrSetImplBase::moveHelper(const void **SmallStorage,
unsigned SmallSize,
const void **RHSSmallStorage,
SmallPtrSetImplBase &&RHS) {
assert(&RHS != this && "Self-move should be handled by the caller.");
if (RHS.isSmall()) {
// Copy a small RHS rather than moving.
CurArray = SmallArray;
CurArray = SmallStorage;
std::copy(RHS.CurArray, RHS.CurArray + RHS.NumNonEmpty, CurArray);
} else {
CurArray = RHS.CurArray;
RHS.CurArray = RHS.SmallArray;
RHS.CurArray = RHSSmallStorage;
}
// Copy the rest of the trivial members.
CurArraySize = RHS.CurArraySize;
NumNonEmpty = RHS.NumNonEmpty;
NumTombstones = RHS.NumTombstones;
IsSmall = RHS.IsSmall;
// Make the RHS small and empty.
RHS.CurArraySize = SmallSize;
assert(RHS.CurArray == RHS.SmallArray);
RHS.NumNonEmpty = 0;
RHS.NumTombstones = 0;
RHS.IsSmall = true;
}
void SmallPtrSetImplBase::swap(SmallPtrSetImplBase &RHS) {
void SmallPtrSetImplBase::swap(const void **SmallStorage,
const void **RHSSmallStorage,
SmallPtrSetImplBase &RHS) {
if (this == &RHS) return;
// We can only avoid copying elements if neither set is small.
@@ -227,42 +255,42 @@ void SmallPtrSetImplBase::swap(SmallPtrSetImplBase &RHS) {
// If only RHS is small, copy the small elements into LHS and move the pointer
// from LHS to RHS.
if (!this->isSmall() && RHS.isSmall()) {
assert(RHS.CurArray == RHS.SmallArray);
std::copy(RHS.CurArray, RHS.CurArray + RHS.NumNonEmpty, this->SmallArray);
std::copy(RHS.CurArray, RHS.CurArray + RHS.NumNonEmpty, SmallStorage);
std::swap(RHS.CurArraySize, this->CurArraySize);
std::swap(this->NumNonEmpty, RHS.NumNonEmpty);
std::swap(this->NumTombstones, RHS.NumTombstones);
RHS.CurArray = this->CurArray;
this->CurArray = this->SmallArray;
RHS.IsSmall = false;
this->CurArray = SmallStorage;
this->IsSmall = true;
return;
}
// If only LHS is small, copy the small elements into RHS and move the pointer
// from RHS to LHS.
if (this->isSmall() && !RHS.isSmall()) {
assert(this->CurArray == this->SmallArray);
std::copy(this->CurArray, this->CurArray + this->NumNonEmpty,
RHS.SmallArray);
RHSSmallStorage);
std::swap(RHS.CurArraySize, this->CurArraySize);
std::swap(RHS.NumNonEmpty, this->NumNonEmpty);
std::swap(RHS.NumTombstones, this->NumTombstones);
this->CurArray = RHS.CurArray;
RHS.CurArray = RHS.SmallArray;
this->IsSmall = false;
RHS.CurArray = RHSSmallStorage;
RHS.IsSmall = true;
return;
}
// Both a small, just swap the small elements.
assert(this->isSmall() && RHS.isSmall());
unsigned MinNonEmpty = std::min(this->NumNonEmpty, RHS.NumNonEmpty);
std::swap_ranges(this->SmallArray, this->SmallArray + MinNonEmpty,
RHS.SmallArray);
std::swap_ranges(this->CurArray, this->CurArray + MinNonEmpty, RHS.CurArray);
if (this->NumNonEmpty > MinNonEmpty) {
std::copy(this->SmallArray + MinNonEmpty,
this->SmallArray + this->NumNonEmpty,
RHS.SmallArray + MinNonEmpty);
std::copy(this->CurArray + MinNonEmpty, this->CurArray + this->NumNonEmpty,
RHS.CurArray + MinNonEmpty);
} else {
std::copy(RHS.SmallArray + MinNonEmpty, RHS.SmallArray + RHS.NumNonEmpty,
this->SmallArray + MinNonEmpty);
std::copy(RHS.CurArray + MinNonEmpty, RHS.CurArray + RHS.NumNonEmpty,
this->CurArray + MinNonEmpty);
}
assert(this->CurArraySize == RHS.CurArraySize);
std::swap(this->NumNonEmpty, RHS.NumNonEmpty);

View File

@@ -102,9 +102,18 @@ static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) {
return std::clamp(NewCapacity, MinSize, MaxSize);
}
void *SmallVectorBase::replaceAllocation(void *NewElts, size_t TSize,
size_t NewCapacity,
size_t VSize) {
/// If vector was first created with capacity 0, getFirstEl() points to the
/// memory right after, an area unallocated. If a subsequent allocation,
/// that grows the vector, happens to return the same pointer as getFirstEl(),
/// get a new allocation, otherwise isSmall() will falsely return that no
/// allocation was done (true) and the memory will not be freed in the
/// destructor. If a VSize is given (vector size), also copy that many
/// elements to the new allocation - used if realloca fails to increase
/// space, and happens to allocate precisely at BeginX.
/// This is unlikely to be called often, but resolves a memory leak when the
/// situation does occur.
static void *replaceAllocation(void *NewElts, size_t TSize, size_t NewCapacity,
size_t VSize = 0) {
void *NewEltsReplace = wpi::safe_malloc(NewCapacity * TSize);
if (VSize)
memcpy(NewEltsReplace, NewElts, VSize * TSize);

View File

@@ -23,11 +23,9 @@
// mingw-w64 tends to define it as 0x0502 in its headers.
#undef _WIN32_WINNT
#undef _WIN32_IE
// Require at least Windows 7 API.
#define _WIN32_WINNT 0x0601
#define _WIN32_IE 0x0800 // MinGW at it again. FIXME: verify if still needed.
#define WIN32_LEAN_AND_MEAN
#ifndef NOMINMAX
#define NOMINMAX

View File

@@ -70,14 +70,6 @@ constexpr raw_ostream::Colors raw_ostream::WHITE;
constexpr raw_ostream::Colors raw_ostream::SAVEDCOLOR;
constexpr raw_ostream::Colors raw_ostream::RESET;
namespace {
// Find the length of an array.
template <class T, std::size_t N>
constexpr inline size_t array_lengthof(T (&)[N]) {
return N;
}
} // namespace
raw_ostream::~raw_ostream() {
// raw_ostream's subclasses should take care to flush the buffer
// in their destructors.
@@ -575,6 +567,10 @@ size_t raw_fd_ostream::preferred_buffer_size() const {
if (IsWindowsConsole)
return 0;
return raw_ostream::preferred_buffer_size();
#elif defined(__MVS__)
// The buffer size on z/OS is defined with macro BUFSIZ, which can be
// retrieved by invoking function raw_ostream::preferred_buffer_size().
return raw_ostream::preferred_buffer_size();
#else
assert(FD >= 0 && "File not yet open!");
struct stat statbuf;

File diff suppressed because it is too large Load Diff

View File

@@ -755,7 +755,7 @@ template <class X, class Y> auto dyn_cast_if_present(Y *Val) {
// Forwards to dyn_cast_if_present to avoid breaking current users. This is
// deprecated and will be removed in a future patch, use
// cast_if_present instead.
// dyn_cast_if_present instead.
template <class X, class Y> auto dyn_cast_or_null(const Y &Val) {
return dyn_cast_if_present<X>(Val);
}

View File

@@ -38,10 +38,6 @@
# define __has_builtin(x) 0
#endif
#ifndef __has_include
# define __has_include(x) 0
#endif
// Only use __has_cpp_attribute in C++ mode. GCC defines __has_cpp_attribute in
// C mode, but the :: in __has_cpp_attribute(scoped::attribute) is invalid.
#ifndef LLVM_HAS_CPP_ATTRIBUTE
@@ -115,7 +111,8 @@
/// this attribute will be made public and visible outside of any shared library
/// they are linked in to.
#if LLVM_HAS_CPP_ATTRIBUTE(gnu::visibility)
#if LLVM_HAS_CPP_ATTRIBUTE(gnu::visibility) && defined(__GNUC__) && \
!defined(__clang__)
#define LLVM_ATTRIBUTE_VISIBILITY_HIDDEN [[gnu::visibility("hidden")]]
#define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT [[gnu::visibility("default")]]
#elif __has_attribute(visibility)
@@ -126,18 +123,100 @@
#define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#endif
#if (!(defined(_WIN32) || defined(__CYGWIN__)) || \
(defined(__MINGW32__) && defined(__clang__)))
#define LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_HIDDEN
#if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS)
#define LLVM_EXTERNAL_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#else
#define LLVM_EXTERNAL_VISIBILITY
#endif
#if (!(defined(_WIN32) || defined(__CYGWIN__)) || \
(defined(__MINGW32__) && defined(__clang__)))
#define LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_HIDDEN
// Clang compilers older then 15 do not support gnu style attributes on
// namespaces.
#if defined(__clang__) && __clang_major__ < 15
#define LLVM_LIBRARY_VISIBILITY_NAMESPACE [[gnu::visibility("hidden")]]
#else
#define LLVM_LIBRARY_VISIBILITY_NAMESPACE LLVM_ATTRIBUTE_VISIBILITY_HIDDEN
#endif
#define LLVM_ALWAYS_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#elif defined(_WIN32)
#define LLVM_ALWAYS_EXPORT __declspec(dllexport)
#define LLVM_LIBRARY_VISIBILITY
#define LLVM_LIBRARY_VISIBILITY_NAMESPACE
#else
#define LLVM_LIBRARY_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
#define LLVM_ALWAYS_EXPORT
#define LLVM_LIBRARY_VISIBILITY_NAMESPACE
#endif
/// LLVM_ABI is the main export/visibility macro to mark something as explicitly
/// exported when llvm is built as a shared library with everything else that is
/// unannotated will have internal visibility.
///
/// LLVM_ABI_EXPORT is for the special case for things like plugin symbol
/// declarations or definitions where we don't want the macro to be switching
/// between dllexport and dllimport on windows based on what codebase is being
/// built, it will only be dllexport. For non windows platforms this macro
/// behaves the same as LLVM_ABI.
///
/// LLVM_EXPORT_TEMPLATE is used on explicit template instantiations in source
/// files that were declared extern in a header. This macro is only set as a
/// compiler export attribute on windows, on other platforms it does nothing.
///
/// LLVM_TEMPLATE_ABI is for annotating extern template declarations in headers
/// for both functions and classes. On windows its turned in to dllimport for
/// library consumers, for other platforms its a default visibility attribute.
///
/// LLVM_C_ABI is used to annotated functions and data that need to be exported
/// for the libllvm-c API. This used both for the llvm-c headers and for the
/// functions declared in the different Target's c++ source files that don't
/// include the header forward declaring them.
#ifndef LLVM_ABI_GENERATING_ANNOTATIONS
// Marker to add to classes or functions in public headers that should not have
// export macros added to them by the clang tool
#define LLVM_ABI_NOT_EXPORTED
#if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS) || \
defined(LLVM_ENABLE_PLUGINS)
// Some libraries like those for tablegen are linked in to tools that used
// in the build so can't depend on the llvm shared library. If export macros
// were left enabled when building these we would get duplicate or
// missing symbol linker errors on windows.
#if defined(LLVM_BUILD_STATIC)
#define LLVM_ABI
#define LLVM_TEMPLATE_ABI
#define LLVM_EXPORT_TEMPLATE
#define LLVM_ABI_EXPORT
#elif defined(_WIN32) && !defined(__MINGW32__)
#if defined(LLVM_EXPORTS)
#define LLVM_ABI __declspec(dllexport)
#define LLVM_TEMPLATE_ABI
#define LLVM_EXPORT_TEMPLATE __declspec(dllexport)
#else
#define LLVM_ABI __declspec(dllimport)
#define LLVM_TEMPLATE_ABI __declspec(dllimport)
#define LLVM_EXPORT_TEMPLATE
#endif
#define LLVM_ABI_EXPORT __declspec(dllexport)
#elif defined(__ELF__) || defined(__MINGW32__) || defined(_AIX) || \
defined(__MVS__)
#define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#define LLVM_TEMPLATE_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#define LLVM_EXPORT_TEMPLATE
#define LLVM_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#elif defined(__MACH__) || defined(__WASM__) || defined(__EMSCRIPTEN__)
#define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#define LLVM_TEMPLATE_ABI
#define LLVM_EXPORT_TEMPLATE
#define LLVM_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#endif
#else
#define LLVM_ABI
#define LLVM_TEMPLATE_ABI
#define LLVM_EXPORT_TEMPLATE
#define LLVM_ABI_EXPORT
#endif
#define LLVM_C_ABI LLVM_ABI
#endif
#ifndef LLVM_PREFETCH
@@ -357,6 +436,12 @@
#define LLVM_GSL_POINTER
#endif
#if LLVM_HAS_CPP_ATTRIBUTE(clang::lifetimebound)
#define LLVM_LIFETIME_BOUND [[clang::lifetimebound]]
#else
#define LLVM_LIFETIME_BOUND
#endif
#if LLVM_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L
#define LLVM_CTOR_NODISCARD [[nodiscard]]
#else

View File

@@ -110,7 +110,8 @@ public:
void clear() {
incrementEpoch();
if (getNumEntries() == 0 && getNumTombstones() == 0) return;
if (getNumEntries() == 0 && getNumTombstones() == 0)
return;
// If the capacity of the array is huge, and the # elements used is small,
// shrink the array.
@@ -119,12 +120,13 @@ public:
return;
}
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
if (std::is_trivially_destructible<ValueT>::value) {
const KeyT EmptyKey = getEmptyKey();
if constexpr (std::is_trivially_destructible_v<ValueT>) {
// Use a simpler loop when values don't need destruction.
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P)
P->getFirst() = EmptyKey;
} else {
const KeyT TombstoneKey = getTombstoneKey();
[[maybe_unused]] unsigned NumEntries = getNumEntries();
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) {
@@ -144,8 +146,7 @@ public:
/// Return true if the specified key is in the map, false otherwise.
bool contains(const_arg_type_t<KeyT> Val) const {
const BucketT *TheBucket;
return LookupBucketFor(Val, TheBucket);
return doFind(Val) != nullptr;
}
/// Return 1 if the specified key is in the map, 0 otherwise.
@@ -154,21 +155,17 @@ public:
}
iterator find(const_arg_type_t<KeyT> Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return makeIterator(TheBucket,
shouldReverseIterate<KeyT>() ? getBuckets()
: getBucketsEnd(),
*this, true);
if (BucketT *Bucket = doFind(Val))
return makeIterator(
Bucket, shouldReverseIterate<KeyT>() ? getBuckets() : getBucketsEnd(),
*this, true);
return end();
}
const_iterator find(const_arg_type_t<KeyT> Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return makeConstIterator(TheBucket,
shouldReverseIterate<KeyT>() ? getBuckets()
: getBucketsEnd(),
*this, true);
if (const BucketT *Bucket = doFind(Val))
return makeConstIterator(
Bucket, shouldReverseIterate<KeyT>() ? getBuckets() : getBucketsEnd(),
*this, true);
return end();
}
@@ -177,33 +174,27 @@ public:
/// The DenseMapInfo is responsible for supplying methods
/// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
/// type used.
template<class LookupKeyT>
iterator find_as(const LookupKeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return makeIterator(TheBucket,
shouldReverseIterate<KeyT>() ? getBuckets()
: getBucketsEnd(),
*this, true);
template <class LookupKeyT> iterator find_as(const LookupKeyT &Val) {
if (BucketT *Bucket = doFind(Val))
return makeIterator(
Bucket, shouldReverseIterate<KeyT>() ? getBuckets() : getBucketsEnd(),
*this, true);
return end();
}
template<class LookupKeyT>
template <class LookupKeyT>
const_iterator find_as(const LookupKeyT &Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return makeConstIterator(TheBucket,
shouldReverseIterate<KeyT>() ? getBuckets()
: getBucketsEnd(),
*this, true);
if (const BucketT *Bucket = doFind(Val))
return makeConstIterator(
Bucket, shouldReverseIterate<KeyT>() ? getBuckets() : getBucketsEnd(),
*this, true);
return end();
}
/// lookup - Return the entry for the specified key, or a default
/// constructed value if no such entry exists.
ValueT lookup(const_arg_type_t<KeyT> Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return TheBucket->getSecond();
if (const BucketT *Bucket = doFind(Val))
return Bucket->getSecond();
return ValueT();
}
@@ -233,7 +224,7 @@ public:
// The value is constructed in-place if the key is not in the map, otherwise
// it is not moved.
template <typename... Ts>
std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&... Args) {
std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&...Args) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
return std::make_pair(makeIterator(TheBucket,
@@ -258,7 +249,7 @@ public:
// The value is constructed in-place if the key is not in the map, otherwise
// it is not moved.
template <typename... Ts>
std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&... Args) {
std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&...Args) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
return std::make_pair(makeIterator(TheBucket,
@@ -307,8 +298,7 @@ public:
}
/// insert - Range insertion of pairs.
template<typename InputIt>
void insert(InputIt I, InputIt E) {
template <typename InputIt> void insert(InputIt I, InputIt E) {
for (; I != E; ++I)
insert(*I);
}
@@ -329,23 +319,9 @@ public:
return Ret;
}
/// Returns the value associated to the key in the map if it exists. If it
/// does not exist, emplace a default value for the key and returns a
/// reference to the newly created value.
ValueT &getOrInsertDefault(KeyT &&Key) {
return try_emplace(Key).first->second;
}
/// Returns the value associated to the key in the map if it exists. If it
/// does not exist, emplace a default value for the key and returns a
/// reference to the newly created value.
ValueT &getOrInsertDefault(const KeyT &Key) {
return try_emplace(Key).first->second;
}
bool erase(const KeyT &Val) {
BucketT *TheBucket;
if (!LookupBucketFor(Val, TheBucket))
BucketT *TheBucket = doFind(Val);
if (!TheBucket)
return false; // not in map.
TheBucket->getSecond().~ValueT();
@@ -362,28 +338,20 @@ public:
incrementNumTombstones();
}
value_type& FindAndConstruct(const KeyT &Key) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
return *TheBucket;
return *InsertIntoBucket(TheBucket, Key);
}
ValueT &operator[](const KeyT &Key) {
return FindAndConstruct(Key).second;
}
value_type& FindAndConstruct(KeyT &&Key) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
return *TheBucket;
return TheBucket->second;
return *InsertIntoBucket(TheBucket, std::move(Key));
return InsertIntoBucket(TheBucket, Key)->second;
}
ValueT &operator[](KeyT &&Key) {
return FindAndConstruct(std::move(Key)).second;
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
return TheBucket->second;
return InsertIntoBucket(TheBucket, std::move(Key))->second;
}
/// isPointerIntoBucketsArray - Return true if the specified pointer points
@@ -418,7 +386,7 @@ protected:
setNumEntries(0);
setNumTombstones(0);
assert((getNumBuckets() & (getNumBuckets()-1)) == 0 &&
assert((getNumBuckets() & (getNumBuckets() - 1)) == 0 &&
"# initial buckets must be a power of two!");
const KeyT EmptyKey = getEmptyKey();
for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B)
@@ -470,44 +438,45 @@ protected:
setNumEntries(other.getNumEntries());
setNumTombstones(other.getNumTombstones());
if (std::is_trivially_copyable<KeyT>::value &&
std::is_trivially_copyable<ValueT>::value)
memcpy(reinterpret_cast<void *>(getBuckets()), other.getBuckets(),
getNumBuckets() * sizeof(BucketT));
else
for (size_t i = 0; i < getNumBuckets(); ++i) {
::new (&getBuckets()[i].getFirst())
KeyT(other.getBuckets()[i].getFirst());
if (!KeyInfoT::isEqual(getBuckets()[i].getFirst(), getEmptyKey()) &&
!KeyInfoT::isEqual(getBuckets()[i].getFirst(), getTombstoneKey()))
::new (&getBuckets()[i].getSecond())
ValueT(other.getBuckets()[i].getSecond());
BucketT *Buckets = getBuckets();
const BucketT *OtherBuckets = other.getBuckets();
const size_t NumBuckets = getNumBuckets();
if constexpr (std::is_trivially_copyable_v<KeyT> &&
std::is_trivially_copyable_v<ValueT>) {
memcpy(reinterpret_cast<void *>(Buckets), OtherBuckets,
NumBuckets * sizeof(BucketT));
} else {
const KeyT EmptyKey = getEmptyKey();
const KeyT TombstoneKey = getTombstoneKey();
for (size_t I = 0; I < NumBuckets; ++I) {
::new (&Buckets[I].getFirst()) KeyT(OtherBuckets[I].getFirst());
if (!KeyInfoT::isEqual(Buckets[I].getFirst(), EmptyKey) &&
!KeyInfoT::isEqual(Buckets[I].getFirst(), TombstoneKey))
::new (&Buckets[I].getSecond()) ValueT(OtherBuckets[I].getSecond());
}
}
}
static unsigned getHashValue(const KeyT &Val) {
return KeyInfoT::getHashValue(Val);
}
template<typename LookupKeyT>
template <typename LookupKeyT>
static unsigned getHashValue(const LookupKeyT &Val) {
return KeyInfoT::getHashValue(Val);
}
static const KeyT getEmptyKey() {
static_assert(std::is_base_of<DenseMapBase, DerivedT>::value,
static_assert(std::is_base_of_v<DenseMapBase, DerivedT>,
"Must pass the derived type to this template!");
return KeyInfoT::getEmptyKey();
}
static const KeyT getTombstoneKey() {
return KeyInfoT::getTombstoneKey();
}
static const KeyT getTombstoneKey() { return KeyInfoT::getTombstoneKey(); }
private:
iterator makeIterator(BucketT *P, BucketT *E,
DebugEpochBase &Epoch,
bool NoAdvance=false) {
iterator makeIterator(BucketT *P, BucketT *E, DebugEpochBase &Epoch,
bool NoAdvance = false) {
if (shouldReverseIterate<KeyT>()) {
BucketT *B = P == getBucketsEnd() ? getBuckets() : P + 1;
return iterator(B, E, Epoch, NoAdvance);
@@ -517,7 +486,7 @@ private:
const_iterator makeConstIterator(const BucketT *P, const BucketT *E,
const DebugEpochBase &Epoch,
const bool NoAdvance=false) const {
const bool NoAdvance = false) const {
if (shouldReverseIterate<KeyT>()) {
const BucketT *B = P == getBucketsEnd() ? getBuckets() : P + 1;
return const_iterator(B, E, Epoch, NoAdvance);
@@ -533,13 +502,9 @@ private:
static_cast<DerivedT *>(this)->setNumEntries(Num);
}
void incrementNumEntries() {
setNumEntries(getNumEntries() + 1);
}
void incrementNumEntries() { setNumEntries(getNumEntries() + 1); }
void decrementNumEntries() {
setNumEntries(getNumEntries() - 1);
}
void decrementNumEntries() { setNumEntries(getNumEntries() - 1); }
unsigned getNumTombstones() const {
return static_cast<const DerivedT *>(this)->getNumTombstones();
@@ -549,46 +514,34 @@ private:
static_cast<DerivedT *>(this)->setNumTombstones(Num);
}
void incrementNumTombstones() {
setNumTombstones(getNumTombstones() + 1);
}
void incrementNumTombstones() { setNumTombstones(getNumTombstones() + 1); }
void decrementNumTombstones() {
setNumTombstones(getNumTombstones() - 1);
}
void decrementNumTombstones() { setNumTombstones(getNumTombstones() - 1); }
const BucketT *getBuckets() const {
return static_cast<const DerivedT *>(this)->getBuckets();
}
BucketT *getBuckets() {
return static_cast<DerivedT *>(this)->getBuckets();
}
BucketT *getBuckets() { return static_cast<DerivedT *>(this)->getBuckets(); }
unsigned getNumBuckets() const {
return static_cast<const DerivedT *>(this)->getNumBuckets();
}
BucketT *getBucketsEnd() {
return getBuckets() + getNumBuckets();
}
BucketT *getBucketsEnd() { return getBuckets() + getNumBuckets(); }
const BucketT *getBucketsEnd() const {
return getBuckets() + getNumBuckets();
}
void grow(unsigned AtLeast) {
static_cast<DerivedT *>(this)->grow(AtLeast);
}
void grow(unsigned AtLeast) { static_cast<DerivedT *>(this)->grow(AtLeast); }
void shrink_and_clear() {
static_cast<DerivedT *>(this)->shrink_and_clear();
}
void shrink_and_clear() { static_cast<DerivedT *>(this)->shrink_and_clear(); }
template <typename KeyArg, typename... ValueArgs>
BucketT *InsertIntoBucket(BucketT *TheBucket, KeyArg &&Key,
ValueArgs &&... Values) {
TheBucket = InsertIntoBucketImpl(Key, Key, TheBucket);
ValueArgs &&...Values) {
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
TheBucket->getFirst() = std::forward<KeyArg>(Key);
::new (&TheBucket->getSecond()) ValueT(std::forward<ValueArgs>(Values)...);
@@ -598,7 +551,7 @@ private:
template <typename LookupKeyT>
BucketT *InsertIntoBucketWithLookup(BucketT *TheBucket, KeyT &&Key,
ValueT &&Value, LookupKeyT &Lookup) {
TheBucket = InsertIntoBucketImpl(Key, Lookup, TheBucket);
TheBucket = InsertIntoBucketImpl(Lookup, TheBucket);
TheBucket->getFirst() = std::move(Key);
::new (&TheBucket->getSecond()) ValueT(std::move(Value));
@@ -606,8 +559,7 @@ private:
}
template <typename LookupKeyT>
BucketT *InsertIntoBucketImpl(const KeyT &Key, const LookupKeyT &Lookup,
BucketT *TheBucket) {
BucketT *InsertIntoBucketImpl(const LookupKeyT &Lookup, BucketT *TheBucket) {
incrementEpoch();
// If the load of the hash table is more than 3/4, or if fewer than 1/8 of
@@ -625,8 +577,9 @@ private:
this->grow(NumBuckets * 2);
LookupBucketFor(Lookup, TheBucket);
NumBuckets = getNumBuckets();
} else if (LLVM_UNLIKELY(NumBuckets-(NewNumEntries+getNumTombstones()) <=
NumBuckets/8)) {
} else if (LLVM_UNLIKELY(NumBuckets -
(NewNumEntries + getNumTombstones()) <=
NumBuckets / 8)) {
this->grow(NumBuckets);
LookupBucketFor(Lookup, TheBucket);
}
@@ -644,14 +597,41 @@ private:
return TheBucket;
}
template <typename LookupKeyT> BucketT *doFind(const LookupKeyT &Val) {
BucketT *BucketsPtr = getBuckets();
const unsigned NumBuckets = getNumBuckets();
if (NumBuckets == 0)
return nullptr;
const KeyT EmptyKey = getEmptyKey();
unsigned BucketNo = getHashValue(Val) & (NumBuckets - 1);
unsigned ProbeAmt = 1;
while (true) {
BucketT *Bucket = BucketsPtr + BucketNo;
if (LLVM_LIKELY(KeyInfoT::isEqual(Val, Bucket->getFirst())))
return Bucket;
if (LLVM_LIKELY(KeyInfoT::isEqual(Bucket->getFirst(), EmptyKey)))
return nullptr;
// Otherwise, it's a hash collision or a tombstone, continue quadratic
// probing.
BucketNo += ProbeAmt++;
BucketNo &= NumBuckets - 1;
}
}
template <typename LookupKeyT>
const BucketT *doFind(const LookupKeyT &Val) const {
return const_cast<DenseMapBase *>(this)->doFind(Val); // NOLINT
}
/// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
/// FoundBucket. If the bucket contains the key and a value, this returns
/// true, otherwise it returns a bucket with an empty marker or tombstone and
/// returns false.
template<typename LookupKeyT>
bool LookupBucketFor(const LookupKeyT &Val,
const BucketT *&FoundBucket) const {
const BucketT *BucketsPtr = getBuckets();
template <typename LookupKeyT>
bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) {
BucketT *BucketsPtr = getBuckets();
const unsigned NumBuckets = getNumBuckets();
if (NumBuckets == 0) {
@@ -660,17 +640,17 @@ private:
}
// FoundTombstone - Keep track of whether we find a tombstone while probing.
const BucketT *FoundTombstone = nullptr;
BucketT *FoundTombstone = nullptr;
const KeyT EmptyKey = getEmptyKey();
const KeyT TombstoneKey = getTombstoneKey();
assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
!KeyInfoT::isEqual(Val, TombstoneKey) &&
"Empty/Tombstone value shouldn't be inserted into map!");
unsigned BucketNo = getHashValue(Val) & (NumBuckets-1);
unsigned BucketNo = getHashValue(Val) & (NumBuckets - 1);
unsigned ProbeAmt = 1;
while (true) {
const BucketT *ThisBucket = BucketsPtr + BucketNo;
BucketT *ThisBucket = BucketsPtr + BucketNo;
// Found Val's bucket? If so, return it.
if (LLVM_LIKELY(KeyInfoT::isEqual(Val, ThisBucket->getFirst()))) {
FoundBucket = ThisBucket;
@@ -690,32 +670,21 @@ private:
// prefer to return it than something that would require more probing.
if (KeyInfoT::isEqual(ThisBucket->getFirst(), TombstoneKey) &&
!FoundTombstone)
FoundTombstone = ThisBucket; // Remember the first tombstone found.
FoundTombstone = ThisBucket; // Remember the first tombstone found.
// Otherwise, it's a hash collision or a tombstone, continue quadratic
// probing.
BucketNo += ProbeAmt++;
BucketNo &= (NumBuckets-1);
BucketNo &= (NumBuckets - 1);
}
}
template <typename LookupKeyT>
bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) {
const BucketT *ConstFoundBucket;
bool Result = const_cast<const DenseMapBase *>(this)
->LookupBucketFor(Val, ConstFoundBucket);
FoundBucket = const_cast<BucketT *>(ConstFoundBucket);
return Result;
}
public:
/// Return the approximate size (in bytes) of the actual map.
/// This is just the raw memory used by DenseMap.
/// If entries are pointers to objects, the size of the referenced objects
/// are not included.
size_t getMemorySize() const {
return getNumBuckets() * sizeof(BucketT);
}
size_t getMemorySize() const { return getNumBuckets() * sizeof(BucketT); }
};
/// Equality comparison for DenseMap.
@@ -783,8 +752,7 @@ public:
swap(other);
}
template<typename InputIt>
DenseMap(const InputIt &I, const InputIt &E) {
template <typename InputIt> DenseMap(const InputIt &I, const InputIt &E) {
init(std::distance(I, E));
this->insert(I, E);
}
@@ -799,7 +767,7 @@ public:
deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT));
}
void swap(DenseMap& RHS) {
void swap(DenseMap &RHS) {
this->incrementEpoch();
RHS.incrementEpoch();
std::swap(Buckets, RHS.Buckets);
@@ -808,13 +776,13 @@ public:
std::swap(NumBuckets, RHS.NumBuckets);
}
DenseMap& operator=(const DenseMap& other) {
DenseMap &operator=(const DenseMap &other) {
if (&other != this)
copyFrom(other);
return *this;
}
DenseMap& operator=(DenseMap &&other) {
DenseMap &operator=(DenseMap &&other) {
this->destroyAll();
deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT));
init(0);
@@ -822,7 +790,7 @@ public:
return *this;
}
void copyFrom(const DenseMap& other) {
void copyFrom(const DenseMap &other) {
this->destroyAll();
deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT));
if (allocateBuckets(other.NumBuckets)) {
@@ -847,14 +815,15 @@ public:
unsigned OldNumBuckets = NumBuckets;
BucketT *OldBuckets = Buckets;
allocateBuckets(std::max<unsigned>(64, static_cast<unsigned>(NextPowerOf2(AtLeast-1))));
allocateBuckets(std::max<unsigned>(
64, static_cast<unsigned>(NextPowerOf2(AtLeast - 1))));
assert(Buckets);
if (!OldBuckets) {
this->BaseT::initEmpty();
return;
}
this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets);
this->moveFromOldBuckets(OldBuckets, OldBuckets + OldNumBuckets);
// Free the old table.
deallocate_buffer(OldBuckets, sizeof(BucketT) * OldNumBuckets,
@@ -881,29 +850,17 @@ public:
}
private:
unsigned getNumEntries() const {
return NumEntries;
}
unsigned getNumEntries() const { return NumEntries; }
void setNumEntries(unsigned Num) {
NumEntries = Num;
}
void setNumEntries(unsigned Num) { NumEntries = Num; }
unsigned getNumTombstones() const {
return NumTombstones;
}
unsigned getNumTombstones() const { return NumTombstones; }
void setNumTombstones(unsigned Num) {
NumTombstones = Num;
}
void setNumTombstones(unsigned Num) { NumTombstones = Num; }
BucketT *getBuckets() const {
return Buckets;
}
BucketT *getBuckets() const { return Buckets; }
unsigned getNumBuckets() const {
return NumBuckets;
}
unsigned getNumBuckets() const { return NumBuckets; }
bool allocateBuckets(unsigned Num) {
NumBuckets = Num;
@@ -964,7 +921,7 @@ public:
swap(other);
}
template<typename InputIt>
template <typename InputIt>
SmallDenseMap(const InputIt &I, const InputIt &E) {
init(NextPowerOf2(std::distance(I, E)));
this->insert(I, E);
@@ -978,7 +935,7 @@ public:
deallocateBuckets();
}
void swap(SmallDenseMap& RHS) {
void swap(SmallDenseMap &RHS) {
unsigned TmpNumEntries = RHS.NumEntries;
RHS.NumEntries = NumEntries;
NumEntries = TmpNumEntries;
@@ -1050,13 +1007,13 @@ public:
new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep));
}
SmallDenseMap& operator=(const SmallDenseMap& other) {
SmallDenseMap &operator=(const SmallDenseMap &other) {
if (&other != this)
copyFrom(other);
return *this;
}
SmallDenseMap& operator=(SmallDenseMap &&other) {
SmallDenseMap &operator=(SmallDenseMap &&other) {
this->destroyAll();
deallocateBuckets();
init(0);
@@ -1064,7 +1021,7 @@ public:
return *this;
}
void copyFrom(const SmallDenseMap& other) {
void copyFrom(const SmallDenseMap &other) {
this->destroyAll();
deallocateBuckets();
Small = true;
@@ -1086,7 +1043,7 @@ public:
void grow(unsigned AtLeast) {
if (AtLeast > InlineBuckets)
AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast-1));
AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast - 1));
if (Small) {
// First move the inline buckets into a temporary storage.
@@ -1130,7 +1087,8 @@ public:
new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
}
this->moveFromOldBuckets(OldRep.Buckets, OldRep.Buckets+OldRep.NumBuckets);
this->moveFromOldBuckets(OldRep.Buckets,
OldRep.Buckets + OldRep.NumBuckets);
// Free the old table.
deallocate_buffer(OldRep.Buckets, sizeof(BucketT) * OldRep.NumBuckets,
@@ -1159,9 +1117,7 @@ public:
}
private:
unsigned getNumEntries() const {
return NumEntries;
}
unsigned getNumEntries() const { return NumEntries; }
void setNumEntries(unsigned Num) {
// NumEntries is hardcoded to be 31 bits wide.
@@ -1169,13 +1125,9 @@ private:
NumEntries = Num;
}
unsigned getNumTombstones() const {
return NumTombstones;
}
unsigned getNumTombstones() const { return NumTombstones; }
void setNumTombstones(unsigned Num) {
NumTombstones = Num;
}
void setNumTombstones(unsigned Num) { NumTombstones = Num; }
const BucketT *getInlineBuckets() const {
assert(Small);
@@ -1187,7 +1139,7 @@ private:
BucketT *getInlineBuckets() {
return const_cast<BucketT *>(
const_cast<const SmallDenseMap *>(this)->getInlineBuckets());
const_cast<const SmallDenseMap *>(this)->getInlineBuckets());
}
const LargeRep *getLargeRep() const {
@@ -1198,7 +1150,7 @@ private:
LargeRep *getLargeRep() {
return const_cast<LargeRep *>(
const_cast<const SmallDenseMap *>(this)->getLargeRep());
const_cast<const SmallDenseMap *>(this)->getLargeRep());
}
const BucketT *getBuckets() const {
@@ -1207,7 +1159,7 @@ private:
BucketT *getBuckets() {
return const_cast<BucketT *>(
const_cast<const SmallDenseMap *>(this)->getBuckets());
const_cast<const SmallDenseMap *>(this)->getBuckets());
}
unsigned getNumBuckets() const {
@@ -1258,7 +1210,8 @@ public:
: DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) {
assert(isHandleInSync() && "invalid construction!");
if (NoAdvance) return;
if (NoAdvance)
return;
if (shouldReverseIterate<KeyT>()) {
RetreatPastEmptyBuckets();
return;
@@ -1304,7 +1257,7 @@ public:
return !(LHS == RHS);
}
inline DenseMapIterator& operator++() { // Preincrement
inline DenseMapIterator &operator++() { // Preincrement
assert(isHandleInSync() && "invalid iterator access!");
assert(Ptr != End && "incrementing end() iterator");
if (shouldReverseIterate<KeyT>()) {
@@ -1316,9 +1269,11 @@ public:
AdvancePastEmptyBuckets();
return *this;
}
DenseMapIterator operator++(int) { // Postincrement
DenseMapIterator operator++(int) { // Postincrement
assert(isHandleInSync() && "invalid iterator access!");
DenseMapIterator tmp = *this; ++*this; return tmp;
DenseMapIterator tmp = *this;
++*this;
return tmp;
}
private:

View File

@@ -60,7 +60,7 @@ template <typename value_type, std::size_t alignment = unaligned>
[[nodiscard]] inline value_type read(const void *memory, endianness endian) {
value_type ret;
memcpy(&ret,
memcpy(static_cast<void *>(&ret),
LLVM_ASSUME_ALIGNED(
memory, (detail::PickAlignment<value_type, alignment>::value)),
sizeof(value_type));

View File

@@ -87,6 +87,7 @@ using EnableIfCallable = std::enable_if_t<std::disjunction<
template <typename ReturnT, typename... ParamTs> class UniqueFunctionBase {
protected:
static constexpr size_t InlineStorageSize = sizeof(void *) * 4;
static constexpr size_t InlineStorageAlign = alignof(void *);
template <typename T, class = void>
struct IsSizeLessThanThresholdT : std::false_type {};
@@ -168,7 +169,8 @@ protected:
// provide four pointers worth of storage here.
// This is mutable as an inlined `const unique_function<void() const>` may
// still modify its own mutable members.
alignas(void *) mutable std::byte InlineStorage[InlineStorageSize];
alignas(InlineStorageAlign) mutable std::byte
InlineStorage[InlineStorageSize];
} StorageUnion;
// A compressed pointer to either our dispatching callback or our table of
@@ -269,7 +271,7 @@ protected:
bool IsInlineStorage = true;
void *CallableAddr = getInlineStorage();
if (sizeof(CallableT) > InlineStorageSize ||
alignof(CallableT) > alignof(decltype(StorageUnion.InlineStorage))) {
alignof(CallableT) > InlineStorageAlign) {
IsInlineStorage = false;
// Allocate out-of-line storage. FIXME: Use an explicit alignment
// parameter in C++17 mode.
@@ -319,6 +321,7 @@ protected:
// Non-trivial move, so dispatch to a type-erased implementation.
getNonTrivialCallbacks()->MovePtr(getInlineStorage(),
RHS.getInlineStorage());
getNonTrivialCallbacks()->DestroyPtr(RHS.getInlineStorage());
}
// Clear the old callback and inline flag to get back to as-if-null.

View File

@@ -1,688 +0,0 @@
//===-- llvm/ADT/Hashing.h - Utilities for hashing --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the newly proposed standard C++ interfaces for hashing
// arbitrary data and building hash functions for user-defined types. This
// interface was originally proposed in N3333[1] and is currently under review
// for inclusion in a future TR and/or standard.
//
// The primary interfaces provide are comprised of one type and three functions:
//
// -- 'hash_code' class is an opaque type representing the hash code for some
// data. It is the intended product of hashing, and can be used to implement
// hash tables, checksumming, and other common uses of hashes. It is not an
// integer type (although it can be converted to one) because it is risky
// to assume much about the internals of a hash_code. In particular, each
// execution of the program has a high probability of producing a different
// hash_code for a given input. Thus their values are not stable to save or
// persist, and should only be used during the execution for the
// construction of hashing datastructures.
//
// -- 'hash_value' is a function designed to be overloaded for each
// user-defined type which wishes to be used within a hashing context. It
// should be overloaded within the user-defined type's namespace and found
// via ADL. Overloads for primitive types are provided by this library.
//
// -- 'hash_combine' and 'hash_combine_range' are functions designed to aid
// programmers in easily and intuitively combining a set of data into
// a single hash_code for their object. They should only logically be used
// within the implementation of a 'hash_value' routine or similar context.
//
// Note that 'hash_combine_range' contains very special logic for hashing
// a contiguous array of integers or pointers. This logic is *extremely* fast,
// on a modern Intel "Gainestown" Xeon (Nehalem uarch) @2.2 GHz, these were
// benchmarked at over 6.5 GiB/s for large keys, and <20 cycles/hash for keys
// under 32-bytes.
//
//===----------------------------------------------------------------------===//
#ifndef WPIUTIL_WPI_HASHING_H
#define WPIUTIL_WPI_HASHING_H
#include "wpi/ErrorHandling.h"
#include "wpi/SwapByteOrder.h"
#include "wpi/type_traits.h"
#include <algorithm>
#include <bit>
#include <cassert>
#include <cstring>
#include <optional>
#include <string>
#include <tuple>
#include <utility>
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable : 26495)
#endif
namespace wpi {
template <typename T, typename Enable> struct DenseMapInfo;
/// An opaque object representing a hash code.
///
/// This object represents the result of hashing some entity. It is intended to
/// be used to implement hashtables or other hashing-based data structures.
/// While it wraps and exposes a numeric value, this value should not be
/// trusted to be stable or predictable across processes or executions.
///
/// In order to obtain the hash_code for an object 'x':
/// \code
/// using wpi::hash_value;
/// wpi::hash_code code = hash_value(x);
/// \endcode
class hash_code {
size_t value;
public:
/// Default construct a hash_code.
/// Note that this leaves the value uninitialized.
hash_code() = default;
/// Form a hash code directly from a numerical value.
hash_code(size_t value) : value(value) {}
/// Convert the hash code to its numerical value for use.
/*explicit*/ operator size_t() const { return value; }
friend bool operator==(const hash_code &lhs, const hash_code &rhs) {
return lhs.value == rhs.value;
}
friend bool operator!=(const hash_code &lhs, const hash_code &rhs) {
return lhs.value != rhs.value;
}
/// Allow a hash_code to be directly run through hash_value.
friend size_t hash_value(const hash_code &code) { return code.value; }
};
/// Compute a hash_code for any integer value.
///
/// Note that this function is intended to compute the same hash_code for
/// a particular value without regard to the pre-promotion type. This is in
/// contrast to hash_combine which may produce different hash_codes for
/// differing argument types even if they would implicit promote to a common
/// type without changing the value.
template <typename T>
std::enable_if_t<is_integral_or_enum<T>::value, hash_code> hash_value(T value);
/// Compute a hash_code for a pointer's address.
///
/// N.B.: This hashes the *address*. Not the value and not the type.
template <typename T> hash_code hash_value(const T *ptr);
/// Compute a hash_code for a pair of objects.
template <typename T, typename U>
hash_code hash_value(const std::pair<T, U> &arg);
/// Compute a hash_code for a tuple.
template <typename... Ts>
hash_code hash_value(const std::tuple<Ts...> &arg);
/// Compute a hash_code for a standard string.
template <typename T>
hash_code hash_value(const std::basic_string<T> &arg);
/// Compute a hash_code for a standard string.
template <typename T> hash_code hash_value(const std::optional<T> &arg);
// All of the implementation details of actually computing the various hash
// code values are held within this namespace. These routines are included in
// the header file mainly to allow inlining and constant propagation.
namespace hashing {
namespace detail {
inline uint64_t fetch64(const char *p) {
uint64_t result;
memcpy(&result, p, sizeof(result));
if (sys::IsBigEndianHost)
sys::swapByteOrder(result);
return result;
}
inline uint32_t fetch32(const char *p) {
uint32_t result;
memcpy(&result, p, sizeof(result));
if (sys::IsBigEndianHost)
sys::swapByteOrder(result);
return result;
}
/// Some primes between 2^63 and 2^64 for various uses.
static constexpr uint64_t k0 = 0xc3a5c85c97cb3127ULL;
static constexpr uint64_t k1 = 0xb492b66fbe98f273ULL;
static constexpr uint64_t k2 = 0x9ae16a3b2f90404fULL;
static constexpr uint64_t k3 = 0xc949d7c7509e6557ULL;
/// Bitwise right rotate.
/// Normally this will compile to a single instruction, especially if the
/// shift is a manifest constant.
inline uint64_t rotate(uint64_t val, size_t shift) {
// Avoid shifting by 64: doing so yields an undefined result.
return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
}
inline uint64_t shift_mix(uint64_t val) {
return val ^ (val >> 47);
}
inline uint64_t hash_16_bytes(uint64_t low, uint64_t high) {
// Murmur-inspired hashing.
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
uint64_t a = (low ^ high) * kMul;
a ^= (a >> 47);
uint64_t b = (high ^ a) * kMul;
b ^= (b >> 47);
b *= kMul;
return b;
}
inline uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed) {
uint8_t a = s[0];
uint8_t b = s[len >> 1];
uint8_t c = s[len - 1];
uint32_t y = static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8);
uint32_t z = static_cast<uint32_t>(len) + (static_cast<uint32_t>(c) << 2);
return shift_mix(y * k2 ^ z * k3 ^ seed) * k2;
}
inline uint64_t hash_4to8_bytes(const char *s, size_t len, uint64_t seed) {
uint64_t a = fetch32(s);
return hash_16_bytes(len + (a << 3), seed ^ fetch32(s + len - 4));
}
inline uint64_t hash_9to16_bytes(const char *s, size_t len, uint64_t seed) {
uint64_t a = fetch64(s);
uint64_t b = fetch64(s + len - 8);
return hash_16_bytes(seed ^ a, rotate(b + len, len)) ^ b;
}
inline uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed) {
uint64_t a = fetch64(s) * k1;
uint64_t b = fetch64(s + 8);
uint64_t c = fetch64(s + len - 8) * k2;
uint64_t d = fetch64(s + len - 16) * k0;
return hash_16_bytes(std::rotr<uint64_t>(a - b, 43) +
std::rotr<uint64_t>(c ^ seed, 30) + d,
a + std::rotr<uint64_t>(b ^ k3, 20) - c + len + seed);
}
inline uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed) {
uint64_t z = fetch64(s + 24);
uint64_t a = fetch64(s) + (len + fetch64(s + len - 16)) * k0;
uint64_t b = std::rotr<uint64_t>(a + z, 52);
uint64_t c = std::rotr<uint64_t>(a, 37);
a += fetch64(s + 8);
c += std::rotr<uint64_t>(a, 7);
a += fetch64(s + 16);
uint64_t vf = a + z;
uint64_t vs = b + std::rotr<uint64_t>(a, 31) + c;
a = fetch64(s + 16) + fetch64(s + len - 32);
z = fetch64(s + len - 8);
b = std::rotr<uint64_t>(a + z, 52);
c = std::rotr<uint64_t>(a, 37);
a += fetch64(s + len - 24);
c += std::rotr<uint64_t>(a, 7);
a += fetch64(s + len - 16);
uint64_t wf = a + z;
uint64_t ws = b + std::rotr<uint64_t>(a, 31) + c;
uint64_t r = shift_mix((vf + ws) * k2 + (wf + vs) * k0);
return shift_mix((seed ^ (r * k0)) + vs) * k2;
}
inline uint64_t hash_short(const char *s, size_t length, uint64_t seed) {
if (length >= 4 && length <= 8)
return hash_4to8_bytes(s, length, seed);
if (length > 8 && length <= 16)
return hash_9to16_bytes(s, length, seed);
if (length > 16 && length <= 32)
return hash_17to32_bytes(s, length, seed);
if (length > 32)
return hash_33to64_bytes(s, length, seed);
if (length != 0)
return hash_1to3_bytes(s, length, seed);
return k2 ^ seed;
}
/// The intermediate state used during hashing.
/// Currently, the algorithm for computing hash codes is based on CityHash and
/// keeps 56 bytes of arbitrary state.
struct hash_state {
uint64_t h0 = 0, h1 = 0, h2 = 0, h3 = 0, h4 = 0, h5 = 0, h6 = 0;
/// Create a new hash_state structure and initialize it based on the
/// seed and the first 64-byte chunk.
/// This effectively performs the initial mix.
static hash_state create(const char *s, uint64_t seed) {
hash_state state = {0,
seed,
hash_16_bytes(seed, k1),
std::rotr<uint64_t>(seed ^ k1, 49),
seed * k1,
shift_mix(seed),
0};
state.h6 = hash_16_bytes(state.h4, state.h5);
state.mix(s);
return state;
}
/// Mix 32-bytes from the input sequence into the 16-bytes of 'a'
/// and 'b', including whatever is already in 'a' and 'b'.
static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) {
a += fetch64(s);
uint64_t c = fetch64(s + 24);
b = std::rotr<uint64_t>(b + a + c, 21);
uint64_t d = a;
a += fetch64(s + 8) + fetch64(s + 16);
b += std::rotr<uint64_t>(a, 44) + d;
a += c;
}
/// Mix in a 64-byte buffer of data.
/// We mix all 64 bytes even when the chunk length is smaller, but we
/// record the actual length.
void mix(const char *s) {
h0 = std::rotr<uint64_t>(h0 + h1 + h3 + fetch64(s + 8), 37) * k1;
h1 = std::rotr<uint64_t>(h1 + h4 + fetch64(s + 48), 42) * k1;
h0 ^= h6;
h1 += h3 + fetch64(s + 40);
h2 = std::rotr<uint64_t>(h2 + h5, 33) * k1;
h3 = h4 * k1;
h4 = h0 + h5;
mix_32_bytes(s, h3, h4);
h5 = h2 + h6;
h6 = h1 + fetch64(s + 16);
mix_32_bytes(s + 32, h5, h6);
std::swap(h2, h0);
}
/// Compute the final 64-bit hash code value based on the current
/// state and the length of bytes hashed.
uint64_t finalize(size_t length) {
return hash_16_bytes(hash_16_bytes(h3, h5) + shift_mix(h1) * k1 + h2,
hash_16_bytes(h4, h6) + shift_mix(length) * k1 + h0);
}
};
/// In LLVM_ENABLE_ABI_BREAKING_CHECKS builds, the seed is non-deterministic
/// per process (address of a function in LLVMSupport) to prevent having users
/// depend on the particular hash values. On platforms without ASLR, this is
/// still likely non-deterministic per build.
inline uint64_t get_execution_seed() {
// Work around x86-64 negative offset folding for old Clang -fno-pic
// https://reviews.llvm.org/D93931
#if LLVM_ENABLE_ABI_BREAKING_CHECKS && \
(!defined(__clang__) || __clang_major__ > 11)
return static_cast<uint64_t>(
reinterpret_cast<uintptr_t>(&install_fatal_error_handler));
#else
return 0xff51afd7ed558ccdULL;
#endif
}
/// Trait to indicate whether a type's bits can be hashed directly.
///
/// A type trait which is true if we want to combine values for hashing by
/// reading the underlying data. It is false if values of this type must
/// first be passed to hash_value, and the resulting hash_codes combined.
//
// FIXME: We want to replace is_integral_or_enum and is_pointer here with
// a predicate which asserts that comparing the underlying storage of two
// values of the type for equality is equivalent to comparing the two values
// for equality. For all the platforms we care about, this holds for integers
// and pointers, but there are platforms where it doesn't and we would like to
// support user-defined types which happen to satisfy this property.
template <typename T> struct is_hashable_data
: std::integral_constant<bool, ((is_integral_or_enum<T>::value ||
std::is_pointer<T>::value) &&
64 % sizeof(T) == 0)> {};
// Special case std::pair to detect when both types are viable and when there
// is no alignment-derived padding in the pair. This is a bit of a lie because
// std::pair isn't truly POD, but it's close enough in all reasonable
// implementations for our use case of hashing the underlying data.
template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
: std::integral_constant<bool, (is_hashable_data<T>::value &&
is_hashable_data<U>::value &&
(sizeof(T) + sizeof(U)) ==
sizeof(std::pair<T, U>))> {};
/// Helper to get the hashable data representation for a type.
/// This variant is enabled when the type itself can be used.
template <typename T>
std::enable_if_t<is_hashable_data<T>::value, T>
get_hashable_data(const T &value) {
return value;
}
/// Helper to get the hashable data representation for a type.
/// This variant is enabled when we must first call hash_value and use the
/// result as our data.
template <typename T>
std::enable_if_t<!is_hashable_data<T>::value, size_t>
get_hashable_data(const T &value) {
using ::wpi::hash_value;
return hash_value(value);
}
/// Helper to store data from a value into a buffer and advance the
/// pointer into that buffer.
///
/// This routine first checks whether there is enough space in the provided
/// buffer, and if not immediately returns false. If there is space, it
/// copies the underlying bytes of value into the buffer, advances the
/// buffer_ptr past the copied bytes, and returns true.
template <typename T>
bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value,
size_t offset = 0) {
size_t store_size = sizeof(value) - offset;
if (buffer_ptr + store_size > buffer_end)
return false;
const char *value_data = reinterpret_cast<const char *>(&value);
memcpy(buffer_ptr, value_data + offset, store_size);
buffer_ptr += store_size;
return true;
}
/// Implement the combining of integral values into a hash_code.
///
/// This overload is selected when the value type of the iterator is
/// integral. Rather than computing a hash_code for each object and then
/// combining them, this (as an optimization) directly combines the integers.
template <typename InputIteratorT>
hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
const uint64_t seed = get_execution_seed();
char buffer[64], *buffer_ptr = buffer;
char *const buffer_end = std::end(buffer);
while (first != last && store_and_advance(buffer_ptr, buffer_end,
get_hashable_data(*first)))
++first;
if (first == last)
return hash_short(buffer, buffer_ptr - buffer, seed);
assert(buffer_ptr == buffer_end);
hash_state state = state.create(buffer, seed);
size_t length = 64;
while (first != last) {
// Fill up the buffer. We don't clear it, which re-mixes the last round
// when only a partial 64-byte chunk is left.
buffer_ptr = buffer;
while (first != last && store_and_advance(buffer_ptr, buffer_end,
get_hashable_data(*first)))
++first;
// Rotate the buffer if we did a partial fill in order to simulate doing
// a mix of the last 64-bytes. That is how the algorithm works when we
// have a contiguous byte sequence, and we want to emulate that here.
std::rotate(buffer, buffer_ptr, buffer_end);
// Mix this chunk into the current state.
state.mix(buffer);
length += buffer_ptr - buffer;
};
return state.finalize(length);
}
/// Implement the combining of integral values into a hash_code.
///
/// This overload is selected when the value type of the iterator is integral
/// and when the input iterator is actually a pointer. Rather than computing
/// a hash_code for each object and then combining them, this (as an
/// optimization) directly combines the integers. Also, because the integers
/// are stored in contiguous memory, this routine avoids copying each value
/// and directly reads from the underlying memory.
template <typename ValueT>
std::enable_if_t<is_hashable_data<ValueT>::value, hash_code>
hash_combine_range_impl(ValueT *first, ValueT *last) {
const uint64_t seed = get_execution_seed();
const char *s_begin = reinterpret_cast<const char *>(first);
const char *s_end = reinterpret_cast<const char *>(last);
const size_t length = std::distance(s_begin, s_end);
if (length <= 64)
return hash_short(s_begin, length, seed);
const char *s_aligned_end = s_begin + (length & ~63);
hash_state state = state.create(s_begin, seed);
s_begin += 64;
while (s_begin != s_aligned_end) {
state.mix(s_begin);
s_begin += 64;
}
if (length & 63)
state.mix(s_end - 64);
return state.finalize(length);
}
} // namespace detail
} // namespace hashing
/// Compute a hash_code for a sequence of values.
///
/// This hashes a sequence of values. It produces the same hash_code as
/// 'hash_combine(a, b, c, ...)', but can run over arbitrary sized sequences
/// and is significantly faster given pointers and types which can be hashed as
/// a sequence of bytes.
template <typename InputIteratorT>
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last) {
return ::wpi::hashing::detail::hash_combine_range_impl(first, last);
}
// Implementation details for hash_combine.
namespace hashing {
namespace detail {
/// Helper class to manage the recursive combining of hash_combine
/// arguments.
///
/// This class exists to manage the state and various calls involved in the
/// recursive combining of arguments used in hash_combine. It is particularly
/// useful at minimizing the code in the recursive calls to ease the pain
/// caused by a lack of variadic functions.
struct hash_combine_recursive_helper {
char buffer[64] = {};
hash_state state;
const uint64_t seed;
public:
/// Construct a recursive hash combining helper.
///
/// This sets up the state for a recursive hash combine, including getting
/// the seed and buffer setup.
hash_combine_recursive_helper()
: seed(get_execution_seed()) {}
/// Combine one chunk of data into the current in-flight hash.
///
/// This merges one chunk of data into the hash. First it tries to buffer
/// the data. If the buffer is full, it hashes the buffer into its
/// hash_state, empties it, and then merges the new chunk in. This also
/// handles cases where the data straddles the end of the buffer.
template <typename T>
char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data) {
if (!store_and_advance(buffer_ptr, buffer_end, data)) {
// Check for skew which prevents the buffer from being packed, and do
// a partial store into the buffer to fill it. This is only a concern
// with the variadic combine because that formation can have varying
// argument types.
size_t partial_store_size = buffer_end - buffer_ptr;
memcpy(buffer_ptr, &data, partial_store_size);
// If the store fails, our buffer is full and ready to hash. We have to
// either initialize the hash state (on the first full buffer) or mix
// this buffer into the existing hash state. Length tracks the *hashed*
// length, not the buffered length.
if (length == 0) {
state = state.create(buffer, seed);
length = 64;
} else {
// Mix this chunk into the current state and bump length up by 64.
state.mix(buffer);
length += 64;
}
// Reset the buffer_ptr to the head of the buffer for the next chunk of
// data.
buffer_ptr = buffer;
// Try again to store into the buffer -- this cannot fail as we only
// store types smaller than the buffer.
if (!store_and_advance(buffer_ptr, buffer_end, data,
partial_store_size))
wpi_unreachable("buffer smaller than stored type");
}
return buffer_ptr;
}
/// Recursive, variadic combining method.
///
/// This function recurses through each argument, combining that argument
/// into a single hash.
template <typename T, typename ...Ts>
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
const T &arg, const Ts &...args) {
buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg));
// Recurse to the next argument.
return combine(length, buffer_ptr, buffer_end, args...);
}
/// Base case for recursive, variadic combining.
///
/// The base case when combining arguments recursively is reached when all
/// arguments have been handled. It flushes the remaining buffer and
/// constructs a hash_code.
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end) {
// Check whether the entire set of values fit in the buffer. If so, we'll
// use the optimized short hashing routine and skip state entirely.
if (length == 0)
return hash_short(buffer, buffer_ptr - buffer, seed);
// Mix the final buffer, rotating it if we did a partial fill in order to
// simulate doing a mix of the last 64-bytes. That is how the algorithm
// works when we have a contiguous byte sequence, and we want to emulate
// that here.
std::rotate(buffer, buffer_ptr, buffer_end);
// Mix this chunk into the current state.
state.mix(buffer);
length += buffer_ptr - buffer;
return state.finalize(length);
}
};
} // namespace detail
} // namespace hashing
/// Combine values into a single hash_code.
///
/// This routine accepts a varying number of arguments of any type. It will
/// attempt to combine them into a single hash_code. For user-defined types it
/// attempts to call a \see hash_value overload (via ADL) for the type. For
/// integer and pointer types it directly combines their data into the
/// resulting hash_code.
///
/// The result is suitable for returning from a user's hash_value
/// *implementation* for their user-defined type. Consumers of a type should
/// *not* call this routine, they should instead call 'hash_value'.
template <typename ...Ts> hash_code hash_combine(const Ts &...args) {
// Recursively hash each argument using a helper class.
::wpi::hashing::detail::hash_combine_recursive_helper helper;
return helper.combine(0, helper.buffer, helper.buffer + 64, args...);
}
// Implementation details for implementations of hash_value overloads provided
// here.
namespace hashing {
namespace detail {
/// Helper to hash the value of a single integer.
///
/// Overloads for smaller integer types are not provided to ensure consistent
/// behavior in the presence of integral promotions. Essentially,
/// "hash_value('4')" and "hash_value('0' + 4)" should be the same.
inline hash_code hash_integer_value(uint64_t value) {
// Similar to hash_4to8_bytes but using a seed instead of length.
const uint64_t seed = get_execution_seed();
const char *s = reinterpret_cast<const char *>(&value);
const uint64_t a = fetch32(s);
return hash_16_bytes(seed + (a << 3), fetch32(s + 4));
}
} // namespace detail
} // namespace hashing
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T>
std::enable_if_t<is_integral_or_enum<T>::value, hash_code> hash_value(T value) {
return ::wpi::hashing::detail::hash_integer_value(
static_cast<uint64_t>(value));
}
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T> hash_code hash_value(const T *ptr) {
return ::wpi::hashing::detail::hash_integer_value(
reinterpret_cast<uintptr_t>(ptr));
}
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T, typename U>
hash_code hash_value(const std::pair<T, U> &arg) {
return hash_combine(arg.first, arg.second);
}
template <typename... Ts> hash_code hash_value(const std::tuple<Ts...> &arg) {
return std::apply([](const auto &...xs) { return hash_combine(xs...); }, arg);
}
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T>
hash_code hash_value(const std::basic_string<T> &arg) {
return hash_combine_range(arg.begin(), arg.end());
}
template <typename T> hash_code hash_value(const std::optional<T> &arg) {
return arg ? hash_combine(true, *arg) : hash_value(false);
}
template <> struct DenseMapInfo<hash_code, void> {
static inline hash_code getEmptyKey() { return hash_code(-1); }
static inline hash_code getTombstoneKey() { return hash_code(-2); }
static unsigned getHashValue(hash_code val) {
return static_cast<unsigned>(size_t(val));
}
static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; }
};
} // namespace wpi
/// Implement std::hash so that hash_code can be used in STL containers.
namespace std {
template<>
struct hash<wpi::hash_code> {
size_t operator()(wpi::hash_code const& Val) const {
return Val;
}
};
} // namespace std;
#ifdef _WIN32
#pragma warning(pop)
#endif
#endif

View File

@@ -1,259 +0,0 @@
//===- llvm/ADT/MapVector.h - Map w/ deterministic value order --*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements a map that provides insertion order iteration. The
/// interface is purposefully minimal. The key is assumed to be cheap to copy
/// and 2 copies are kept, one for indexing in a DenseMap, one for iteration in
/// a SmallVector.
///
//===----------------------------------------------------------------------===//
#ifndef WPIUTIL_WPI_MAPVECTOR_H
#define WPIUTIL_WPI_MAPVECTOR_H
#include "wpi/DenseMap.h"
#include "wpi/SmallVector.h"
#include <cassert>
#include <cstddef>
#include <iterator>
#include <type_traits>
#include <utility>
namespace wpi {
/// This class implements a map that also provides access to all stored values
/// in a deterministic order. The values are kept in a SmallVector<*, 0> and the
/// mapping is done with DenseMap from Keys to indexes in that vector.
template <typename KeyT, typename ValueT,
typename MapType = DenseMap<KeyT, unsigned>,
typename VectorType = SmallVector<std::pair<KeyT, ValueT>, 0>>
class MapVector {
MapType Map;
VectorType Vector;
static_assert(
std::is_integral_v<typename MapType::mapped_type>,
"The mapped_type of the specified Map must be an integral type");
public:
using key_type = KeyT;
using value_type = typename VectorType::value_type;
using size_type = typename VectorType::size_type;
using iterator = typename VectorType::iterator;
using const_iterator = typename VectorType::const_iterator;
using reverse_iterator = typename VectorType::reverse_iterator;
using const_reverse_iterator = typename VectorType::const_reverse_iterator;
/// Clear the MapVector and return the underlying vector.
VectorType takeVector() {
Map.clear();
return std::move(Vector);
}
size_type size() const { return Vector.size(); }
/// Grow the MapVector so that it can contain at least \p NumEntries items
/// before resizing again.
void reserve(size_type NumEntries) {
Map.reserve(NumEntries);
Vector.reserve(NumEntries);
}
iterator begin() { return Vector.begin(); }
const_iterator begin() const { return Vector.begin(); }
iterator end() { return Vector.end(); }
const_iterator end() const { return Vector.end(); }
reverse_iterator rbegin() { return Vector.rbegin(); }
const_reverse_iterator rbegin() const { return Vector.rbegin(); }
reverse_iterator rend() { return Vector.rend(); }
const_reverse_iterator rend() const { return Vector.rend(); }
bool empty() const {
return Vector.empty();
}
std::pair<KeyT, ValueT> &front() { return Vector.front(); }
const std::pair<KeyT, ValueT> &front() const { return Vector.front(); }
std::pair<KeyT, ValueT> &back() { return Vector.back(); }
const std::pair<KeyT, ValueT> &back() const { return Vector.back(); }
void clear() {
Map.clear();
Vector.clear();
}
void swap(MapVector &RHS) {
std::swap(Map, RHS.Map);
std::swap(Vector, RHS.Vector);
}
ValueT &operator[](const KeyT &Key) {
std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(Key, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
auto &I = Result.first->second;
if (Result.second) {
Vector.push_back(std::make_pair(Key, ValueT()));
I = Vector.size() - 1;
}
return Vector[I].second;
}
// Returns a copy of the value. Only allowed if ValueT is copyable.
ValueT lookup(const KeyT &Key) const {
static_assert(std::is_copy_constructible_v<ValueT>,
"Cannot call lookup() if ValueT is not copyable.");
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
}
template <typename... Ts>
std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&...Args) {
auto [It, Inserted] = Map.insert(std::make_pair(Key, 0));
if (Inserted) {
It->second = Vector.size();
Vector.emplace_back(std::piecewise_construct, std::forward_as_tuple(Key),
std::forward_as_tuple(std::forward<Ts>(Args)...));
return std::make_pair(std::prev(end()), true);
}
return std::make_pair(begin() + It->second, false);
}
template <typename... Ts>
std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&...Args) {
auto [It, Inserted] = Map.insert(std::make_pair(Key, 0));
if (Inserted) {
It->second = Vector.size();
Vector.emplace_back(std::piecewise_construct,
std::forward_as_tuple(std::move(Key)),
std::forward_as_tuple(std::forward<Ts>(Args)...));
return std::make_pair(std::prev(end()), true);
}
return std::make_pair(begin() + It->second, false);
}
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
return try_emplace(KV.first, KV.second);
}
std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
return try_emplace(std::move(KV.first), std::move(KV.second));
}
template <typename V>
std::pair<iterator, bool> insert_or_assign(const KeyT &Key, V &&Val) {
auto Ret = try_emplace(Key, std::forward<V>(Val));
if (!Ret.second)
Ret.first->second = std::forward<V>(Val);
return Ret;
}
template <typename V>
std::pair<iterator, bool> insert_or_assign(KeyT &&Key, V &&Val) {
auto Ret = try_emplace(std::move(Key), std::forward<V>(Val));
if (!Ret.second)
Ret.first->second = std::forward<V>(Val);
return Ret;
}
bool contains(const KeyT &Key) const { return Map.find(Key) != Map.end(); }
size_type count(const KeyT &Key) const { return contains(Key) ? 1 : 0; }
iterator find(const KeyT &Key) {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? Vector.end() :
(Vector.begin() + Pos->second);
}
const_iterator find(const KeyT &Key) const {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? Vector.end() :
(Vector.begin() + Pos->second);
}
/// Remove the last element from the vector.
void pop_back() {
typename MapType::iterator Pos = Map.find(Vector.back().first);
Map.erase(Pos);
Vector.pop_back();
}
/// Remove the element given by Iterator.
///
/// Returns an iterator to the element following the one which was removed,
/// which may be end().
///
/// \note This is a deceivingly expensive operation (linear time). It's
/// usually better to use \a remove_if() if possible.
typename VectorType::iterator erase(typename VectorType::iterator Iterator) {
Map.erase(Iterator->first);
auto Next = Vector.erase(Iterator);
if (Next == Vector.end())
return Next;
// Update indices in the map.
size_t Index = Next - Vector.begin();
for (auto &I : Map) {
assert(I.second != Index && "Index was already erased!");
if (I.second > Index)
--I.second;
}
return Next;
}
/// Remove all elements with the key value Key.
///
/// Returns the number of elements removed.
size_type erase(const KeyT &Key) {
auto Iterator = find(Key);
if (Iterator == end())
return 0;
erase(Iterator);
return 1;
}
/// Remove the elements that match the predicate.
///
/// Erase all elements that match \c Pred in a single pass. Takes linear
/// time.
template <class Predicate> void remove_if(Predicate Pred);
};
template <typename KeyT, typename ValueT, typename MapType, typename VectorType>
template <class Function>
void MapVector<KeyT, ValueT, MapType, VectorType>::remove_if(Function Pred) {
auto O = Vector.begin();
for (auto I = O, E = Vector.end(); I != E; ++I) {
if (Pred(*I)) {
// Erase from the map.
Map.erase(I->first);
continue;
}
if (I != O) {
// Move the value and update the index in the map.
*O = std::move(*I);
Map[O->first] = O - Vector.begin();
}
++O;
}
// Erase trailing entries in the vector.
Vector.erase(O, Vector.end());
}
/// A MapVector that performs no allocations if smaller than a certain
/// size.
template <typename KeyT, typename ValueT, unsigned N>
struct SmallMapVector
: MapVector<KeyT, ValueT, SmallDenseMap<KeyT, unsigned, N>,
SmallVector<std::pair<KeyT, ValueT>, N>> {
};
} // end namespace wpi
#endif // WPIUTIL_WPI_MAPVECTOR_H

View File

@@ -471,13 +471,21 @@ constexpr uint64_t alignTo(uint64_t Value, uint64_t Align) {
return CeilDiv * Align;
}
/// Will overflow only if result is not representable in T.
template <typename U, typename V, typename T = common_uint<U, V>>
constexpr T alignToPowerOf2(U Value, V Align) {
assert(Align != 0 && (Align & (Align - 1)) == 0 &&
"Align must be a power of 2");
T NegAlign = static_cast<T>(0) - Align;
return (Value + (Align - 1)) & NegAlign;
}
/// Fallback when arguments aren't integral.
constexpr uint64_t alignToPowerOf2(uint64_t Value, uint64_t Align) {
assert(Align != 0 && (Align & (Align - 1)) == 0 &&
"Align must be a power of 2");
// Replace unary minus to avoid compilation error on Windows:
// "unary minus operator applied to unsigned type, result still unsigned"
uint64_t NegAlign = (~Align) + 1;
return (Value + Align - 1) & NegAlign;
uint64_t NegAlign = 0 - Align;
return (Value + (Align - 1)) & NegAlign;
}
/// If non-zero \p Skew is specified, the return value will be a minimal integer

View File

@@ -192,12 +192,18 @@ public:
// isa<T>, cast<T> and the wpi::dyn_cast<T>
/// Test if the Union currently holds the type matching T.
template <typename T> inline bool is() const { return isa<T>(*this); }
template <typename T>
[[deprecated("Use isa instead")]]
inline bool is() const {
return isa<T>(*this);
}
/// Returns the value of the specified pointer type.
///
/// If the specified pointer type is incorrect, assert.
template <typename T> inline T get() const {
template <typename T>
[[deprecated("Use cast instead")]]
inline T get() const {
assert(isa<T>(*this) && "Invalid accessor called");
return cast<T>(*this);
}

View File

@@ -16,9 +16,10 @@
#define WPIUTIL_WPI_SMALLPTRSET_H
#include "wpi/EpochTracker.h"
#include "wpi/Compiler.h"
#include "wpi/MathExtras.h"
#include "wpi/ReverseIteration.h"
#include "wpi/type_traits.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdlib>
@@ -52,10 +53,7 @@ class SmallPtrSetImplBase : public DebugEpochBase {
friend class SmallPtrSetIteratorImpl;
protected:
/// SmallArray - Points to a fixed size set of buckets, used in 'small mode'.
const void **SmallArray;
/// CurArray - This is the current set of buckets. If equal to SmallArray,
/// then the set is in 'small mode'.
/// The current set of buckets, in either small or big representation.
const void **CurArray;
/// CurArraySize - The allocated size of CurArray, always a power of two.
unsigned CurArraySize;
@@ -66,16 +64,18 @@ protected:
unsigned NumNonEmpty;
/// Number of tombstones in CurArray.
unsigned NumTombstones;
/// Whether the set is in small representation.
bool IsSmall;
// Helpers to copy and move construct a SmallPtrSet.
SmallPtrSetImplBase(const void **SmallStorage,
const SmallPtrSetImplBase &that);
SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize,
SmallPtrSetImplBase &&that);
const void **RHSSmallStorage, SmallPtrSetImplBase &&that);
explicit SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize)
: SmallArray(SmallStorage), CurArray(SmallStorage),
CurArraySize(SmallSize), NumNonEmpty(0), NumTombstones(0) {
: CurArray(SmallStorage), CurArraySize(SmallSize), NumNonEmpty(0),
NumTombstones(0), IsSmall(true) {
assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
"Initial size must be a power of two!");
}
@@ -92,6 +92,7 @@ public:
[[nodiscard]] bool empty() const { return size() == 0; }
size_type size() const { return NumNonEmpty - NumTombstones; }
size_type capacity() const { return CurArraySize; }
void clear() {
incrementEpoch();
@@ -108,6 +109,27 @@ public:
NumTombstones = 0;
}
void reserve(size_type NumEntries) {
incrementEpoch();
// Do nothing if we're given zero as a reservation size.
if (NumEntries == 0)
return;
// No need to expand if we're small and NumEntries will fit in the space.
if (isSmall() && NumEntries <= CurArraySize)
return;
// insert_imp_big will reallocate if stores is more than 75% full, on the
// /final/ insertion.
if (!isSmall() && ((NumEntries - 1) * 4) < (CurArraySize * 3))
return;
// We must Grow -- find the size where we'd be 75% full, then round up to
// the next power of two.
size_type NewSize = NumEntries + (NumEntries / 3);
NewSize = 1 << (Log2_32_Ceil(NewSize) + 1);
// Like insert_imp_big, always allocate at least 128 elements.
NewSize = (std::max)(128u, NewSize);
Grow(NewSize);
}
protected:
static void *getTombstoneMarker() { return reinterpret_cast<void*>(-2); }
@@ -127,7 +149,7 @@ protected:
std::pair<const void *const *, bool> insert_imp(const void *Ptr) {
if (isSmall()) {
// Check to see if it is already in the set.
for (const void **APtr = SmallArray, **E = SmallArray + NumNonEmpty;
for (const void **APtr = CurArray, **E = CurArray + NumNonEmpty;
APtr != E; ++APtr) {
const void *Value = *APtr;
if (Value == Ptr)
@@ -136,9 +158,9 @@ protected:
// Nope, there isn't. If we stay small, just 'pushback' now.
if (NumNonEmpty < CurArraySize) {
SmallArray[NumNonEmpty++] = Ptr;
CurArray[NumNonEmpty++] = Ptr;
incrementEpoch();
return std::make_pair(SmallArray + (NumNonEmpty - 1), true);
return std::make_pair(CurArray + (NumNonEmpty - 1), true);
}
// Otherwise, hit the big set case, which will call grow.
}
@@ -151,10 +173,10 @@ protected:
/// in.
bool erase_imp(const void * Ptr) {
if (isSmall()) {
for (const void **APtr = SmallArray, **E = SmallArray + NumNonEmpty;
for (const void **APtr = CurArray, **E = CurArray + NumNonEmpty;
APtr != E; ++APtr) {
if (*APtr == Ptr) {
*APtr = SmallArray[--NumNonEmpty];
*APtr = CurArray[--NumNonEmpty];
incrementEpoch();
return true;
}
@@ -162,8 +184,8 @@ protected:
return false;
}
auto *Bucket = FindBucketFor(Ptr);
if (*Bucket != Ptr)
auto *Bucket = doFind(Ptr);
if (!Bucket)
return false;
*const_cast<const void **>(Bucket) = getTombstoneMarker();
@@ -180,25 +202,40 @@ protected:
const void *const * find_imp(const void * Ptr) const {
if (isSmall()) {
// Linear search for the item.
for (const void *const *APtr = SmallArray,
*const *E = SmallArray + NumNonEmpty; APtr != E; ++APtr)
for (const void *const *APtr = CurArray, *const *E =
CurArray + NumNonEmpty;
APtr != E; ++APtr)
if (*APtr == Ptr)
return APtr;
return EndPointer();
}
// Big set case.
auto *Bucket = FindBucketFor(Ptr);
if (*Bucket == Ptr)
if (auto *Bucket = doFind(Ptr))
return Bucket;
return EndPointer();
}
bool isSmall() const { return CurArray == SmallArray; }
bool contains_imp(const void *Ptr) const {
if (isSmall()) {
// Linear search for the item.
const void *const *APtr = CurArray;
const void *const *E = CurArray + NumNonEmpty;
for (; APtr != E; ++APtr)
if (*APtr == Ptr)
return true;
return false;
}
return doFind(Ptr) != nullptr;
}
bool isSmall() const { return IsSmall; }
private:
std::pair<const void *const *, bool> insert_imp_big(const void *Ptr);
const void *const *doFind(const void *Ptr) const;
const void * const *FindBucketFor(const void *Ptr) const;
void shrink_and_clear();
@@ -208,16 +245,19 @@ private:
protected:
/// swap - Swaps the elements of two sets.
/// Note: This method assumes that both sets have the same small size.
void swap(SmallPtrSetImplBase &RHS);
void swap(const void **SmallStorage, const void **RHSSmallStorage,
SmallPtrSetImplBase &RHS);
void CopyFrom(const SmallPtrSetImplBase &RHS);
void MoveFrom(unsigned SmallSize, SmallPtrSetImplBase &&RHS);
void copyFrom(const void **SmallStorage, const SmallPtrSetImplBase &RHS);
void moveFrom(const void **SmallStorage, unsigned SmallSize,
const void **RHSSmallStorage, SmallPtrSetImplBase &&RHS);
private:
/// Code shared by MoveFrom() and move constructor.
void MoveHelper(unsigned SmallSize, SmallPtrSetImplBase &&RHS);
/// Code shared by CopyFrom() and copy constructor.
void CopyHelper(const SmallPtrSetImplBase &RHS);
/// Code shared by moveFrom() and move constructor.
void moveHelper(const void **SmallStorage, unsigned SmallSize,
const void **RHSSmallStorage, SmallPtrSetImplBase &&RHS);
/// Code shared by copyFrom() and copy constructor.
void copyHelper(const SmallPtrSetImplBase &RHS);
};
/// SmallPtrSetIteratorImpl - This is the common base class shared between all
@@ -378,7 +418,7 @@ public:
bool remove_if(UnaryPredicate P) {
bool Removed = false;
if (isSmall()) {
const void **APtr = SmallArray, **E = SmallArray + NumNonEmpty;
const void **APtr = CurArray, **E = CurArray + NumNonEmpty;
while (APtr != E) {
PtrType Ptr = PtrTraits::getFromVoidPointer(const_cast<void *>(*APtr));
if (P(Ptr)) {
@@ -410,13 +450,13 @@ public:
/// count - Return 1 if the specified pointer is in the set, 0 otherwise.
size_type count(ConstPtrType Ptr) const {
return find_imp(ConstPtrTraits::getAsVoidPointer(Ptr)) != EndPointer();
return contains_imp(ConstPtrTraits::getAsVoidPointer(Ptr));
}
iterator find(ConstPtrType Ptr) const {
return makeIterator(find_imp(ConstPtrTraits::getAsVoidPointer(Ptr)));
}
bool contains(ConstPtrType Ptr) const {
return find_imp(ConstPtrTraits::getAsVoidPointer(Ptr)) != EndPointer();
return contains_imp(ConstPtrTraits::getAsVoidPointer(Ptr));
}
template <typename IterT>
@@ -503,7 +543,8 @@ public:
SmallPtrSet() : BaseT(SmallStorage, SmallSizePowTwo) {}
SmallPtrSet(const SmallPtrSet &that) : BaseT(SmallStorage, that) {}
SmallPtrSet(SmallPtrSet &&that)
: BaseT(SmallStorage, SmallSizePowTwo, std::move(that)) {}
: BaseT(SmallStorage, SmallSizePowTwo, that.SmallStorage,
std::move(that)) {}
template<typename It>
SmallPtrSet(It I, It E) : BaseT(SmallStorage, SmallSizePowTwo) {
@@ -518,14 +559,15 @@ public:
SmallPtrSet<PtrType, SmallSize> &
operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
if (&RHS != this)
this->CopyFrom(RHS);
this->copyFrom(SmallStorage, RHS);
return *this;
}
SmallPtrSet<PtrType, SmallSize> &
operator=(SmallPtrSet<PtrType, SmallSize> &&RHS) {
if (&RHS != this)
this->MoveFrom(SmallSizePowTwo, std::move(RHS));
this->moveFrom(SmallStorage, SmallSizePowTwo, RHS.SmallStorage,
std::move(RHS));
return *this;
}
@@ -538,7 +580,7 @@ public:
/// swap - Swaps the elements of two sets.
void swap(SmallPtrSet<PtrType, SmallSize> &RHS) {
SmallPtrSetImplBase::swap(RHS);
SmallPtrSetImplBase::swap(SmallStorage, RHS.SmallStorage, RHS);
}
};

View File

@@ -17,13 +17,10 @@
#include "wpi/SmallPtrSet.h"
#include "wpi/SmallVector.h"
#include "wpi/iterator.h"
#include "wpi/Compiler.h"
#include "wpi/type_traits.h"
#include <cstddef>
#include <functional>
#include <optional>
#include <initializer_list>
#include <set>
#include <type_traits>
#include <utility>
namespace wpi {
@@ -46,24 +43,24 @@ private:
VecIterTy VecIter;
};
bool isSmall;
bool IsSmall;
public:
SmallSetIterator(SetIterTy SetIter) : SetIter(SetIter), isSmall(false) {}
SmallSetIterator(SetIterTy SetIter) : SetIter(SetIter), IsSmall(false) {}
SmallSetIterator(VecIterTy VecIter) : VecIter(VecIter), isSmall(true) {}
SmallSetIterator(VecIterTy VecIter) : VecIter(VecIter), IsSmall(true) {}
// Spell out destructor, copy/move constructor and assignment operators for
// MSVC STL, where set<T>::const_iterator is not trivially copy constructible.
~SmallSetIterator() {
if (isSmall)
if (IsSmall)
VecIter.~VecIterTy();
else
SetIter.~SetIterTy();
}
SmallSetIterator(const SmallSetIterator &Other) : isSmall(Other.isSmall) {
if (isSmall)
SmallSetIterator(const SmallSetIterator &Other) : IsSmall(Other.IsSmall) {
if (IsSmall)
VecIter = Other.VecIter;
else
// Use placement new, to make sure SetIter is properly constructed, even
@@ -71,8 +68,8 @@ public:
new (&SetIter) SetIterTy(Other.SetIter);
}
SmallSetIterator(SmallSetIterator &&Other) : isSmall(Other.isSmall) {
if (isSmall)
SmallSetIterator(SmallSetIterator &&Other) : IsSmall(Other.IsSmall) {
if (IsSmall)
VecIter = std::move(Other.VecIter);
else
// Use placement new, to make sure SetIter is properly constructed, even
@@ -83,11 +80,11 @@ public:
SmallSetIterator& operator=(const SmallSetIterator& Other) {
// Call destructor for SetIter, so it gets properly destroyed if it is
// not trivially destructible in case we are setting VecIter.
if (!isSmall)
if (!IsSmall)
SetIter.~SetIterTy();
isSmall = Other.isSmall;
if (isSmall)
IsSmall = Other.IsSmall;
if (IsSmall)
VecIter = Other.VecIter;
else
new (&SetIter) SetIterTy(Other.SetIter);
@@ -97,11 +94,11 @@ public:
SmallSetIterator& operator=(SmallSetIterator&& Other) {
// Call destructor for SetIter, so it gets properly destroyed if it is
// not trivially destructible in case we are setting VecIter.
if (!isSmall)
if (!IsSmall)
SetIter.~SetIterTy();
isSmall = Other.isSmall;
if (isSmall)
IsSmall = Other.IsSmall;
if (IsSmall)
VecIter = std::move(Other.VecIter);
else
new (&SetIter) SetIterTy(std::move(Other.SetIter));
@@ -109,22 +106,22 @@ public:
}
bool operator==(const SmallSetIterator &RHS) const {
if (isSmall != RHS.isSmall)
if (IsSmall != RHS.IsSmall)
return false;
if (isSmall)
if (IsSmall)
return VecIter == RHS.VecIter;
return SetIter == RHS.SetIter;
}
SmallSetIterator &operator++() { // Preincrement
if (isSmall)
VecIter++;
if (IsSmall)
++VecIter;
else
SetIter++;
++SetIter;
return *this;
}
const T &operator*() const { return isSmall ? *VecIter : *SetIter; }
const T &operator*() const { return IsSmall ? *VecIter : *SetIter; }
};
/// SmallSet - This maintains a set of unique values, optimizing for the case
@@ -139,10 +136,6 @@ class SmallSet {
SmallVector<T, N> Vector;
std::set<T, C> Set;
using VIterator = typename SmallVector<T, N>::const_iterator;
using SIterator = typename std::set<T, C>::const_iterator;
using mutable_iterator = typename SmallVector<T, N>::iterator;
// In small mode SmallPtrSet uses linear search for the elements, so it is
// not a good idea to choose this value too high. You may consider using a
// DenseSet<> instead if you expect many elements in the set.
@@ -155,6 +148,22 @@ public:
using const_iterator = SmallSetIterator<T, N, C>;
SmallSet() = default;
SmallSet(const SmallSet &) = default;
SmallSet(SmallSet &&) = default;
template <typename IterT> SmallSet(IterT Begin, IterT End) {
insert(Begin, End);
}
template <typename RangeT>
explicit SmallSet(const iterator_range<RangeT> &R) {
insert(R.begin(), R.end());
}
SmallSet(std::initializer_list<T> L) { insert(L.begin(), L.end()); }
SmallSet &operator=(const SmallSet &) = default;
SmallSet &operator=(SmallSet &&) = default;
[[nodiscard]] bool empty() const { return Vector.empty() && Set.empty(); }
@@ -163,39 +172,16 @@ public:
}
/// count - Return 1 if the element is in the set, 0 otherwise.
size_type count(const T &V) const {
if (isSmall()) {
// Since the collection is small, just do a linear search.
return vfind(V) == Vector.end() ? 0 : 1;
} else {
return Set.count(V);
}
}
size_type count(const T &V) const { return contains(V) ? 1 : 0; }
/// insert - Insert an element into the set if it isn't already there.
/// Returns a pair. The first value of it is an iterator to the inserted
/// element or the existing element in the set. The second value is true
/// if the element is inserted (it was not in the set before).
std::pair<const_iterator, bool> insert(const T &V) {
if (!isSmall()) {
auto [I, Inserted] = Set.insert(V);
return std::make_pair(const_iterator(I), Inserted);
}
std::pair<const_iterator, bool> insert(const T &V) { return insertImpl(V); }
VIterator I = vfind(V);
if (I != Vector.end()) // Don't reinsert if it already exists.
return std::make_pair(const_iterator(I), false);
if (Vector.size() < N) {
Vector.push_back(V);
return std::make_pair(const_iterator(std::prev(Vector.end())), true);
}
// Otherwise, grow from vector to set.
while (!Vector.empty()) {
Set.insert(Vector.back());
Vector.pop_back();
}
return std::make_pair(const_iterator(Set.insert(V).first), true);
std::pair<const_iterator, bool> insert(T &&V) {
return insertImpl(std::move(V));
}
template <typename IterT>
@@ -207,11 +193,11 @@ public:
bool erase(const T &V) {
if (!isSmall())
return Set.erase(V);
for (mutable_iterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
if (*I == V) {
Vector.erase(I);
return true;
}
auto I = vfind(V);
if (I != Vector.end()) {
Vector.erase(I);
return true;
}
return false;
}
@@ -242,8 +228,33 @@ public:
private:
bool isSmall() const { return Set.empty(); }
VIterator vfind(const T &V) const {
for (VIterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
template <typename ArgType>
std::pair<const_iterator, bool> insertImpl(ArgType &&V) {
static_assert(std::is_convertible_v<ArgType, T>,
"ArgType must be convertible to T!");
if (!isSmall()) {
auto [I, Inserted] = Set.insert(std::forward<ArgType>(V));
return {const_iterator(I), Inserted};
}
auto I = vfind(V);
if (I != Vector.end()) // Don't reinsert if it already exists.
return {const_iterator(I), false};
if (Vector.size() < N) {
Vector.push_back(std::forward<ArgType>(V));
return {const_iterator(std::prev(Vector.end())), true};
}
// Otherwise, grow from vector to set.
Set.insert(std::make_move_iterator(Vector.begin()),
std::make_move_iterator(Vector.end()));
Vector.clear();
return {const_iterator(Set.insert(std::forward<ArgType>(V)).first), true};
}
// Handwritten linear search. The use of std::find might hurt performance as
// its implementation may be optimized for larger containers.
typename SmallVector<T, N>::const_iterator vfind(const T &V) const {
for (auto I = Vector.begin(), E = Vector.end(); I != E; ++I)
if (*I == V)
return I;
return Vector.end();

View File

@@ -23,7 +23,6 @@
#endif
#include "wpi/Compiler.h"
#include "wpi/type_traits.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -82,19 +81,6 @@ protected:
/// This function will report a fatal error if it cannot increase capacity.
void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
/// If vector was first created with capacity 0, getFirstEl() points to the
/// memory right after, an area unallocated. If a subsequent allocation,
/// that grows the vector, happens to return the same pointer as getFirstEl(),
/// get a new allocation, otherwise isSmall() will falsely return that no
/// allocation was done (true) and the memory will not be freed in the
/// destructor. If a VSize is given (vector size), also copy that many
/// elements to the new allocation - used if realloca fails to increase
/// space, and happens to allocate precisely at BeginX.
/// This is unlikely to be called often, but resolves a memory leak when the
/// situation does occur.
void *replaceAllocation(void *NewElts, size_t TSize, size_t NewCapacity,
size_t VSize = 0);
public:
size_t size() const { return Size; }
size_t capacity() const { return Capacity; }

View File

@@ -15,13 +15,11 @@
#define WPIUTIL_WPI_VERSIONTUPLE_H
#include "wpi/DenseMapInfo.h"
#include "wpi/Hashing.h"
#include <optional>
#include <string>
#include <tuple>
namespace wpi {
template <typename HasherT, wpi::endianness Endianness> class HashBuilder;
class raw_ostream;
/// Represents a version number in the form major[.minor[.subminor[.build]]].

View File

@@ -43,7 +43,8 @@ class iterator_range {
IteratorT begin_iterator, end_iterator;
public:
#if __GNUC__ == 7 || (__GNUC__ == 8 && __GNUC_MINOR__ < 4)
#if defined(__GNUC__) && \
(__GNUC__ == 7 || (__GNUC__ == 8 && __GNUC_MINOR__ < 4))
// Be careful no to break gcc-7 and gcc-8 < 8.4 on the mlir target.
// See https://github.com/llvm/llvm-project/issues/63843
template <typename Container>

View File

@@ -147,7 +147,7 @@ public:
/// So that the stream could keep at least tell() + ExtraSize bytes
/// without re-allocations. reserveExtraSpace() does not change
/// the size/data of the stream.
virtual void reserveExtraSpace(uint64_t ExtraSize) {}
virtual void reserveExtraSpace(uint64_t ExtraSize) { (void)ExtraSize; }
/// Set the stream to be buffered, with an automatically determined buffer
/// size.

View File

@@ -1,81 +0,0 @@
/*
xxHash - Extremely Fast Hash algorithm
Header File
Copyright (C) 2012-2016, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at :
- xxHash source repository : https://github.com/Cyan4973/xxHash
*/
/* based on revision d2df04efcbef7d7f6886d345861e5dfda4edacc1 Removed
* everything but a simple interface for computing XXh64. */
#ifndef WPIUTIL_WPI_XXHASH_H
#define WPIUTIL_WPI_XXHASH_H
#include <stdint.h>
#include <span>
#include <string_view>
namespace wpi {
uint64_t xxHash64(std::string_view Data);
uint64_t xxHash64(std::span<const uint8_t> Data);
uint64_t xxh3_64bits(std::span<const uint8_t> data);
inline uint64_t xxh3_64bits(std::string_view data) {
return xxh3_64bits(std::span(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
}
/*-**********************************************************************
* XXH3 128-bit variant
************************************************************************/
/*!
* @brief The return value from 128-bit hashes.
*
* Stored in little endian order, although the fields themselves are in native
* endianness.
*/
struct XXH128_hash_t {
uint64_t low64; /*!< `value & 0xFFFFFFFFFFFFFFFF` */
uint64_t high64; /*!< `value >> 64` */
/// Convenience equality check operator.
bool operator==(const XXH128_hash_t rhs) const {
return low64 == rhs.low64 && high64 == rhs.high64;
}
};
/// XXH3's 128-bit variant.
XXH128_hash_t xxh3_128bits(std::span<const uint8_t> data);
} // namespace wpi
#endif

View File

@@ -10,6 +10,8 @@
using namespace wpi;
int CountCopyAndMove::DefaultConstructions = 0;
int CountCopyAndMove::ValueConstructions = 0;
int CountCopyAndMove::CopyConstructions = 0;
int CountCopyAndMove::CopyAssignments = 0;
int CountCopyAndMove::MoveConstructions = 0;

View File

@@ -12,6 +12,8 @@
namespace wpi {
struct CountCopyAndMove {
static int DefaultConstructions;
static int ValueConstructions;
static int CopyConstructions;
static int CopyAssignments;
static int MoveConstructions;
@@ -19,8 +21,8 @@ struct CountCopyAndMove {
static int Destructions;
int val;
CountCopyAndMove() = default;
explicit CountCopyAndMove(int val) : val(val) {}
CountCopyAndMove() { ++DefaultConstructions; }
explicit CountCopyAndMove(int val) : val(val) { ++ValueConstructions; }
CountCopyAndMove(const CountCopyAndMove &other) : val(other.val) {
++CopyConstructions;
}
@@ -40,6 +42,8 @@ struct CountCopyAndMove {
~CountCopyAndMove() { ++Destructions; }
static void ResetCounts() {
DefaultConstructions = 0;
ValueConstructions = 0;
CopyConstructions = 0;
CopyAssignments = 0;
MoveConstructions = 0;
@@ -47,6 +51,11 @@ struct CountCopyAndMove {
Destructions = 0;
}
static int TotalConstructions() {
return DefaultConstructions + ValueConstructions + MoveConstructions +
CopyConstructions;
}
static int TotalCopies() { return CopyConstructions + CopyAssignments; }
static int TotalMoves() { return MoveConstructions + MoveAssignments; }

View File

@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "wpi/FunctionExtras.h"
#include "CountCopyAndMove.h"
#include "gtest/gtest.h"
#include <memory>
@@ -310,4 +311,43 @@ class Incomplete {};
Incomplete incompleteFunction() { return {}; }
const Incomplete incompleteFunctionConst() { return {}; }
// Check that we can store a pointer-sized payload inline in the unique_function.
TEST(UniqueFunctionTest, InlineStorageWorks) {
// We do assume a couple of implementation details of the unique_function here:
// - It can store certain small-enough payload inline
// - Inline storage size is at least >= sizeof(void*)
void *ptr = nullptr;
unique_function<void(void *)> UniqueFunctionWithInlineStorage{
[ptr](void *self) {
auto mid = reinterpret_cast<uintptr_t>(&ptr);
auto beg = reinterpret_cast<uintptr_t>(self);
auto end = reinterpret_cast<uintptr_t>(self) +
sizeof(unique_function<void(void *)>);
// Make sure the address of the captured pointer lies somewhere within
// the unique_function object.
EXPECT_TRUE(mid >= beg && mid < end);
}};
UniqueFunctionWithInlineStorage(&UniqueFunctionWithInlineStorage);
}
// GCC warns that val in CountCopyAndMove is uninitialized
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
// Check that the moved-from captured state is properly destroyed during
// move construction/assignment.
TEST(UniqueFunctionTest, MovedFromStateIsDestroyedCorrectly) {
CountCopyAndMove::ResetCounts();
{
unique_function<void()> CapturingFunction{
[Counter = CountCopyAndMove{}] {}};
unique_function<void()> CapturingFunctionMoved{
std::move(CapturingFunction)};
}
EXPECT_EQ(CountCopyAndMove::TotalConstructions(),
CountCopyAndMove::Destructions);
}
} // anonymous namespace

View File

@@ -1,542 +0,0 @@
//===- unittest/ADT/MapVectorTest.cpp - MapVector unit tests ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpedantic"
#if !defined(__clang__)
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#endif
#include "wpi/MapVector.h"
#include "wpi/iterator_range.h"
#include "gtest/gtest.h"
#include <memory>
#include <utility>
using namespace wpi;
namespace {
struct CountCopyAndMove {
CountCopyAndMove() = default;
CountCopyAndMove(const CountCopyAndMove &) { copy = 1; }
CountCopyAndMove(CountCopyAndMove &&) { move = 1; }
void operator=(const CountCopyAndMove &) { ++copy; }
void operator=(CountCopyAndMove &&) { ++move; }
int copy = 0;
int move = 0;
};
struct A : CountCopyAndMove {
A(int v) : v(v) {}
int v;
};
} // namespace
namespace wpi {
template <> struct DenseMapInfo<A> {
static inline A getEmptyKey() { return 0x7fffffff; }
static inline A getTombstoneKey() { return -0x7fffffff - 1; }
static unsigned getHashValue(const A &Val) { return (unsigned)(Val.v * 37U); }
static bool isEqual(const A &LHS, const A &RHS) { return LHS.v == RHS.v; }
};
} // namespace wpi
namespace {
TEST(MapVectorTest, swap) {
MapVector<int, int> MV1, MV2;
std::pair<MapVector<int, int>::iterator, bool> R;
R = MV1.insert(std::make_pair(1, 2));
ASSERT_EQ(R.first, MV1.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_TRUE(R.second);
EXPECT_FALSE(MV1.empty());
EXPECT_TRUE(MV2.empty());
MV2.swap(MV1);
EXPECT_TRUE(MV1.empty());
EXPECT_FALSE(MV2.empty());
auto I = MV1.find(1);
ASSERT_EQ(MV1.end(), I);
I = MV2.find(1);
ASSERT_EQ(I, MV2.begin());
EXPECT_EQ(I->first, 1);
EXPECT_EQ(I->second, 2);
}
TEST(MapVectorTest, insert_pop) {
MapVector<int, int> MV;
std::pair<MapVector<int, int>::iterator, bool> R;
R = MV.insert(std::make_pair(1, 2));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_TRUE(R.second);
R = MV.insert(std::make_pair(1, 3));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_FALSE(R.second);
R = MV.insert(std::make_pair(4, 5));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 5);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 5);
MV.pop_back();
EXPECT_EQ(MV.size(), 1u);
EXPECT_EQ(MV[1], 2);
R = MV.insert(std::make_pair(4, 7));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 7);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 7);
}
TEST(MapVectorTest, try_emplace) {
struct AAndU {
A a;
std::unique_ptr<int> b;
AAndU(A a, std::unique_ptr<int> b) : a(a), b(std::move(b)) {}
};
MapVector<A, AAndU> mv;
A zero(0);
auto try0 = mv.try_emplace(zero, zero, nullptr);
EXPECT_TRUE(try0.second);
EXPECT_EQ(0, try0.first->second.a.v);
EXPECT_EQ(1, try0.first->second.a.copy);
EXPECT_EQ(0, try0.first->second.a.move);
auto try1 = mv.try_emplace(zero, zero, nullptr);
EXPECT_FALSE(try1.second);
EXPECT_EQ(0, try1.first->second.a.v);
EXPECT_EQ(1, try1.first->second.a.copy);
EXPECT_EQ(0, try1.first->second.a.move);
EXPECT_EQ(try0.first, try1.first);
EXPECT_EQ(1, try1.first->first.copy);
EXPECT_EQ(0, try1.first->first.move);
A two(2);
auto try2 = mv.try_emplace(2, std::move(two), std::make_unique<int>(2));
EXPECT_TRUE(try2.second);
EXPECT_EQ(2, try2.first->second.a.v);
EXPECT_EQ(0, try2.first->second.a.move);
std::unique_ptr<int> p(new int(3));
auto try3 = mv.try_emplace(std::move(two), 3, std::move(p));
EXPECT_FALSE(try3.second);
EXPECT_EQ(2, try3.first->second.a.v);
EXPECT_EQ(1, try3.first->second.a.copy);
EXPECT_EQ(0, try3.first->second.a.move);
EXPECT_EQ(try2.first, try3.first);
EXPECT_EQ(0, try3.first->first.copy);
EXPECT_EQ(1, try3.first->first.move);
EXPECT_NE(nullptr, p);
}
TEST(MapVectorTest, insert_or_assign) {
MapVector<A, A> mv;
A zero(0);
auto try0 = mv.insert_or_assign(zero, zero);
EXPECT_TRUE(try0.second);
EXPECT_EQ(0, try0.first->second.v);
EXPECT_EQ(1, try0.first->second.copy);
EXPECT_EQ(0, try0.first->second.move);
auto try1 = mv.insert_or_assign(zero, zero);
EXPECT_FALSE(try1.second);
EXPECT_EQ(0, try1.first->second.v);
EXPECT_EQ(2, try1.first->second.copy);
EXPECT_EQ(0, try1.first->second.move);
EXPECT_EQ(try0.first, try1.first);
EXPECT_EQ(1, try1.first->first.copy);
EXPECT_EQ(0, try1.first->first.move);
A two(2);
auto try2 = mv.try_emplace(2, std::move(two));
EXPECT_TRUE(try2.second);
EXPECT_EQ(2, try2.first->second.v);
EXPECT_EQ(1, try2.first->second.move);
auto try3 = mv.insert_or_assign(std::move(two), 3);
EXPECT_FALSE(try3.second);
EXPECT_EQ(3, try3.first->second.v);
EXPECT_EQ(0, try3.first->second.copy);
EXPECT_EQ(2, try3.first->second.move);
EXPECT_EQ(try2.first, try3.first);
EXPECT_EQ(0, try3.first->first.copy);
EXPECT_EQ(1, try3.first->first.move);
}
TEST(MapVectorTest, erase) {
MapVector<int, int> MV;
MV.insert(std::make_pair(1, 2));
MV.insert(std::make_pair(3, 4));
MV.insert(std::make_pair(5, 6));
ASSERT_EQ(MV.size(), 3u);
ASSERT_TRUE(MV.contains(1));
MV.erase(MV.find(1));
ASSERT_EQ(MV.size(), 2u);
ASSERT_FALSE(MV.contains(1));
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV[3], 4);
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(3), 1u);
ASSERT_EQ(MV.size(), 1u);
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(79), 0u);
ASSERT_EQ(MV.size(), 1u);
}
TEST(MapVectorTest, remove_if) {
MapVector<int, int> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
ASSERT_EQ(MV.size(), 3u);
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV.find(5), MV.end());
ASSERT_EQ(MV[2], 12);
ASSERT_EQ(MV[4], 14);
ASSERT_EQ(MV[6], 16);
}
TEST(MapVectorTest, iteration_test) {
MapVector<int, int> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
int count = 1;
for (auto P : make_range(MV.begin(), MV.end())) {
ASSERT_EQ(P.first, count);
count++;
}
count = 6;
for (auto P : make_range(MV.rbegin(), MV.rend())) {
ASSERT_EQ(P.first, count);
count--;
}
}
TEST(MapVectorTest, NonCopyable) {
MapVector<int, std::unique_ptr<int>> MV;
MV.insert(std::make_pair(1, std::make_unique<int>(1)));
MV.insert(std::make_pair(2, std::make_unique<int>(2)));
ASSERT_EQ(MV.count(1), 1u);
ASSERT_EQ(*MV.find(2)->second, 2);
}
template <class IntType> struct MapVectorMappedTypeTest : ::testing::Test {
using int_type = IntType;
};
using MapIntTypes = ::testing::Types<int, long, long long, unsigned,
unsigned long, unsigned long long>;
TYPED_TEST_SUITE(MapVectorMappedTypeTest, MapIntTypes, );
TYPED_TEST(MapVectorMappedTypeTest, DifferentDenseMap) {
// Test that using a map with a mapped type other than 'unsigned' compiles
// and works.
using IntType = typename TestFixture::int_type;
using MapVectorType = MapVector<int, int, DenseMap<int, IntType>>;
MapVectorType MV;
std::pair<typename MapVectorType::iterator, bool> R;
R = MV.insert(std::make_pair(1, 2));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_TRUE(R.second);
const std::pair<int, int> Elem(1, 3);
R = MV.insert(Elem);
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_FALSE(R.second);
int& value = MV[4];
EXPECT_EQ(value, 0);
value = 5;
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 5);
}
TEST(SmallMapVectorSmallTest, insert_pop) {
SmallMapVector<int, int, 32> MV;
std::pair<SmallMapVector<int, int, 32>::iterator, bool> R;
R = MV.insert(std::make_pair(1, 2));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_TRUE(R.second);
R = MV.insert(std::make_pair(1, 3));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_FALSE(R.second);
R = MV.insert(std::make_pair(4, 5));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 5);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 5);
MV.pop_back();
EXPECT_EQ(MV.size(), 1u);
EXPECT_EQ(MV[1], 2);
R = MV.insert(std::make_pair(4, 7));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 7);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 7);
}
TEST(SmallMapVectorSmallTest, erase) {
SmallMapVector<int, int, 32> MV;
MV.insert(std::make_pair(1, 2));
MV.insert(std::make_pair(3, 4));
MV.insert(std::make_pair(5, 6));
ASSERT_EQ(MV.size(), 3u);
MV.erase(MV.find(1));
ASSERT_EQ(MV.size(), 2u);
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV[3], 4);
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(3), 1u);
ASSERT_EQ(MV.size(), 1u);
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(79), 0u);
ASSERT_EQ(MV.size(), 1u);
}
TEST(SmallMapVectorSmallTest, remove_if) {
SmallMapVector<int, int, 32> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
ASSERT_EQ(MV.size(), 3u);
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV.find(5), MV.end());
ASSERT_EQ(MV[2], 12);
ASSERT_EQ(MV[4], 14);
ASSERT_EQ(MV[6], 16);
}
TEST(SmallMapVectorSmallTest, iteration_test) {
SmallMapVector<int, int, 32> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
int count = 1;
for (auto P : make_range(MV.begin(), MV.end())) {
ASSERT_EQ(P.first, count);
count++;
}
count = 6;
for (auto P : make_range(MV.rbegin(), MV.rend())) {
ASSERT_EQ(P.first, count);
count--;
}
}
TEST(SmallMapVectorSmallTest, NonCopyable) {
SmallMapVector<int, std::unique_ptr<int>, 8> MV;
MV.insert(std::make_pair(1, std::make_unique<int>(1)));
MV.insert(std::make_pair(2, std::make_unique<int>(2)));
ASSERT_EQ(MV.count(1), 1u);
ASSERT_EQ(*MV.find(2)->second, 2);
}
TEST(SmallMapVectorLargeTest, insert_pop) {
SmallMapVector<int, int, 1> MV;
std::pair<SmallMapVector<int, int, 1>::iterator, bool> R;
R = MV.insert(std::make_pair(1, 2));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_TRUE(R.second);
R = MV.insert(std::make_pair(1, 3));
ASSERT_EQ(R.first, MV.begin());
EXPECT_EQ(R.first->first, 1);
EXPECT_EQ(R.first->second, 2);
EXPECT_FALSE(R.second);
R = MV.insert(std::make_pair(4, 5));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 5);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 5);
MV.pop_back();
EXPECT_EQ(MV.size(), 1u);
EXPECT_EQ(MV[1], 2);
R = MV.insert(std::make_pair(4, 7));
ASSERT_NE(R.first, MV.end());
EXPECT_EQ(R.first->first, 4);
EXPECT_EQ(R.first->second, 7);
EXPECT_TRUE(R.second);
EXPECT_EQ(MV.size(), 2u);
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 7);
}
TEST(SmallMapVectorLargeTest, erase) {
SmallMapVector<int, int, 1> MV;
MV.insert(std::make_pair(1, 2));
MV.insert(std::make_pair(3, 4));
MV.insert(std::make_pair(5, 6));
ASSERT_EQ(MV.size(), 3u);
MV.erase(MV.find(1));
ASSERT_EQ(MV.size(), 2u);
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV[3], 4);
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(3), 1u);
ASSERT_EQ(MV.size(), 1u);
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV[5], 6);
ASSERT_EQ(MV.erase(79), 0u);
ASSERT_EQ(MV.size(), 1u);
}
TEST(SmallMapVectorLargeTest, remove_if) {
SmallMapVector<int, int, 1> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
ASSERT_EQ(MV.size(), 3u);
ASSERT_EQ(MV.find(1), MV.end());
ASSERT_EQ(MV.find(3), MV.end());
ASSERT_EQ(MV.find(5), MV.end());
ASSERT_EQ(MV[2], 12);
ASSERT_EQ(MV[4], 14);
ASSERT_EQ(MV[6], 16);
}
TEST(SmallMapVectorLargeTest, iteration_test) {
SmallMapVector<int, int, 1> MV;
MV.insert(std::make_pair(1, 11));
MV.insert(std::make_pair(2, 12));
MV.insert(std::make_pair(3, 13));
MV.insert(std::make_pair(4, 14));
MV.insert(std::make_pair(5, 15));
MV.insert(std::make_pair(6, 16));
ASSERT_EQ(MV.size(), 6u);
int count = 1;
for (auto P : make_range(MV.begin(), MV.end())) {
ASSERT_EQ(P.first, count);
count++;
}
count = 6;
for (auto P : make_range(MV.rbegin(), MV.rend())) {
ASSERT_EQ(P.first, count);
count--;
}
}
} // namespace

View File

@@ -218,8 +218,11 @@ TEST(MathExtras, AlignToPowerOf2) {
EXPECT_EQ(24u, alignToPowerOf2(17, 8));
EXPECT_EQ(0u, alignToPowerOf2(~0LL, 8));
EXPECT_EQ(240u, alignToPowerOf2(240, 16));
EXPECT_EQ(static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()) + 1,
alignToPowerOf2(std::numeric_limits<uint32_t>::max(), 2));
// Overflow.
EXPECT_EQ(0u, alignToPowerOf2(static_cast<uint8_t>(200),
static_cast<uint8_t>(128)));
EXPECT_EQ(0u, alignToPowerOf2(std::numeric_limits<uint32_t>::max(), 2));
}
TEST(MathExtras, AlignDown) {

View File

@@ -13,11 +13,13 @@
#include "wpi/SmallPtrSet.h"
#include "wpi/PointerIntPair.h"
#include "wpi/PointerLikeTypeTraits.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <algorithm>
using namespace wpi;
using testing::UnorderedElementsAre;
TEST(SmallPtrSetTest, Assignment) {
int buf[8];
@@ -409,3 +411,50 @@ TEST(SmallPtrSetTest, RemoveIf) {
Removed = Set.remove_if([](int *Ptr) { return false; });
EXPECT_FALSE(Removed);
}
TEST(SmallPtrSetTest, Reserve) {
// Check that we don't do anything silly when using reserve().
SmallPtrSet<int *, 4> Set;
int Vals[8] = {0, 1, 2, 3, 4, 5, 6, 7};
Set.insert(&Vals[0]);
// We shouldn't reallocate when this happens.
Set.reserve(4);
EXPECT_EQ(Set.capacity(), 4u);
Set.insert(&Vals[1]);
Set.insert(&Vals[2]);
Set.insert(&Vals[3]);
// We shouldn't reallocate this time either.
Set.reserve(4);
EXPECT_EQ(Set.capacity(), 4u);
EXPECT_EQ(Set.size(), 4u);
EXPECT_THAT(Set,
UnorderedElementsAre(&Vals[0], &Vals[1], &Vals[2], &Vals[3]));
// Reserving further should lead to a reallocation. And matching the existing
// insertion approach, we immediately allocate up to 128 elements.
Set.reserve(5);
EXPECT_EQ(Set.capacity(), 128u);
EXPECT_EQ(Set.size(), 4u);
EXPECT_THAT(Set,
UnorderedElementsAre(&Vals[0], &Vals[1], &Vals[2], &Vals[3]));
// And we should be able to insert another two or three elements without
// reallocating.
Set.insert(&Vals[4]);
Set.insert(&Vals[5]);
// Calling a smaller reserve size should have no effect.
Set.reserve(1);
EXPECT_EQ(Set.capacity(), 128u);
EXPECT_EQ(Set.size(), 6u);
// Reserving zero should have no effect either.
Set.reserve(0);
EXPECT_EQ(Set.capacity(), 128u);
EXPECT_EQ(Set.size(), 6u);
EXPECT_THAT(Set, UnorderedElementsAre(&Vals[0], &Vals[1], &Vals[2], &Vals[3], &Vals[4], &Vals[5]));
}

View File

@@ -11,12 +11,64 @@
//===----------------------------------------------------------------------===//
#include "wpi/SmallSet.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <algorithm>
#include <string>
using namespace wpi;
TEST(SmallSetTest, ConstructorIteratorPair) {
std::initializer_list<int> L = {1, 2, 3, 4, 5};
SmallSet<int, 4> S(std::begin(L), std::end(L));
EXPECT_THAT(S, testing::UnorderedElementsAreArray(L));
}
TEST(SmallSet, ConstructorRange) {
std::initializer_list<int> L = {1, 2, 3, 4, 5};
SmallSet<int, 4> S(wpi::make_range(std::begin(L), std::end(L)));
EXPECT_THAT(S, testing::UnorderedElementsAreArray(L));
}
TEST(SmallSet, ConstructorInitializerList) {
std::initializer_list<int> L = {1, 2, 3, 4, 5};
SmallSet<int, 4> S = {1, 2, 3, 4, 5};
EXPECT_THAT(S, testing::UnorderedElementsAreArray(L));
}
TEST(SmallSet, CopyConstructor) {
SmallSet<int, 4> S = {1, 2, 3};
SmallSet<int, 4> T = S;
EXPECT_THAT(S, testing::ContainerEq(T));
}
TEST(SmallSet, MoveConstructor) {
std::initializer_list<int> L = {1, 2, 3};
SmallSet<int, 4> S = L;
SmallSet<int, 4> T = std::move(S);
EXPECT_THAT(T, testing::UnorderedElementsAreArray(L));
}
TEST(SmallSet, CopyAssignment) {
SmallSet<int, 4> S = {1, 2, 3};
SmallSet<int, 4> T;
T = S;
EXPECT_THAT(S, testing::ContainerEq(T));
}
TEST(SmallSet, MoveAssignment) {
std::initializer_list<int> L = {1, 2, 3};
SmallSet<int, 4> S = L;
SmallSet<int, 4> T;
T = std::move(S);
EXPECT_THAT(T, testing::UnorderedElementsAreArray(L));
}
TEST(SmallSetTest, Insert) {
SmallSet<int, 4> s1;
@@ -41,6 +93,40 @@ TEST(SmallSetTest, Insert) {
EXPECT_EQ(0u, s1.count(4));
}
TEST(SmallSetTest, InsertPerfectFwd) {
struct Value {
int Key;
bool Moved;
Value(int Key) : Key(Key), Moved(false) {}
Value(const Value &) = default;
Value(Value &&Other) : Key(Other.Key), Moved(false) { Other.Moved = true; }
bool operator==(const Value &Other) const { return Key == Other.Key; }
bool operator<(const Value &Other) const { return Key < Other.Key; }
};
{
SmallSet<Value, 4> S;
Value V1(1), V2(2);
S.insert(V1);
EXPECT_EQ(V1.Moved, false);
S.insert(std::move(V2));
EXPECT_EQ(V2.Moved, true);
}
{
SmallSet<Value, 1> S;
Value V1(1), V2(2);
S.insert(V1);
EXPECT_EQ(V1.Moved, false);
S.insert(std::move(V2));
EXPECT_EQ(V2.Moved, true);
}
}
TEST(SmallSetTest, Grow) {
SmallSet<int, 4> s1;

View File

@@ -1,132 +0,0 @@
//===- llvm/unittest/Support/xxhashTest.cpp -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "wpi/xxhash.h"
#include "gtest/gtest.h"
using namespace wpi;
/* use #define to make them constant, required for initialization */
#define PRIME32 2654435761U
#define PRIME64 11400714785074694797ULL
/*
* Fills a test buffer with pseudorandom data.
*
* This is used in the sanity check - its values must not be changed.
*/
static void fillTestBuffer(uint8_t *buffer, size_t len) {
uint64_t byteGen = PRIME32;
assert(buffer != NULL);
for (size_t i = 0; i < len; i++) {
buffer[i] = (uint8_t)(byteGen >> 56);
byteGen *= PRIME64;
}
}
TEST(xxhashTest, Basic) {
EXPECT_EQ(0xef46db3751d8e999U, xxHash64(std::string_view()));
EXPECT_EQ(0x33bf00a859c4ba3fU, xxHash64("foo"));
EXPECT_EQ(0x48a37c90ad27a659U, xxHash64("bar"));
EXPECT_EQ(0x69196c1b3af0bff9U,
xxHash64("0123456789abcdefghijklmnopqrstuvwxyz"));
}
TEST(xxhashTest, xxh3) {
constexpr size_t size = 2243;
uint8_t a[size];
uint64_t x = 1;
for (size_t i = 0; i < size; ++i) {
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
a[i] = uint8_t(x);
}
#define F(len, expected) \
EXPECT_EQ(uint64_t(expected), xxh3_64bits(std::span(a, size_t(len))))
F(0, 0x2d06800538d394c2);
F(1, 0xd0d496e05c553485);
F(2, 0x84d625edb7055eac);
F(3, 0x6ea2d59aca5c3778);
F(4, 0xbf65290914e80242);
F(5, 0xc01fd099ad4fc8e4);
F(6, 0x9e3ea8187399caa5);
F(7, 0x9da8b60540644f5a);
F(8, 0xabc1413da6cd0209);
F(9, 0x8bc89400bfed51f6);
F(16, 0x7e46916754d7c9b8);
F(17, 0xed4be912ba5f836d);
F(32, 0xf59b59b58c304fd1);
F(33, 0x9013fb74ca603e0c);
F(64, 0xfa5271fcce0db1c3);
F(65, 0x79c42431727f1012);
F(96, 0x591ee0ddf9c9ccd1);
F(97, 0x8ffc6a3111fe19da);
F(128, 0x06a146ee9a2da378);
F(129, 0xbc7138129bf065da);
F(403, 0xcefeb3ffa532ad8c);
F(512, 0xcdfa6b6268e3650f);
F(513, 0x4bb5d42742f9765f);
F(2048, 0x330ce110cbb79eae);
F(2049, 0x3ba6afa0249fef9a);
F(2240, 0xd61d4d2a94e926a8);
F(2243, 0x0979f786a24edde7);
#undef F
}
TEST(xxhashTest, xxh3_128bits) {
#define SANITY_BUFFER_SIZE 2367
uint8_t sanityBuffer[SANITY_BUFFER_SIZE];
fillTestBuffer(sanityBuffer, sizeof(sanityBuffer));
#define F(len, expected) \
EXPECT_EQ(XXH128_hash_t(expected), \
xxh3_128bits(std::span(sanityBuffer, size_t(len))))
F(0, (XXH128_hash_t{0x6001C324468D497FULL,
0x99AA06D3014798D8ULL})); /* empty string */
F(1, (XXH128_hash_t{0xC44BDFF4074EECDBULL,
0xA6CD5E9392000F6AULL})); /* 1 - 3 */
F(6, (XXH128_hash_t{0x3E7039BDDA43CFC6ULL,
0x082AFE0B8162D12AULL})); /* 4 - 8 */
F(12, (XXH128_hash_t{0x061A192713F69AD9ULL,
0x6E3EFD8FC7802B18ULL})); /* 9 - 16 */
F(24, (XXH128_hash_t{0x1E7044D28B1B901DULL,
0x0CE966E4678D3761ULL})); /* 17 - 32 */
F(48, (XXH128_hash_t{0xF942219AED80F67BULL,
0xA002AC4E5478227EULL})); /* 33 - 64 */
F(81, (XXH128_hash_t{0x5E8BAFB9F95FB803ULL,
0x4952F58181AB0042ULL})); /* 65 - 96 */
F(222, (XXH128_hash_t{0xF1AEBD597CEC6B3AULL,
0x337E09641B948717ULL})); /* 129-240 */
F(403,
(XXH128_hash_t{
0xCDEB804D65C6DEA4ULL,
0x1B6DE21E332DD73DULL})); /* one block, last stripe is overlapping */
F(512,
(XXH128_hash_t{
0x617E49599013CB6BULL,
0x18D2D110DCC9BCA1ULL})); /* one block, finishing at stripe boundary */
F(2048,
(XXH128_hash_t{
0xDD59E2C3A5F038E0ULL,
0xF736557FD47073A5ULL})); /* 2 blocks, finishing at block boundary */
F(2240,
(XXH128_hash_t{
0x6E73A90539CF2948ULL,
0xCCB134FBFA7CE49DULL})); /* 3 blocks, finishing at stripe boundary */
F(2367,
(XXH128_hash_t{
0xCB37AEB9E5D361EDULL,
0xE89C0F6FF369B427ULL})); /* 3 blocks, last stripe is overlapping */
#undef F
}