mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[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:
4
.github/workflows/bazel.yml
vendored
4
.github/workflows/bazel.yml
vendored
@@ -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 }}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 +-
|
||||
@@ -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.
|
||||
@@ -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) {
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
@@ -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
|
||||
@@ -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 ----------------
|
||||
@@ -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)) {
|
||||
@@ -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() {
|
||||
@@ -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 @@
|
||||
@@ -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 @@
|
||||
@@ -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();
|
||||
@@ -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) {
|
||||
@@ -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 +++---
|
||||
@@ -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);
|
||||
@@ -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>
|
||||
@@ -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 @@
|
||||
@@ -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) {
|
||||
@@ -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 @@
|
||||
@@ -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.
|
||||
---
|
||||
@@ -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:
|
||||
@@ -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)
|
||||
@@ -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 +++++
|
||||
@@ -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.
|
||||
@@ -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)};
|
||||
}
|
||||
|
||||
@@ -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 +++++---------
|
||||
@@ -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) {
|
||||
@@ -24,7 +24,7 @@
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_WIN32)
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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]]].
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user