3PP: Bump submodules

This commit is contained in:
Xphalnos 2025-01-05 14:44:08 +01:00 committed by Radosław Gliński
parent 13badbb4c0
commit bb20ada9bf
16 changed files with 1940 additions and 1450 deletions

2
third_party/SDL2 vendored

@ -1 +1 @@
Subproject commit 79ec168f3c1e2fe27335cb8886439f7ef676fb49 Subproject commit fa24d868ac2f8fd558e4e914c9863411245db8fd

@ -1 +1 @@
Subproject commit 1c35ba99ce775f8342d87a83a3f0f696f99c2a39 Subproject commit 3bab6924988e5f19bf36586a496156cf72f70d9f

@ -1 +1 @@
Subproject commit af1ed2fb3d9d67926389a71e12531bef76f50482 Subproject commit 66b08439abd988e87b4542389b4937ce13bd0063

2
third_party/cxxopts vendored

@ -1 +1 @@
Subproject commit 63d1b65a694cfceafc20863afa75df49dfbe6b2a Subproject commit f029892dab60526184ee42ae63a7f6d19a6b0e49

2
third_party/date vendored

@ -1 +1 @@
Subproject commit 51ce7e131079c061533d741be5fe7cca57f2faac Subproject commit 5bdb7e6f31fac909c090a46dbd9fea27b6e609a4

2
third_party/fmt vendored

@ -1 +1 @@
Subproject commit 0c9fce2ffefecfdce794e1859584e25877b7b592 Subproject commit e3ddede6c4ee818825c4e5a6dfa1d384860c27d9

View File

@ -1,5 +1,5 @@
This is automated checker to make sure a C++ file follows Google's C++ style This is automated checker to make sure a C++ file follows Google's C++ style
guide (http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml). As it guide (https://google.github.io/styleguide/cppguide.html). As it
heavily relies on regular expressions, cpplint.py won't catch all violations of heavily relies on regular expressions, cpplint.py won't catch all violations of
the style guide and will very occasionally report a false positive. There is a the style guide and will very occasionally report a false positive. There is a
list of things we currently don't handle very well at the top of cpplint.py, list of things we currently don't handle very well at the top of cpplint.py,

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@ LLVM Release License
University of Illinois/NCSA University of Illinois/NCSA
Open Source License Open Source License
Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign. Copyright (c) 2003-2015 University of Illinois at Urbana-Champaign.
All rights reserved. All rights reserved.
Developed by: Developed by:
@ -63,7 +63,6 @@ Program Directory
------- --------- ------- ---------
Autoconf llvm/autoconf Autoconf llvm/autoconf
llvm/projects/ModuleMaker/autoconf llvm/projects/ModuleMaker/autoconf
llvm/projects/sample/autoconf
Google Test llvm/utils/unittest/googletest Google Test llvm/utils/unittest/googletest
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex} OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT} pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT}

View File

@ -1 +0,0 @@
// here just to keep gyp happy

View File

@ -33,11 +33,15 @@ class BitVector {
enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT }; enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32,
"Unsupported word size");
BitWord *Bits; // Actual bits. BitWord *Bits; // Actual bits.
unsigned Size; // Size of bitvector in bits. unsigned Size; // Size of bitvector in bits.
unsigned Capacity; // Size of allocated memory in BitWord. unsigned Capacity; // Number of BitWords allocated in the Bits array.
public: public:
typedef unsigned size_type;
// Encapsulation of a single bit. // Encapsulation of a single bit.
class reference { class reference {
friend class BitVector; friend class BitVector;
@ -53,7 +57,7 @@ public:
BitPos = Idx % BITWORD_SIZE; BitPos = Idx % BITWORD_SIZE;
} }
~reference() {} reference(const reference&) = default;
reference &operator=(reference t) { reference &operator=(reference t) {
*this = bool(t); *this = bool(t);
@ -62,21 +66,21 @@ public:
reference& operator=(bool t) { reference& operator=(bool t) {
if (t) if (t)
*WordRef |= 1L << BitPos; *WordRef |= BitWord(1) << BitPos;
else else
*WordRef &= ~(1L << BitPos); *WordRef &= ~(BitWord(1) << BitPos);
return *this; return *this;
} }
operator bool() const { operator bool() const {
return ((*WordRef) & (1L << BitPos)) ? true : false; return ((*WordRef) & (BitWord(1) << BitPos)) ? true : false;
} }
}; };
/// BitVector default ctor - Creates an empty bitvector. /// BitVector default ctor - Creates an empty bitvector.
BitVector() : Size(0), Capacity(0) { BitVector() : Size(0), Capacity(0) {
Bits = 0; Bits = nullptr;
} }
/// BitVector ctor - Creates a bitvector of specified number of bits. All /// BitVector ctor - Creates a bitvector of specified number of bits. All
@ -92,7 +96,7 @@ public:
/// BitVector copy ctor. /// BitVector copy ctor.
BitVector(const BitVector &RHS) : Size(RHS.size()) { BitVector(const BitVector &RHS) : Size(RHS.size()) {
if (Size == 0) { if (Size == 0) {
Bits = 0; Bits = nullptr;
Capacity = 0; Capacity = 0;
return; return;
} }
@ -102,12 +106,10 @@ public:
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
} }
#if LLVM_HAS_RVALUE_REFERENCES
BitVector(BitVector &&RHS) BitVector(BitVector &&RHS)
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) { : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
RHS.Bits = 0; RHS.Bits = nullptr;
} }
#endif
~BitVector() { ~BitVector() {
std::free(Bits); std::free(Bits);
@ -117,18 +119,13 @@ public:
bool empty() const { return Size == 0; } bool empty() const { return Size == 0; }
/// size - Returns the number of bits in this bitvector. /// size - Returns the number of bits in this bitvector.
unsigned size() const { return Size; } size_type size() const { return Size; }
/// count - Returns the number of bits which are set. /// count - Returns the number of bits which are set.
unsigned count() const { size_type count() const {
unsigned NumBits = 0; unsigned NumBits = 0;
for (unsigned i = 0; i < NumBitWords(size()); ++i) for (unsigned i = 0; i < NumBitWords(size()); ++i)
if (sizeof(BitWord) == 4) NumBits += countPopulation(Bits[i]);
NumBits += CountPopulation_32((uint32_t)Bits[i]);
else if (sizeof(BitWord) == 8)
NumBits += CountPopulation_64(Bits[i]);
else
llvm_unreachable("Unsupported!");
return NumBits; return NumBits;
} }
@ -162,13 +159,8 @@ public:
/// of the bits are set. /// of the bits are set.
int find_first() const { int find_first() const {
for (unsigned i = 0; i < NumBitWords(size()); ++i) for (unsigned i = 0; i < NumBitWords(size()); ++i)
if (Bits[i] != 0) { if (Bits[i] != 0)
if (sizeof(BitWord) == 4) return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
return i * BITWORD_SIZE + countTrailingZeros((uint32_t)Bits[i]);
if (sizeof(BitWord) == 8)
return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
llvm_unreachable("Unsupported!");
}
return -1; return -1;
} }
@ -185,23 +177,13 @@ public:
// Mask off previous bits. // Mask off previous bits.
Copy &= ~0UL << BitPos; Copy &= ~0UL << BitPos;
if (Copy != 0) { if (Copy != 0)
if (sizeof(BitWord) == 4) return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
return WordPos * BITWORD_SIZE + countTrailingZeros((uint32_t)Copy);
if (sizeof(BitWord) == 8)
return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
llvm_unreachable("Unsupported!");
}
// Check subsequent words. // Check subsequent words.
for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i) for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
if (Bits[i] != 0) { if (Bits[i] != 0)
if (sizeof(BitWord) == 4) return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
return i * BITWORD_SIZE + countTrailingZeros((uint32_t)Bits[i]);
if (sizeof(BitWord) == 8)
return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
llvm_unreachable("Unsupported!");
}
return -1; return -1;
} }
@ -244,7 +226,8 @@ public:
} }
BitVector &set(unsigned Idx) { BitVector &set(unsigned Idx) {
Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE); assert(Bits && "Bits never allocated");
Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE);
return *this; return *this;
} }
@ -283,7 +266,7 @@ public:
} }
BitVector &reset(unsigned Idx) { BitVector &reset(unsigned Idx) {
Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE)); Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE));
return *this; return *this;
} }
@ -324,7 +307,7 @@ public:
} }
BitVector &flip(unsigned Idx) { BitVector &flip(unsigned Idx) {
Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE); Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE);
return *this; return *this;
} }
@ -336,7 +319,7 @@ public:
bool operator[](unsigned Idx) const { bool operator[](unsigned Idx) const {
assert (Idx < Size && "Out-of-bounds Bit access."); assert (Idx < Size && "Out-of-bounds Bit access.");
BitWord Mask = 1L << (Idx % BITWORD_SIZE); BitWord Mask = BitWord(1) << (Idx % BITWORD_SIZE);
return (Bits[Idx / BITWORD_SIZE] & Mask) != 0; return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
} }
@ -455,6 +438,7 @@ public:
// Grow the bitvector to have enough elements. // Grow the bitvector to have enough elements.
Capacity = RHSWords; Capacity = RHSWords;
assert(Capacity > 0 && "negative capacity?");
BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord)); std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
@ -465,7 +449,6 @@ public:
return *this; return *this;
} }
#if LLVM_HAS_RVALUE_REFERENCES
const BitVector &operator=(BitVector &&RHS) { const BitVector &operator=(BitVector &&RHS) {
if (this == &RHS) return *this; if (this == &RHS) return *this;
@ -474,11 +457,10 @@ public:
Size = RHS.Size; Size = RHS.Size;
Capacity = RHS.Capacity; Capacity = RHS.Capacity;
RHS.Bits = 0; RHS.Bits = nullptr;
return *this; return *this;
} }
#endif
void swap(BitVector &RHS) { void swap(BitVector &RHS) {
std::swap(Bits, RHS.Bits); std::swap(Bits, RHS.Bits);
@ -552,6 +534,7 @@ private:
void grow(unsigned NewSize) { void grow(unsigned NewSize) {
Capacity = std::max(NumBitWords(NewSize), Capacity * 2); Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
assert(Capacity > 0 && "realloc-ing zero space");
Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord)); Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
clear_unused_bits(); clear_unused_bits();
@ -563,7 +546,7 @@ private:
template<bool AddBits, bool InvertMask> template<bool AddBits, bool InvertMask>
void applyMask(const uint32_t *Mask, unsigned MaskWords) { void applyMask(const uint32_t *Mask, unsigned MaskWords) {
assert(BITWORD_SIZE % 32 == 0 && "Unsupported BitWord size."); static_assert(BITWORD_SIZE % 32 == 0, "Unsupported BitWord size.");
MaskWords = std::min(MaskWords, (size() + 31) / 32); MaskWords = std::min(MaskWords, (size() + 31) / 32);
const unsigned Scale = BITWORD_SIZE / 32; const unsigned Scale = BITWORD_SIZE / 32;
unsigned i; unsigned i;
@ -587,8 +570,16 @@ private:
if (AddBits) if (AddBits)
clear_unused_bits(); clear_unused_bits();
} }
public:
/// Return the size (in bytes) of the bit vector.
size_t getMemorySize() const { return Capacity * sizeof(BitWord); }
}; };
static inline size_t capacity_in_bytes(const BitVector &X) {
return X.getMemorySize();
}
} // End llvm namespace } // End llvm namespace
namespace std { namespace std {

View File

@ -33,140 +33,65 @@
# define __has_builtin(x) 0 # define __has_builtin(x) 0
#endif #endif
/// \macro __GNUC_PREREQ /// \macro LLVM_GNUC_PREREQ
/// \brief Defines __GNUC_PREREQ if glibc's features.h isn't available. /// \brief Extend the default __GNUC_PREREQ even if glibc's features.h isn't
#ifndef __GNUC_PREREQ /// available.
# if defined(__GNUC__) && defined(__GNUC_MINOR__) #ifndef LLVM_GNUC_PREREQ
# define __GNUC_PREREQ(maj, min) \ # if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) # define LLVM_GNUC_PREREQ(maj, min, patch) \
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
((maj) << 20) + ((min) << 10) + (patch))
# elif defined(__GNUC__) && defined(__GNUC_MINOR__)
# define LLVM_GNUC_PREREQ(maj, min, patch) \
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
# else # else
# define __GNUC_PREREQ(maj, min) 0 # define LLVM_GNUC_PREREQ(maj, min, patch) 0
# endif # endif
#endif #endif
/// \macro LLVM_MSC_PREREQ /// \macro LLVM_MSC_PREREQ
/// \brief Is the compiler MSVC of at least the specified version? /// \brief Is the compiler MSVC of at least the specified version?
/// The common \param version values to check for are: /// The common \param version values to check for are:
/// * 1600: Microsoft Visual Studio 2010 / 10.0
/// * 1700: Microsoft Visual Studio 2012 / 11.0
/// * 1800: Microsoft Visual Studio 2013 / 12.0 /// * 1800: Microsoft Visual Studio 2013 / 12.0
/// * 1900: Microsoft Visual Studio 2015 / 14.0
#ifdef _MSC_VER #ifdef _MSC_VER
#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version)) #define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
// We require at least MSVC 2013.
#if !LLVM_MSC_PREREQ(1800)
#error LLVM requires at least MSVC 2013.
#endif
#else #else
#define LLVM_MSC_PREREQ(version) 0 #define LLVM_MSC_PREREQ(version) 0
#endif #endif
/// \brief Does the compiler support r-value references? #if !defined(_MSC_VER) || defined(__clang__) || LLVM_MSC_PREREQ(1900)
/// This implies that <utility> provides the one-argument std::move; it #define LLVM_NOEXCEPT noexcept
/// does not imply the existence of any other C++ library features.
#if __has_feature(cxx_rvalue_references) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1600)
#define LLVM_HAS_RVALUE_REFERENCES 1
#else #else
#define LLVM_HAS_RVALUE_REFERENCES 0 #define LLVM_NOEXCEPT throw()
#endif #endif
/// \brief Does the compiler support r-value reference *this? /// \brief Does the compiler support ref-qualifiers for *this?
/// ///
/// Sadly, this is separate from just r-value reference support because GCC /// Sadly, this is separate from just rvalue reference support because GCC
/// implemented everything but this thus far. No release of GCC yet has support /// and MSVC implemented this later than everything else.
/// for this feature so it is enabled with Clang only. #if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1)
/// FIXME: This should change to a version check when GCC grows support for it.
#if __has_feature(cxx_rvalue_references)
#define LLVM_HAS_RVALUE_REFERENCE_THIS 1 #define LLVM_HAS_RVALUE_REFERENCE_THIS 1
#else #else
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0 #define LLVM_HAS_RVALUE_REFERENCE_THIS 0
#endif #endif
/// \macro LLVM_HAS_CXX11_TYPETRAITS /// Expands to '&' if ref-qualifiers for *this are supported.
/// \brief Does the compiler have the C++11 type traits.
/// ///
/// #include <type_traits> /// This can be used to provide lvalue/rvalue overrides of member functions.
/// /// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
/// * enable_if
/// * {true,false}_type
/// * is_constructible
/// * etc...
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
#define LLVM_HAS_CXX11_TYPETRAITS 1
#else
#define LLVM_HAS_CXX11_TYPETRAITS 0
#endif
/// \macro LLVM_HAS_CXX11_STDLIB
/// \brief Does the compiler have the C++11 standard library.
///
/// Implies LLVM_HAS_RVALUE_REFERENCES, LLVM_HAS_CXX11_TYPETRAITS
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
#define LLVM_HAS_CXX11_STDLIB 1
#else
#define LLVM_HAS_CXX11_STDLIB 0
#endif
/// \macro LLVM_HAS_VARIADIC_TEMPLATES
/// \brief Does this compiler support variadic templates.
///
/// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward.
#if __has_feature(cxx_variadic_templates) || LLVM_MSC_PREREQ(1800)
# define LLVM_HAS_VARIADIC_TEMPLATES 1
#else
# define LLVM_HAS_VARIADIC_TEMPLATES 0
#endif
/// llvm_move - Expands to ::std::move if the compiler supports
/// r-value references; otherwise, expands to the argument.
#if LLVM_HAS_RVALUE_REFERENCES
#define llvm_move(value) (::std::move(value))
#else
#define llvm_move(value) (value)
#endif
/// Expands to '&' if r-value references are supported.
///
/// This can be used to provide l-value/r-value overrides of member functions.
/// The r-value override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
#if LLVM_HAS_RVALUE_REFERENCE_THIS #if LLVM_HAS_RVALUE_REFERENCE_THIS
#define LLVM_LVALUE_FUNCTION & #define LLVM_LVALUE_FUNCTION &
#else #else
#define LLVM_LVALUE_FUNCTION #define LLVM_LVALUE_FUNCTION
#endif #endif
/// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it.
/// Use to mark functions as uncallable. Member functions with this should
/// be declared private so that some behavior is kept in C++03 mode.
///
/// class DontCopy {
/// private:
/// DontCopy(const DontCopy&) LLVM_DELETED_FUNCTION;
/// DontCopy &operator =(const DontCopy&) LLVM_DELETED_FUNCTION;
/// public:
/// ...
/// };
#if __has_feature(cxx_deleted_functions) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
#define LLVM_DELETED_FUNCTION = delete
#else
#define LLVM_DELETED_FUNCTION
#endif
/// LLVM_FINAL - Expands to 'final' if the compiler supports it.
/// Use to mark classes or virtual methods as final.
#if __has_feature(cxx_override_control) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
#define LLVM_FINAL final
#else
#define LLVM_FINAL
#endif
/// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it.
/// Use to mark virtual methods as overriding a base class method.
#if __has_feature(cxx_override_control) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
#define LLVM_OVERRIDE override
#else
#define LLVM_OVERRIDE
#endif
#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__) #if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define LLVM_CONSTEXPR constexpr # define LLVM_CONSTEXPR constexpr
#else #else
@ -178,20 +103,26 @@
/// not accessible from outside it. Can also be used to mark variables and /// not accessible from outside it. Can also be used to mark variables and
/// functions, making them private to any shared library they are linked into. /// functions, making them private to any shared library they are linked into.
/// On PE/COFF targets, library visibility is the default, so this isn't needed. /// On PE/COFF targets, library visibility is the default, so this isn't needed.
#if (__has_attribute(visibility) || __GNUC_PREREQ(4, 0)) && \ #if (__has_attribute(visibility) || LLVM_GNUC_PREREQ(4, 0, 0)) && \
!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32) !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32)
#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
#else #else
#define LLVM_LIBRARY_VISIBILITY #define LLVM_LIBRARY_VISIBILITY
#endif #endif
#if __has_attribute(used) || __GNUC_PREREQ(3, 1) #if __has_attribute(sentinel) || LLVM_GNUC_PREREQ(3, 0, 0)
#define LLVM_END_WITH_NULL __attribute__((sentinel))
#else
#define LLVM_END_WITH_NULL
#endif
#if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0)
#define LLVM_ATTRIBUTE_USED __attribute__((__used__)) #define LLVM_ATTRIBUTE_USED __attribute__((__used__))
#else #else
#define LLVM_ATTRIBUTE_USED #define LLVM_ATTRIBUTE_USED
#endif #endif
#if __has_attribute(warn_unused_result) || __GNUC_PREREQ(3, 4) #if __has_attribute(warn_unused_result) || LLVM_GNUC_PREREQ(3, 4, 0)
#define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__)) #define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__))
#else #else
#define LLVM_ATTRIBUTE_UNUSED_RESULT #define LLVM_ATTRIBUTE_UNUSED_RESULT
@ -205,14 +136,14 @@
// more portable solution: // more portable solution:
// (void)unused_var_name; // (void)unused_var_name;
// Prefer cast-to-void wherever it is sufficient. // Prefer cast-to-void wherever it is sufficient.
#if __has_attribute(unused) || __GNUC_PREREQ(3, 1) #if __has_attribute(unused) || LLVM_GNUC_PREREQ(3, 1, 0)
#define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__)) #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
#else #else
#define LLVM_ATTRIBUTE_UNUSED #define LLVM_ATTRIBUTE_UNUSED
#endif #endif
// FIXME: Provide this for PE/COFF targets. // FIXME: Provide this for PE/COFF targets.
#if (__has_attribute(weak) || __GNUC_PREREQ(4, 0)) && \ #if (__has_attribute(weak) || LLVM_GNUC_PREREQ(4, 0, 0)) && \
(!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32)) (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32))
#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
#else #else
@ -235,7 +166,7 @@
#define LLVM_READONLY #define LLVM_READONLY
#endif #endif
#if __has_builtin(__builtin_expect) || __GNUC_PREREQ(4, 0) #if __has_builtin(__builtin_expect) || LLVM_GNUC_PREREQ(4, 0, 0)
#define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true) #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
#define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false) #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
#else #else
@ -243,22 +174,9 @@
#define LLVM_UNLIKELY(EXPR) (EXPR) #define LLVM_UNLIKELY(EXPR) (EXPR)
#endif #endif
// C++ doesn't support 'extern template' of template specializations. GCC does,
// but requires __extension__ before it. In the header, use this:
// EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
// in the .cpp file, use this:
// TEMPLATE_INSTANTIATION(class foo<bar>);
#ifdef __GNUC__
#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
#define TEMPLATE_INSTANTIATION(X) template X
#else
#define EXTERN_TEMPLATE_INSTANTIATION(X)
#define TEMPLATE_INSTANTIATION(X)
#endif
/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, /// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
/// mark a method "not for inlining". /// mark a method "not for inlining".
#if __has_attribute(noinline) || __GNUC_PREREQ(3, 4) #if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0)
#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline) #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
@ -270,8 +188,8 @@
/// so, mark a method "always inline" because it is performance sensitive. GCC /// so, mark a method "always inline" because it is performance sensitive. GCC
/// 3.4 supported this but is buggy in various cases and produces unimplemented /// 3.4 supported this but is buggy in various cases and produces unimplemented
/// errors, just use it in GCC 4.0 and later. /// errors, just use it in GCC 4.0 and later.
#if __has_attribute(always_inline) || __GNUC_PREREQ(4, 0) #if __has_attribute(always_inline) || LLVM_GNUC_PREREQ(4, 0, 0)
#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) #define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
#else #else
@ -286,6 +204,22 @@
#define LLVM_ATTRIBUTE_NORETURN #define LLVM_ATTRIBUTE_NORETURN
#endif #endif
#if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0)
#define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
#else
#define LLVM_ATTRIBUTE_RETURNS_NONNULL
#endif
/// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a
/// pointer that does not alias any other valid pointer.
#ifdef __GNUC__
#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
#elif defined(_MSC_VER)
#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
#else
#define LLVM_ATTRIBUTE_RETURNS_NOALIAS
#endif
/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress /// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
/// pedantic diagnostics. /// pedantic diagnostics.
#ifdef __GNUC__ #ifdef __GNUC__
@ -312,7 +246,7 @@
/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
/// to an expression which states that it is undefined behavior for the /// to an expression which states that it is undefined behavior for the
/// compiler to reach this point. Otherwise is not defined. /// compiler to reach this point. Otherwise is not defined.
#if __has_builtin(__builtin_unreachable) || __GNUC_PREREQ(4, 5) #if __has_builtin(__builtin_unreachable) || LLVM_GNUC_PREREQ(4, 5, 0)
# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# define LLVM_BUILTIN_UNREACHABLE __assume(false) # define LLVM_BUILTIN_UNREACHABLE __assume(false)
@ -320,15 +254,21 @@
/// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression /// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
/// which causes the program to exit abnormally. /// which causes the program to exit abnormally.
#if __has_builtin(__builtin_trap) || __GNUC_PREREQ(4, 3) #if __has_builtin(__builtin_trap) || LLVM_GNUC_PREREQ(4, 3, 0)
# define LLVM_BUILTIN_TRAP __builtin_trap() # define LLVM_BUILTIN_TRAP __builtin_trap()
#elif defined(_MSC_VER)
// The __debugbreak intrinsic is supported by MSVC, does not require forward
// declarations involving platform-specific typedefs (unlike RaiseException),
// results in a call to vectored exception handlers, and encodes to a short
// instruction that still causes the trapping behavior we want.
# define LLVM_BUILTIN_TRAP __debugbreak()
#else #else
# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
#endif #endif
/// \macro LLVM_ASSUME_ALIGNED /// \macro LLVM_ASSUME_ALIGNED
/// \brief Returns a pointer with an assumed alignment. /// \brief Returns a pointer with an assumed alignment.
#if __has_builtin(__builtin_assume_aligned) && __GNUC_PREREQ(4, 7) #if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0)
# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
#elif defined(LLVM_BUILTIN_UNREACHABLE) #elif defined(LLVM_BUILTIN_UNREACHABLE)
// As of today, clang does not support __builtin_assume_aligned. // As of today, clang does not support __builtin_assume_aligned.
@ -338,6 +278,65 @@
# define LLVM_ASSUME_ALIGNED(p, a) (p) # define LLVM_ASSUME_ALIGNED(p, a) (p)
#endif #endif
/// \macro LLVM_ALIGNAS
/// \brief Used to specify a minimum alignment for a structure or variable. The
/// alignment must be a constant integer. Use LLVM_PTR_SIZE to compute
/// alignments in terms of the size of a pointer.
///
/// Note that __declspec(align) has special quirks, it's not legal to pass a
/// structure with __declspec(align) as a formal parameter.
#ifdef _MSC_VER
# define LLVM_ALIGNAS(x) __declspec(align(x))
#elif __GNUC__ && !__has_feature(cxx_alignas) && !LLVM_GNUC_PREREQ(4, 8, 0)
# define LLVM_ALIGNAS(x) __attribute__((aligned(x)))
#else
# define LLVM_ALIGNAS(x) alignas(x)
#endif
/// \macro LLVM_PACKED
/// \brief Used to specify a packed structure.
/// LLVM_PACKED(
/// struct A {
/// int i;
/// int j;
/// int k;
/// long long l;
/// });
///
/// LLVM_PACKED_START
/// struct B {
/// int i;
/// int j;
/// int k;
/// long long l;
/// };
/// LLVM_PACKED_END
#ifdef _MSC_VER
# define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop))
# define LLVM_PACKED_START __pragma(pack(push, 1))
# define LLVM_PACKED_END __pragma(pack(pop))
#else
# define LLVM_PACKED(d) d __attribute__((packed))
# define LLVM_PACKED_START _Pragma("pack(push, 1)")
# define LLVM_PACKED_END _Pragma("pack(pop)")
#endif
/// \macro LLVM_PTR_SIZE
/// \brief A constant integer equivalent to the value of sizeof(void*).
/// Generally used in combination with LLVM_ALIGNAS or when doing computation in
/// the preprocessor.
#ifdef __SIZEOF_POINTER__
# define LLVM_PTR_SIZE __SIZEOF_POINTER__
#elif defined(_WIN64)
# define LLVM_PTR_SIZE 8
#elif defined(_WIN32)
# define LLVM_PTR_SIZE 4
#elif defined(_MSC_VER)
# error "could not determine LLVM_PTR_SIZE as a constant int for MSVC"
#else
# define LLVM_PTR_SIZE sizeof(void *)
#endif
/// \macro LLVM_FUNCTION_NAME /// \macro LLVM_FUNCTION_NAME
/// \brief Expands to __func__ on compilers which support it. Otherwise, /// \brief Expands to __func__ on compilers which support it. Otherwise,
/// expands to a compiler-dependent replacement. /// expands to a compiler-dependent replacement.
@ -347,91 +346,65 @@
# define LLVM_FUNCTION_NAME __func__ # define LLVM_FUNCTION_NAME __func__
#endif #endif
#if defined(HAVE_SANITIZER_MSAN_INTERFACE_H)
# include <sanitizer/msan_interface.h>
#else
# define __msan_allocated_memory(p, size)
# define __msan_unpoison(p, size)
#endif
/// \macro LLVM_MEMORY_SANITIZER_BUILD /// \macro LLVM_MEMORY_SANITIZER_BUILD
/// \brief Whether LLVM itself is built with MemorySanitizer instrumentation. /// \brief Whether LLVM itself is built with MemorySanitizer instrumentation.
#if __has_feature(memory_sanitizer) #if __has_feature(memory_sanitizer)
# define LLVM_MEMORY_SANITIZER_BUILD 1 # define LLVM_MEMORY_SANITIZER_BUILD 1
# include <sanitizer/msan_interface.h>
#else #else
# define LLVM_MEMORY_SANITIZER_BUILD 0 # define LLVM_MEMORY_SANITIZER_BUILD 0
# define __msan_allocated_memory(p, size)
# define __msan_unpoison(p, size)
#endif #endif
/// \macro LLVM_ADDRESS_SANITIZER_BUILD /// \macro LLVM_ADDRESS_SANITIZER_BUILD
/// \brief Whether LLVM itself is built with AddressSanitizer instrumentation. /// \brief Whether LLVM itself is built with AddressSanitizer instrumentation.
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
# define LLVM_ADDRESS_SANITIZER_BUILD 1 # define LLVM_ADDRESS_SANITIZER_BUILD 1
# include <sanitizer/asan_interface.h>
#else #else
# define LLVM_ADDRESS_SANITIZER_BUILD 0 # define LLVM_ADDRESS_SANITIZER_BUILD 0
# define __asan_poison_memory_region(p, size)
# define __asan_unpoison_memory_region(p, size)
#endif #endif
/// \macro LLVM_IS_UNALIGNED_ACCESS_FAST /// \macro LLVM_THREAD_SANITIZER_BUILD
/// \brief Is unaligned memory access fast on the host machine. /// \brief Whether LLVM itself is built with ThreadSanitizer instrumentation.
/// #if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)
/// Don't specialize on alignment for platforms where unaligned memory accesses # define LLVM_THREAD_SANITIZER_BUILD 1
/// generates the same code as aligned memory accesses for common types.
#if defined(_M_AMD64) || defined(_M_IX86) || defined(__amd64) || \
defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || \
defined(_X86_) || defined(__i386) || defined(__i386__)
# define LLVM_IS_UNALIGNED_ACCESS_FAST 1
#else #else
# define LLVM_IS_UNALIGNED_ACCESS_FAST 0 # define LLVM_THREAD_SANITIZER_BUILD 0
#endif #endif
/// \macro LLVM_EXPLICIT #if LLVM_THREAD_SANITIZER_BUILD
/// \brief Expands to explicit on compilers which support explicit conversion // Thread Sanitizer is a tool that finds races in code.
/// operators. Otherwise expands to nothing. // See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
#if __has_feature(cxx_explicit_conversions) || \ // tsan detects these exact functions by name.
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800) extern "C" {
#define LLVM_EXPLICIT explicit void AnnotateHappensAfter(const char *file, int line, const volatile void *cv);
#else void AnnotateHappensBefore(const char *file, int line, const volatile void *cv);
#define LLVM_EXPLICIT void AnnotateIgnoreWritesBegin(const char *file, int line);
#endif void AnnotateIgnoreWritesEnd(const char *file, int line);
}
/// \macro LLVM_STATIC_ASSERT // This marker is used to define a happens-before arc. The race detector will
/// \brief Expands to C/C++'s static_assert on compilers which support it. // infer an arc from the begin to the end when they share the same pointer
#if __has_feature(cxx_static_assert) || \ // argument.
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1600) # define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__, __LINE__, cv)
# define LLVM_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
#elif __has_feature(c_static_assert)
# define LLVM_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg)
#elif __has_extension(c_static_assert)
# define LLVM_STATIC_ASSERT(expr, msg) LLVM_EXTENSION _Static_assert(expr, msg)
#else
# define LLVM_STATIC_ASSERT(expr, msg)
#endif
/// \macro LLVM_ENUM_INT_TYPE // This marker defines the destination of a happens-before arc.
/// \brief Expands to colon followed by the given integral type on compilers # define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__, __LINE__, cv)
/// which support C++11 strong enums. This can be used to make enums unsigned
/// with MSVC.
#if __has_feature(cxx_strong_enums) || LLVM_MSC_PREREQ(1600)
# define LLVM_ENUM_INT_TYPE(intty) : intty
#else
# define LLVM_ENUM_INT_TYPE(intty)
#endif
/// \brief Does the compiler support C++11 semantics for strongly typed forward // Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
/// declared enums? # define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
#if __has_feature(cxx_strong_enums) || LLVM_MSC_PREREQ(1700)
#define LLVM_HAS_STRONG_ENUMS 1
#else
#define LLVM_HAS_STRONG_ENUMS 0
#endif
/// \brief Does the compiler support generalized initializers (using braced // Resume checking for racy writes.
/// lists and std::initializer_list). While clang may claim it supports general # define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
/// initializers, if we're using MSVC's headers, we might not have a usable
/// std::initializer list type from the STL. Disable this for now.
#if __has_feature(cxx_generalized_initializers) && !defined(_MSC_VER)
#define LLVM_HAS_INITIALIZER_LISTS 1
#else #else
#define LLVM_HAS_INITIALIZER_LISTS 0 # define TsanHappensBefore(cv)
# define TsanHappensAfter(cv)
# define TsanIgnoreWritesBegin()
# define TsanIgnoreWritesEnd()
#endif #endif
/// \brief Mark debug helper function definitions like dump() that should not be /// \brief Mark debug helper function definitions like dump() that should not be
@ -443,4 +416,33 @@
#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
#endif #endif
/// \macro LLVM_THREAD_LOCAL
/// \brief A thread-local storage specifier which can be used with globals,
/// extern globals, and static globals.
///
/// This is essentially an extremely restricted analog to C++11's thread_local
/// support, and uses that when available. However, it falls back on
/// platform-specific or vendor-provided extensions when necessary. These
/// extensions don't support many of the C++11 thread_local's features. You
/// should only use this for PODs that you can statically 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.
#if LLVM_ENABLE_THREADS
#if __has_feature(cxx_thread_local)
#define LLVM_THREAD_LOCAL thread_local
#elif defined(_MSC_VER)
// MSVC supports this with a __declspec.
#define LLVM_THREAD_LOCAL __declspec(thread)
#else
// Clang, GCC, and other compatible compilers used __thread prior to C++11 and
// we only need the restricted functionality that provides.
#define LLVM_THREAD_LOCAL __thread
#endif
#else // !LLVM_ENABLE_THREADS
// If threading is disabled entirely, this compiles to nothing and you get
// a normal global variable.
#define LLVM_THREAD_LOCAL
#endif
#endif #endif

View File

@ -18,13 +18,16 @@
#ifdef IGNORED_LLVM_XENIA #ifdef IGNORED_LLVM_XENIA
#include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/SwapByteOrder.h"
#endif // IGNORED_LLVM_XENIA #endif // IGNORED_LLVM_XENIA
#include <cmath> #include <cassert>
#include <cstring> #include <cstring>
#include "llvm/Support/type_traits.h" #include <type_traits>
#ifdef _MSC_VER #ifdef _MSC_VER
#include <intrin.h> #include <intrin.h>
#include <limits> #endif
#ifdef __ANDROID_NDK__
#include <android/api-level.h>
#endif #endif
namespace llvm { namespace llvm {
@ -38,6 +41,65 @@ enum ZeroBehavior {
ZB_Width ZB_Width
}; };
namespace detail {
template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
static std::size_t count(T Val, ZeroBehavior) {
if (!Val)
return std::numeric_limits<T>::digits;
if (Val & 0x1)
return 0;
// Bisection method.
std::size_t ZeroBits = 0;
T Shift = std::numeric_limits<T>::digits >> 1;
T Mask = std::numeric_limits<T>::max() >> Shift;
while (Shift) {
if ((Val & Mask) == 0) {
Val >>= Shift;
ZeroBits |= Shift;
}
Shift >>= 1;
Mask >>= Shift;
}
return ZeroBits;
}
};
#if __GNUC__ >= 4 || defined(_MSC_VER)
template <typename T> struct TrailingZerosCounter<T, 4> {
static std::size_t count(T Val, ZeroBehavior ZB) {
if (ZB != ZB_Undefined && Val == 0)
return 32;
#if __has_builtin(__builtin_ctz) || LLVM_GNUC_PREREQ(4, 0, 0)
return __builtin_ctz(Val);
#elif defined(_MSC_VER)
unsigned long Index;
_BitScanForward(&Index, Val);
return Index;
#endif
}
};
#if !defined(_MSC_VER) || defined(_M_X64)
template <typename T> struct TrailingZerosCounter<T, 8> {
static std::size_t count(T Val, ZeroBehavior ZB) {
if (ZB != ZB_Undefined && Val == 0)
return 64;
#if __has_builtin(__builtin_ctzll) || LLVM_GNUC_PREREQ(4, 0, 0)
return __builtin_ctzll(Val);
#elif defined(_MSC_VER)
unsigned long Index;
_BitScanForward64(&Index, Val);
return Index;
#endif
}
};
#endif
#endif
} // namespace detail
/// \brief Count number of 0's from the least significant bit to the most /// \brief Count number of 0's from the least significant bit to the most
/// stopping at the first 1. /// stopping at the first 1.
/// ///
@ -46,68 +108,66 @@ enum ZeroBehavior {
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
/// valid arguments. /// valid arguments.
template <typename T> template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_integer && std::size_t countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
!std::numeric_limits<T>::is_signed, std::size_t>::type static_assert(std::numeric_limits<T>::is_integer &&
countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) { !std::numeric_limits<T>::is_signed,
(void)ZB; "Only unsigned integral types are allowed.");
return detail::TrailingZerosCounter<T, sizeof(T)>::count(Val, ZB);
}
if (!Val) namespace detail {
return std::numeric_limits<T>::digits; template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
if (Val & 0x1) static std::size_t count(T Val, ZeroBehavior) {
return 0; if (!Val)
return std::numeric_limits<T>::digits;
// Bisection method. // Bisection method.
std::size_t ZeroBits = 0; std::size_t ZeroBits = 0;
T Shift = std::numeric_limits<T>::digits >> 1; for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
T Mask = std::numeric_limits<T>::max() >> Shift; T Tmp = Val >> Shift;
while (Shift) { if (Tmp)
if ((Val & Mask) == 0) { Val = Tmp;
Val >>= Shift; else
ZeroBits |= Shift; ZeroBits |= Shift;
} }
Shift >>= 1; return ZeroBits;
Mask >>= Shift;
} }
return ZeroBits; };
}
// Disable signed. #if __GNUC__ >= 4 || defined(_MSC_VER)
template <typename T> template <typename T> struct LeadingZerosCounter<T, 4> {
typename enable_if_c<std::numeric_limits<T>::is_integer && static std::size_t count(T Val, ZeroBehavior ZB) {
std::numeric_limits<T>::is_signed, std::size_t>::type if (ZB != ZB_Undefined && Val == 0)
countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION; return 32;
#if __GNUC__ >= 4 || _MSC_VER #if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0)
template <> return __builtin_clz(Val);
inline std::size_t countTrailingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) { #elif defined(_MSC_VER)
if (ZB != ZB_Undefined && Val == 0) unsigned long Index;
return 32; _BitScanReverse(&Index, Val);
return Index ^ 31;
#if __has_builtin(__builtin_ctz) || __GNUC_PREREQ(4, 0)
return __builtin_ctz(Val);
#elif _MSC_VER
unsigned long Index;
_BitScanForward(&Index, Val);
return Index;
#endif #endif
} }
};
#if !defined(_MSC_VER) || defined(_M_X64) #if !defined(_MSC_VER) || defined(_M_X64)
template <> template <typename T> struct LeadingZerosCounter<T, 8> {
inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) { static std::size_t count(T Val, ZeroBehavior ZB) {
if (ZB != ZB_Undefined && Val == 0) if (ZB != ZB_Undefined && Val == 0)
return 64; return 64;
#if __has_builtin(__builtin_ctzll) || __GNUC_PREREQ(4, 0) #if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0)
return __builtin_ctzll(Val); return __builtin_clzll(Val);
#elif _MSC_VER #elif defined(_MSC_VER)
unsigned long Index; unsigned long Index;
_BitScanForward64(&Index, Val); _BitScanReverse64(&Index, Val);
return Index; return Index ^ 63;
#endif #endif
} }
};
#endif #endif
#endif #endif
} // namespace detail
/// \brief Count number of 0's from the most significant bit to the least /// \brief Count number of 0's from the most significant bit to the least
/// stopping at the first 1. /// stopping at the first 1.
@ -117,64 +177,13 @@ inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
/// valid arguments. /// valid arguments.
template <typename T> template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_integer && std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
!std::numeric_limits<T>::is_signed, std::size_t>::type static_assert(std::numeric_limits<T>::is_integer &&
countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { !std::numeric_limits<T>::is_signed,
(void)ZB; "Only unsigned integral types are allowed.");
return detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB);
if (!Val)
return std::numeric_limits<T>::digits;
// Bisection method.
std::size_t ZeroBits = 0;
for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
T Tmp = Val >> Shift;
if (Tmp)
Val = Tmp;
else
ZeroBits |= Shift;
}
return ZeroBits;
} }
// Disable signed.
template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_integer &&
std::numeric_limits<T>::is_signed, std::size_t>::type
countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION;
#if __GNUC__ >= 4 || _MSC_VER
template <>
inline std::size_t countLeadingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) {
if (ZB != ZB_Undefined && Val == 0)
return 32;
#if __has_builtin(__builtin_clz) || __GNUC_PREREQ(4, 0)
return __builtin_clz(Val);
#elif _MSC_VER
unsigned long Index;
_BitScanReverse(&Index, Val);
return Index ^ 31;
#endif
}
#if !defined(_MSC_VER) || defined(_M_X64)
template <>
inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
if (ZB != ZB_Undefined && Val == 0)
return 64;
#if __has_builtin(__builtin_clzll) || __GNUC_PREREQ(4, 0)
return __builtin_clzll(Val);
#elif _MSC_VER
unsigned long Index;
_BitScanReverse64(&Index, Val);
return Index ^ 63;
#endif
}
#endif
#endif
/// \brief Get the index of the first set bit starting from the least /// \brief Get the index of the first set bit starting from the least
/// significant bit. /// significant bit.
/// ///
@ -182,22 +191,13 @@ inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
/// ///
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are /// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
/// valid arguments. /// valid arguments.
template <typename T> template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
typename enable_if_c<std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed, T>::type
findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
if (ZB == ZB_Max && Val == 0) if (ZB == ZB_Max && Val == 0)
return std::numeric_limits<T>::max(); return std::numeric_limits<T>::max();
return countTrailingZeros(Val, ZB_Undefined); return countTrailingZeros(Val, ZB_Undefined);
} }
// Disable signed.
template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_integer &&
std::numeric_limits<T>::is_signed, T>::type
findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
/// \brief Get the index of the last set bit starting from the least /// \brief Get the index of the last set bit starting from the least
/// significant bit. /// significant bit.
/// ///
@ -205,10 +205,7 @@ findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
/// ///
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are /// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
/// valid arguments. /// valid arguments.
template <typename T> template <typename T> T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
typename enable_if_c<std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed, T>::type
findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
if (ZB == ZB_Max && Val == 0) if (ZB == ZB_Max && Val == 0)
return std::numeric_limits<T>::max(); return std::numeric_limits<T>::max();
@ -218,12 +215,6 @@ findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
(std::numeric_limits<T>::digits - 1); (std::numeric_limits<T>::digits - 1);
} }
// Disable signed.
template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_integer &&
std::numeric_limits<T>::is_signed, T>::type
findLastSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
/// \brief Macro compressed bit reversal table for 256 bits. /// \brief Macro compressed bit reversal table for 256 bits.
/// ///
/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable /// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
@ -232,6 +223,9 @@ static const unsigned char BitReverseTable256[256] = {
#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16) #define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16)
#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4) #define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4)
R6(0), R6(2), R6(1), R6(3) R6(0), R6(2), R6(1), R6(3)
#undef R2
#undef R4
#undef R6
}; };
/// \brief Reverse the bits in \p Val. /// \brief Reverse the bits in \p Val.
@ -260,6 +254,12 @@ inline uint32_t Lo_32(uint64_t Value) {
return static_cast<uint32_t>(Value); return static_cast<uint32_t>(Value);
} }
/// Make_64 - This functions makes a 64-bit integer from a high / low pair of
/// 32-bit integers.
inline uint64_t Make_64(uint32_t High, uint32_t Low) {
return ((uint64_t)High << 32) | (uint64_t)Low;
}
/// isInt - Checks if an integer fits into the given bit width. /// isInt - Checks if an integer fits into the given bit width.
template<unsigned N> template<unsigned N>
inline bool isInt(int64_t x) { inline bool isInt(int64_t x) {
@ -315,7 +315,7 @@ inline bool isShiftedUInt(uint64_t x) {
/// isUIntN - Checks if an unsigned integer fits into the given (dynamic) /// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
/// bit width. /// bit width.
inline bool isUIntN(unsigned N, uint64_t x) { inline bool isUIntN(unsigned N, uint64_t x) {
return x == (x & (~0ULL >> (64 - N))); return N >= 64 || x < (UINT64_C(1)<<(N));
} }
/// isIntN - Checks if an signed integer fits into the given (dynamic) /// isIntN - Checks if an signed integer fits into the given (dynamic)
@ -324,31 +324,31 @@ inline bool isIntN(unsigned N, int64_t x) {
return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1))); return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
} }
/// isMask_32 - This function returns true if the argument is a sequence of ones /// isMask_32 - This function returns true if the argument is a non-empty
/// starting at the least significant bit with the remainder zero (32 bit /// sequence of ones starting at the least significant bit with the remainder
/// version). Ex. isMask_32(0x0000FFFFU) == true. /// zero (32 bit version). Ex. isMask_32(0x0000FFFFU) == true.
inline bool isMask_32(uint32_t Value) { inline bool isMask_32(uint32_t Value) {
return Value && ((Value + 1) & Value) == 0; return Value && ((Value + 1) & Value) == 0;
} }
/// isMask_64 - This function returns true if the argument is a sequence of ones /// isMask_64 - This function returns true if the argument is a non-empty
/// starting at the least significant bit with the remainder zero (64 bit /// sequence of ones starting at the least significant bit with the remainder
/// version). /// zero (64 bit version).
inline bool isMask_64(uint64_t Value) { inline bool isMask_64(uint64_t Value) {
return Value && ((Value + 1) & Value) == 0; return Value && ((Value + 1) & Value) == 0;
} }
/// isShiftedMask_32 - This function returns true if the argument contains a /// isShiftedMask_32 - This function returns true if the argument contains a
/// sequence of ones with the remainder zero (32 bit version.) /// non-empty sequence of ones with the remainder zero (32 bit version.)
/// Ex. isShiftedMask_32(0x0000FF00U) == true. /// Ex. isShiftedMask_32(0x0000FF00U) == true.
inline bool isShiftedMask_32(uint32_t Value) { inline bool isShiftedMask_32(uint32_t Value) {
return isMask_32((Value - 1) | Value); return Value && isMask_32((Value - 1) | Value);
} }
/// isShiftedMask_64 - This function returns true if the argument contains a /// isShiftedMask_64 - This function returns true if the argument contains a
/// sequence of ones with the remainder zero (64 bit version.) /// non-empty sequence of ones with the remainder zero (64 bit version.)
inline bool isShiftedMask_64(uint64_t Value) { inline bool isShiftedMask_64(uint64_t Value) {
return isMask_64((Value - 1) | Value); return Value && isMask_64((Value - 1) | Value);
} }
/// isPowerOf2_32 - This function returns true if the argument is a power of /// isPowerOf2_32 - This function returns true if the argument is a power of
@ -383,61 +383,86 @@ inline uint64_t ByteSwap_64(uint64_t Value) {
} }
#endif // IGNORED_LLVM_XENIA #endif // IGNORED_LLVM_XENIA
/// CountLeadingOnes_32 - this function performs the operation of /// \brief Count the number of ones from the most significant bit to the first
/// counting the number of ones from the most significant bit to the first zero /// zero bit.
/// bit. Ex. CountLeadingOnes_32(0xFF0FFF00) == 8. ///
/// Returns 32 if the word is all ones. /// Ex. CountLeadingOnes(0xFF0FFF00) == 8.
inline unsigned CountLeadingOnes_32(uint32_t Value) { /// Only unsigned integral types are allowed.
return countLeadingZeros(~Value); ///
/// \param ZB the behavior on an input of all ones. Only ZB_Width and
/// ZB_Undefined are valid arguments.
template <typename T>
std::size_t countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) {
static_assert(std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed,
"Only unsigned integral types are allowed.");
return countLeadingZeros(~Value, ZB);
} }
/// CountLeadingOnes_64 - This function performs the operation /// \brief Count the number of ones from the least significant bit to the first
/// of counting the number of ones from the most significant bit to the first /// zero bit.
/// zero bit (64 bit edition.) ///
/// Returns 64 if the word is all ones. /// Ex. countTrailingOnes(0x00FF00FF) == 8.
inline unsigned CountLeadingOnes_64(uint64_t Value) { /// Only unsigned integral types are allowed.
return countLeadingZeros(~Value); ///
/// \param ZB the behavior on an input of all ones. Only ZB_Width and
/// ZB_Undefined are valid arguments.
template <typename T>
std::size_t countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) {
static_assert(std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed,
"Only unsigned integral types are allowed.");
return countTrailingZeros(~Value, ZB);
} }
/// CountTrailingOnes_32 - this function performs the operation of namespace detail {
/// counting the number of ones from the least significant bit to the first zero template <typename T, std::size_t SizeOfT> struct PopulationCounter {
/// bit. Ex. CountTrailingOnes_32(0x00FF00FF) == 8. static unsigned count(T Value) {
/// Returns 32 if the word is all ones. // Generic version, forward to 32 bits.
inline unsigned CountTrailingOnes_32(uint32_t Value) { static_assert(SizeOfT <= 4, "Not implemented!");
return countTrailingZeros(~Value);
}
/// CountTrailingOnes_64 - This function performs the operation
/// of counting the number of ones from the least significant bit to the first
/// zero bit (64 bit edition.)
/// Returns 64 if the word is all ones.
inline unsigned CountTrailingOnes_64(uint64_t Value) {
return countTrailingZeros(~Value);
}
/// CountPopulation_32 - this function counts the number of set bits in a value.
/// Ex. CountPopulation(0xF000F000) = 8
/// Returns 0 if the word is zero.
inline unsigned CountPopulation_32(uint32_t Value) {
#if __GNUC__ >= 4 #if __GNUC__ >= 4
return __builtin_popcount(Value); return __builtin_popcount(Value);
#else #else
uint32_t v = Value - ((Value >> 1) & 0x55555555); uint32_t v = Value;
v = (v & 0x33333333) + ((v >> 2) & 0x33333333); v = v - ((v >> 1) & 0x55555555);
return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
#endif #endif
}
};
template <typename T> struct PopulationCounter<T, 8> {
static unsigned count(T Value) {
#if __GNUC__ >= 4
return __builtin_popcountll(Value);
#else
uint64_t v = Value;
v = v - ((v >> 1) & 0x5555555555555555ULL);
v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
#endif
}
};
} // namespace detail
/// \brief Count the number of set bits in a value.
/// Ex. countPopulation(0xF000F000) = 8
/// Returns 0 if the word is zero.
template <typename T>
inline unsigned countPopulation(T Value) {
static_assert(std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed,
"Only unsigned integral types are allowed.");
return detail::PopulationCounter<T, sizeof(T)>::count(Value);
} }
/// CountPopulation_64 - this function counts the number of set bits in a value, /// Log2 - This function returns the log base 2 of the specified value
/// (64 bit edition.) inline double Log2(double Value) {
inline unsigned CountPopulation_64(uint64_t Value) { #if defined(__ANDROID_API__) && __ANDROID_API__ < 18
#if __GNUC__ >= 4 return __builtin_log(Value) / __builtin_log(2.0);
return __builtin_popcountll(Value);
#else #else
uint64_t v = Value - ((Value >> 1) & 0x5555555555555555ULL); return log2(Value);
v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
#endif #endif
} }
@ -526,14 +551,6 @@ inline uint32_t FloatToBits(float Float) {
return T.I; return T.I;
} }
/// Platform-independent wrappers for the C99 isnan() function.
int IsNAN(float f);
int IsNAN(double d);
/// Platform-independent wrappers for the C99 isinf() function.
int IsInf(float f);
int IsInf(double d);
/// MinAlign - A and B are either alignments or offsets. Return the minimum /// MinAlign - A and B are either alignments or offsets. Return the minimum
/// alignment that may be assumed after adding the two together. /// alignment that may be assumed after adding the two together.
inline uint64_t MinAlign(uint64_t A, uint64_t B) { inline uint64_t MinAlign(uint64_t A, uint64_t B) {
@ -545,6 +562,25 @@ inline uint64_t MinAlign(uint64_t A, uint64_t B) {
return (A | B) & (1 + ~(A | B)); return (A | B) & (1 + ~(A | B));
} }
/// \brief Aligns \c Addr to \c Alignment bytes, rounding up.
///
/// Alignment should be a power of two. This method rounds up, so
/// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8.
inline uintptr_t alignAddr(const void *Addr, size_t Alignment) {
assert(Alignment && isPowerOf2_64((uint64_t)Alignment) &&
"Alignment is not a power of two!");
assert((uintptr_t)Addr + Alignment - 1 >= (uintptr_t)Addr);
return (((uintptr_t)Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1));
}
/// \brief Returns the necessary adjustment for aligning \c Ptr to \c Alignment
/// bytes, rounding up.
inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) {
return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr;
}
/// NextPowerOf2 - Returns the next power of two (in 64-bits) /// NextPowerOf2 - Returns the next power of two (in 64-bits)
/// that is strictly greater than A. Returns zero on overflow. /// that is strictly greater than A. Returns zero on overflow.
inline uint64_t NextPowerOf2(uint64_t A) { inline uint64_t NextPowerOf2(uint64_t A) {
@ -567,14 +603,27 @@ inline uint64_t PowerOf2Floor(uint64_t A) {
/// Returns the next integer (mod 2**64) that is greater than or equal to /// Returns the next integer (mod 2**64) that is greater than or equal to
/// \p Value and is a multiple of \p Align. \p Align must be non-zero. /// \p Value and is a multiple of \p Align. \p Align must be non-zero.
/// ///
/// If non-zero \p Skew is specified, the return value will be a minimal
/// integer that is greater than or equal to \p Value and equal to
/// \p Align * N + \p Skew for some integer N. If \p Skew is larger than
/// \p Align, its value is adjusted to '\p Skew mod \p Align'.
///
/// Examples: /// Examples:
/// \code /// \code
/// RoundUpToAlignment(5, 8) = 8 /// RoundUpToAlignment(5, 8) = 8
/// RoundUpToAlignment(17, 8) = 24 /// RoundUpToAlignment(17, 8) = 24
/// RoundUpToAlignment(~0LL, 8) = 0 /// RoundUpToAlignment(~0LL, 8) = 0
/// RoundUpToAlignment(321, 255) = 510
///
/// RoundUpToAlignment(5, 8, 7) = 7
/// RoundUpToAlignment(17, 8, 1) = 17
/// RoundUpToAlignment(~0LL, 8, 3) = 3
/// RoundUpToAlignment(321, 255, 42) = 552
/// \endcode /// \endcode
inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) { inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align,
return ((Value + Align - 1) / Align) * Align; uint64_t Skew = 0) {
Skew %= Align;
return (Value + Align - 1 - Skew) / Align * Align + Skew;
} }
/// Returns the offset to the next integer (mod 2**64) that is greater than /// Returns the offset to the next integer (mod 2**64) that is greater than
@ -584,13 +633,6 @@ inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
return RoundUpToAlignment(Value, Align) - Value; return RoundUpToAlignment(Value, Align) - Value;
} }
/// abs64 - absolute value of a 64-bit int. Not all environments support
/// "abs" on whatever their name for the 64-bit int type is. The absolute
/// value of the largest negative number is undefined, as with "abs".
inline int64_t abs64(int64_t x) {
return (x < 0) ? -x : x;
}
/// SignExtend32 - Sign extend B-bit number x to 32-bit int. /// SignExtend32 - Sign extend B-bit number x to 32-bit int.
/// Usage int32_t r = SignExtend32<5>(x); /// Usage int32_t r = SignExtend32<5>(x);
template <unsigned B> inline int32_t SignExtend32(uint32_t x) { template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
@ -615,13 +657,90 @@ inline int64_t SignExtend64(uint64_t X, unsigned B) {
return int64_t(X << (64 - B)) >> (64 - B); return int64_t(X << (64 - B)) >> (64 - B);
} }
#if defined(_MSC_VER) /// \brief Add two unsigned integers, X and Y, of type T.
// Visual Studio defines the HUGE_VAL class of macros using purposeful /// Clamp the result to the maximum representable value of T on overflow.
// constant arithmetic overflow, which it then warns on when encountered. /// ResultOverflowed indicates if the result is larger than the maximum
const float huge_valf = std::numeric_limits<float>::infinity(); /// representable value of type T.
#else template <typename T>
const float huge_valf = HUGE_VALF; typename std::enable_if<std::is_unsigned<T>::value, T>::type
#endif SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
bool Dummy;
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
// Hacker's Delight, p. 29
T Z = X + Y;
Overflowed = (Z < X || Z < Y);
if (Overflowed)
return std::numeric_limits<T>::max();
else
return Z;
}
/// \brief Multiply two unsigned integers, X and Y, of type T.
/// Clamp the result to the maximum representable value of T on overflow.
/// ResultOverflowed indicates if the result is larger than the maximum
/// representable value of type T.
template <typename T>
typename std::enable_if<std::is_unsigned<T>::value, T>::type
SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
bool Dummy;
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
// Hacker's Delight, p. 30 has a different algorithm, but we don't use that
// because it fails for uint16_t (where multiplication can have undefined
// behavior due to promotion to int), and requires a division in addition
// to the multiplication.
Overflowed = false;
// Log2(Z) would be either Log2Z or Log2Z + 1.
// 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);
const T Max = std::numeric_limits<T>::max();
int Log2Max = Log2_64(Max);
if (Log2Z < Log2Max) {
return X * Y;
}
if (Log2Z > Log2Max) {
Overflowed = true;
return Max;
}
// We're going to use the top bit, and maybe overflow one
// bit past it. Multiply all but the bottom bit then add
// that on at the end.
T Z = (X >> 1) * Y;
if (Z & ~(Max >> 1)) {
Overflowed = true;
return Max;
}
Z <<= 1;
if (X & 1)
return SaturatingAdd(Z, Y, ResultOverflowed);
return Z;
}
/// \brief Multiply two unsigned integers, X and Y, and add the unsigned
/// integer, A to the product. Clamp the result to the maximum representable
/// value of T on overflow. ResultOverflowed indicates if the result is larger
/// than the maximum representable value of type T.
/// Note that this is purely a convenience function as there is no distinction
/// where overflow occurred in a 'fused' multiply-add for unsigned numbers.
template <typename T>
typename std::enable_if<std::is_unsigned<T>::value, T>::type
SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) {
bool Dummy;
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
T Product = SaturatingMultiply(X, Y, &Overflowed);
if (Overflowed)
return Product;
return SaturatingAdd(A, Product, &Overflowed);
}
extern const float huge_valf;
} // End llvm namespace } // End llvm namespace
#endif #endif

View File

@ -1,244 +0,0 @@
//===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides a template class that determines if a type is a class or
// not. The basic mechanism, based on using the pointer to member function of
// a zero argument to a function was "boosted" from the boost type_traits
// library. See http://www.boost.org/ for all the gory details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
#define LLVM_SUPPORT_TYPE_TRAITS_H
//#include "llvm/Support/DataTypes.h"
#include <cstddef>
#include <utility>
#ifndef __has_feature
#define LLVM_DEFINED_HAS_FEATURE
#define __has_feature(x) 0
#endif
// This is actually the conforming implementation which works with abstract
// classes. However, enough compilers have trouble with it that most will use
// the one in boost/type_traits/object_traits.hpp. This implementation actually
// works with VC7.0, but other interactions seem to fail when we use it.
namespace llvm {
namespace dont_use
{
// These two functions should never be used. They are helpers to
// the is_class template below. They cannot be located inside
// is_class because doing so causes at least GCC to think that
// the value of the "value" enumerator is not constant. Placing
// them out here (for some strange reason) allows the sizeof
// operator against them to magically be constant. This is
// important to make the is_class<T>::value idiom zero cost. it
// evaluates to a constant 1 or 0 depending on whether the
// parameter T is a class or not (respectively).
template<typename T> char is_class_helper(void(T::*)());
template<typename T> double is_class_helper(...);
}
template <typename T>
struct is_class
{
// is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For
// more details:
// http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1
public:
static const bool value =
sizeof(char) == sizeof(dont_use::is_class_helper<T>(0));
};
/// isPodLike - This is a type trait that is used to determine whether a given
/// type can be copied around with memcpy instead of running ctors etc.
template <typename T>
struct isPodLike {
#if __has_feature(is_trivially_copyable)
// If the compiler supports the is_trivially_copyable trait use it, as it
// matches the definition of isPodLike closely.
static const bool value = __is_trivially_copyable(T);
#else
// If we don't know anything else, we can (at least) assume that all non-class
// types are PODs.
static const bool value = !is_class<T>::value;
#endif
};
// std::pair's are pod-like if their elements are.
template<typename T, typename U>
struct isPodLike<std::pair<T, U> > {
static const bool value = isPodLike<T>::value && isPodLike<U>::value;
};
template <class T, T v>
struct integral_constant {
typedef T value_type;
static const value_type value = v;
typedef integral_constant<T,v> type;
operator value_type() { return value; }
};
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
/// \brief Metafunction that determines whether the two given types are
/// equivalent.
template<typename T, typename U> struct is_same : public false_type {};
template<typename T> struct is_same<T, T> : public true_type {};
/// \brief Metafunction that removes const qualification from a type.
template <typename T> struct remove_const { typedef T type; };
template <typename T> struct remove_const<const T> { typedef T type; };
/// \brief Metafunction that removes volatile qualification from a type.
template <typename T> struct remove_volatile { typedef T type; };
template <typename T> struct remove_volatile<volatile T> { typedef T type; };
/// \brief Metafunction that removes both const and volatile qualification from
/// a type.
template <typename T> struct remove_cv {
typedef typename remove_const<typename remove_volatile<T>::type>::type type;
};
/// \brief Helper to implement is_integral metafunction.
template <typename T> struct is_integral_impl : false_type {};
template <> struct is_integral_impl< bool> : true_type {};
template <> struct is_integral_impl< char> : true_type {};
template <> struct is_integral_impl< signed char> : true_type {};
template <> struct is_integral_impl<unsigned char> : true_type {};
template <> struct is_integral_impl< wchar_t> : true_type {};
template <> struct is_integral_impl< short> : true_type {};
template <> struct is_integral_impl<unsigned short> : true_type {};
template <> struct is_integral_impl< int> : true_type {};
template <> struct is_integral_impl<unsigned int> : true_type {};
template <> struct is_integral_impl< long> : true_type {};
template <> struct is_integral_impl<unsigned long> : true_type {};
template <> struct is_integral_impl< long long> : true_type {};
template <> struct is_integral_impl<unsigned long long> : true_type {};
/// \brief Metafunction that determines whether the given type is an integral
/// type.
template <typename T>
struct is_integral : is_integral_impl<T> {};
/// \brief Metafunction to remove reference from a type.
template <typename T> struct remove_reference { typedef T type; };
template <typename T> struct remove_reference<T&> { typedef T type; };
/// \brief Metafunction that determines whether the given type is a pointer
/// type.
template <typename T> struct is_pointer : false_type {};
template <typename T> struct is_pointer<T*> : true_type {};
template <typename T> struct is_pointer<T* const> : true_type {};
template <typename T> struct is_pointer<T* volatile> : true_type {};
template <typename T> struct is_pointer<T* const volatile> : true_type {};
/// \brief Metafunction that determines wheather the given type is a reference.
template <typename T> struct is_reference : false_type {};
template <typename T> struct is_reference<T&> : true_type {};
/// \brief Metafunction that determines whether the given type is either an
/// integral type or an enumeration type.
///
/// Note that this accepts potentially more integral types than we whitelist
/// above for is_integral because it is based on merely being convertible
/// implicitly to an integral type.
template <typename T> class is_integral_or_enum {
// Provide an overload which can be called with anything implicitly
// convertible to an unsigned long long. This should catch integer types and
// enumeration types at least. We blacklist classes with conversion operators
// below.
static double check_int_convertible(unsigned long long);
static char check_int_convertible(...);
typedef typename remove_reference<T>::type UnderlyingT;
static UnderlyingT &nonce_instance;
public:
static const bool
value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value &&
!is_same<UnderlyingT, float>::value &&
!is_same<UnderlyingT, double>::value &&
sizeof(char) != sizeof(check_int_convertible(nonce_instance)));
};
// enable_if_c - Enable/disable a template based on a metafunction
template<bool Cond, typename T = void>
struct enable_if_c {
typedef T type;
};
template<typename T> struct enable_if_c<false, T> { };
// enable_if - Enable/disable a template based on a metafunction
template<typename Cond, typename T = void>
struct enable_if : public enable_if_c<Cond::value, T> { };
namespace dont_use {
template<typename Base> char base_of_helper(const volatile Base*);
template<typename Base> double base_of_helper(...);
}
/// is_base_of - Metafunction to determine whether one type is a base class of
/// (or identical to) another type.
template<typename Base, typename Derived>
struct is_base_of {
static const bool value
= is_class<Base>::value && is_class<Derived>::value &&
sizeof(char) == sizeof(dont_use::base_of_helper<Base>((Derived*)0));
};
// remove_pointer - Metafunction to turn Foo* into Foo. Defined in
// C++0x [meta.trans.ptr].
template <typename T> struct remove_pointer { typedef T type; };
template <typename T> struct remove_pointer<T*> { typedef T type; };
template <typename T> struct remove_pointer<T*const> { typedef T type; };
template <typename T> struct remove_pointer<T*volatile> { typedef T type; };
template <typename T> struct remove_pointer<T*const volatile> {
typedef T type; };
// If T is a pointer, just return it. If it is not, return T&.
template<typename T, typename Enable = void>
struct add_lvalue_reference_if_not_pointer { typedef T &type; };
template<typename T>
struct add_lvalue_reference_if_not_pointer<T,
typename enable_if<is_pointer<T> >::type> {
typedef T type;
};
// If T is a pointer to X, return a pointer to const X. If it is not, return
// const T.
template<typename T, typename Enable = void>
struct add_const_past_pointer { typedef const T type; };
template<typename T>
struct add_const_past_pointer<T, typename enable_if<is_pointer<T> >::type> {
typedef const typename remove_pointer<T>::type *type;
};
template <bool, typename T, typename F>
struct conditional { typedef T type; };
template <typename T, typename F>
struct conditional<false, T, F> { typedef F type; };
}
#ifdef LLVM_DEFINED_HAS_FEATURE
#undef __has_feature
#endif
#endif

2
third_party/xbyak vendored

@ -1 +1 @@
Subproject commit cf209c915b849141ed9821fea883fd04bcc34859 Subproject commit 4e44f4614ddbf038f2a6296f5b906d5c72691e0f

2
third_party/xxhash vendored

@ -1 +1 @@
Subproject commit 3e321b4407318ac1348c0b80fb6fbae8c81ad5fa Subproject commit e626a72bc2321cd320e953a0ccf1584cad60f363