mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-30 02:31:44 +00:00
[wpiutil] Vendor llvm and update to 13.0.0 (#4224)
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
//===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -19,12 +18,14 @@
|
||||
#include "wpi/AlignOf.h"
|
||||
#include "wpi/Compiler.h"
|
||||
#include "wpi/MathExtras.h"
|
||||
#include "wpi/MemAlloc.h"
|
||||
#include "wpi/PointerLikeTypeTraits.h"
|
||||
#include "wpi/type_traits.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
@@ -38,6 +39,8 @@ namespace detail {
|
||||
// implementation without requiring two members.
|
||||
template <typename KeyT, typename ValueT>
|
||||
struct DenseMapPair : public std::pair<KeyT, ValueT> {
|
||||
using std::pair<KeyT, ValueT>::pair;
|
||||
|
||||
KeyT &getFirst() { return std::pair<KeyT, ValueT>::first; }
|
||||
const KeyT &getFirst() const { return std::pair<KeyT, ValueT>::first; }
|
||||
ValueT &getSecond() { return std::pair<KeyT, ValueT>::second; }
|
||||
@@ -113,8 +116,8 @@ public:
|
||||
}
|
||||
|
||||
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
|
||||
if (isPodLike<KeyT>::value && isPodLike<ValueT>::value) {
|
||||
// Use a simpler loop when these are trivial types.
|
||||
if (std::is_trivially_destructible<ValueT>::value) {
|
||||
// Use a simpler loop when values don't need destruction.
|
||||
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P)
|
||||
P->getFirst() = EmptyKey;
|
||||
} else {
|
||||
@@ -143,13 +146,15 @@ public:
|
||||
iterator find(const_arg_type_t<KeyT> Val) {
|
||||
BucketT *TheBucket;
|
||||
if (LookupBucketFor(Val, TheBucket))
|
||||
return makeIterator(TheBucket, getBucketsEnd(), *this, true);
|
||||
return makeIterator(TheBucket, 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, getBucketsEnd(), *this, true);
|
||||
return makeConstIterator(TheBucket, getBucketsEnd(),
|
||||
*this, true);
|
||||
return end();
|
||||
}
|
||||
|
||||
@@ -162,14 +167,16 @@ public:
|
||||
iterator find_as(const LookupKeyT &Val) {
|
||||
BucketT *TheBucket;
|
||||
if (LookupBucketFor(Val, TheBucket))
|
||||
return makeIterator(TheBucket, getBucketsEnd(), *this, true);
|
||||
return makeIterator(TheBucket, getBucketsEnd(),
|
||||
*this, true);
|
||||
return end();
|
||||
}
|
||||
template<class LookupKeyT>
|
||||
const_iterator find_as(const LookupKeyT &Val) const {
|
||||
const BucketT *TheBucket;
|
||||
if (LookupBucketFor(Val, TheBucket))
|
||||
return makeConstIterator(TheBucket, getBucketsEnd(), *this, true);
|
||||
return makeConstIterator(TheBucket, getBucketsEnd(),
|
||||
*this, true);
|
||||
return end();
|
||||
}
|
||||
|
||||
@@ -203,16 +210,16 @@ public:
|
||||
std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&... Args) {
|
||||
BucketT *TheBucket;
|
||||
if (LookupBucketFor(Key, TheBucket))
|
||||
return std::make_pair(
|
||||
makeIterator(TheBucket, getBucketsEnd(), *this, true),
|
||||
false); // Already in map.
|
||||
return std::make_pair(makeIterator(TheBucket, getBucketsEnd(),
|
||||
*this, true),
|
||||
false); // Already in map.
|
||||
|
||||
// Otherwise, insert the new element.
|
||||
TheBucket =
|
||||
InsertIntoBucket(TheBucket, std::move(Key), std::forward<Ts>(Args)...);
|
||||
return std::make_pair(
|
||||
makeIterator(TheBucket, getBucketsEnd(), *this, true),
|
||||
true);
|
||||
return std::make_pair(makeIterator(TheBucket, getBucketsEnd(),
|
||||
*this, true),
|
||||
true);
|
||||
}
|
||||
|
||||
// Inserts key,value pair into the map if the key isn't already in the map.
|
||||
@@ -222,15 +229,15 @@ public:
|
||||
std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&... Args) {
|
||||
BucketT *TheBucket;
|
||||
if (LookupBucketFor(Key, TheBucket))
|
||||
return std::make_pair(
|
||||
makeIterator(TheBucket, getBucketsEnd(), *this, true),
|
||||
false); // Already in map.
|
||||
return std::make_pair(makeIterator(TheBucket, getBucketsEnd(),
|
||||
*this, true),
|
||||
false); // Already in map.
|
||||
|
||||
// Otherwise, insert the new element.
|
||||
TheBucket = InsertIntoBucket(TheBucket, Key, std::forward<Ts>(Args)...);
|
||||
return std::make_pair(
|
||||
makeIterator(TheBucket, getBucketsEnd(), *this, true),
|
||||
true);
|
||||
return std::make_pair(makeIterator(TheBucket, getBucketsEnd(),
|
||||
*this, true),
|
||||
true);
|
||||
}
|
||||
|
||||
/// Alternate version of insert() which allows a different, and possibly
|
||||
@@ -243,16 +250,16 @@ public:
|
||||
const LookupKeyT &Val) {
|
||||
BucketT *TheBucket;
|
||||
if (LookupBucketFor(Val, TheBucket))
|
||||
return std::make_pair(
|
||||
makeIterator(TheBucket, getBucketsEnd(), *this, true),
|
||||
false); // Already in map.
|
||||
return std::make_pair(makeIterator(TheBucket, getBucketsEnd(),
|
||||
*this, true),
|
||||
false); // Already in map.
|
||||
|
||||
// Otherwise, insert the new element.
|
||||
TheBucket = InsertIntoBucketWithLookup(TheBucket, std::move(KV.first),
|
||||
std::move(KV.second), Val);
|
||||
return std::make_pair(
|
||||
makeIterator(TheBucket, getBucketsEnd(), *this, true),
|
||||
true);
|
||||
return std::make_pair(makeIterator(TheBucket, getBucketsEnd(),
|
||||
*this, true),
|
||||
true);
|
||||
}
|
||||
|
||||
/// insert - Range insertion of pairs.
|
||||
@@ -389,7 +396,8 @@ protected:
|
||||
setNumEntries(other.getNumEntries());
|
||||
setNumTombstones(other.getNumTombstones());
|
||||
|
||||
if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
|
||||
if (std::is_trivially_copyable<KeyT>::value &&
|
||||
std::is_trivially_copyable<ValueT>::value)
|
||||
memcpy(reinterpret_cast<void *>(getBuckets()), other.getBuckets(),
|
||||
getNumBuckets() * sizeof(BucketT));
|
||||
else
|
||||
@@ -679,7 +687,7 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
|
||||
unsigned NumBuckets;
|
||||
|
||||
public:
|
||||
/// Create a DenseMap wth an optional \p InitialReserve that guarantee that
|
||||
/// Create a DenseMap with an optional \p InitialReserve that guarantee that
|
||||
/// this number of elements can be inserted in the map without grow()
|
||||
explicit DenseMap(unsigned InitialReserve = 0) { init(InitialReserve); }
|
||||
|
||||
@@ -706,7 +714,7 @@ public:
|
||||
|
||||
~DenseMap() {
|
||||
this->destroyAll();
|
||||
operator delete(Buckets);
|
||||
deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT));
|
||||
}
|
||||
|
||||
void swap(DenseMap& RHS) {
|
||||
@@ -726,7 +734,7 @@ public:
|
||||
|
||||
DenseMap& operator=(DenseMap &&other) {
|
||||
this->destroyAll();
|
||||
operator delete(Buckets);
|
||||
deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT));
|
||||
init(0);
|
||||
swap(other);
|
||||
return *this;
|
||||
@@ -734,7 +742,7 @@ public:
|
||||
|
||||
void copyFrom(const DenseMap& other) {
|
||||
this->destroyAll();
|
||||
operator delete(Buckets);
|
||||
deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT));
|
||||
if (allocateBuckets(other.NumBuckets)) {
|
||||
this->BaseT::copyFrom(other);
|
||||
} else {
|
||||
@@ -767,10 +775,12 @@ public:
|
||||
this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets);
|
||||
|
||||
// Free the old table.
|
||||
operator delete(OldBuckets);
|
||||
deallocate_buffer(OldBuckets, sizeof(BucketT) * OldNumBuckets,
|
||||
alignof(BucketT));
|
||||
}
|
||||
|
||||
void shrink_and_clear() {
|
||||
unsigned OldNumBuckets = NumBuckets;
|
||||
unsigned OldNumEntries = NumEntries;
|
||||
this->destroyAll();
|
||||
|
||||
@@ -783,7 +793,8 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
operator delete(Buckets);
|
||||
deallocate_buffer(Buckets, sizeof(BucketT) * OldNumBuckets,
|
||||
alignof(BucketT));
|
||||
init(NewNumBuckets);
|
||||
}
|
||||
|
||||
@@ -819,7 +830,8 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
|
||||
Buckets = static_cast<BucketT *>(
|
||||
allocate_buffer(sizeof(BucketT) * NumBuckets, alignof(BucketT)));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -874,6 +886,9 @@ public:
|
||||
this->insert(I, E);
|
||||
}
|
||||
|
||||
SmallDenseMap(std::initializer_list<typename BaseT::value_type> Vals)
|
||||
: SmallDenseMap(Vals.begin(), Vals.end()) {}
|
||||
|
||||
~SmallDenseMap() {
|
||||
this->destroyAll();
|
||||
deallocateBuckets();
|
||||
@@ -904,7 +919,7 @@ public:
|
||||
std::swap(*LHSB, *RHSB);
|
||||
continue;
|
||||
}
|
||||
// Swap separately and handle any assymetry.
|
||||
// Swap separately and handle any asymmetry.
|
||||
std::swap(LHSB->getFirst(), RHSB->getFirst());
|
||||
if (hasLHSValue) {
|
||||
::new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond()));
|
||||
@@ -986,16 +1001,13 @@ public:
|
||||
}
|
||||
|
||||
void grow(unsigned AtLeast) {
|
||||
if (AtLeast >= InlineBuckets)
|
||||
if (AtLeast > InlineBuckets)
|
||||
AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast-1));
|
||||
|
||||
if (Small) {
|
||||
if (AtLeast < InlineBuckets)
|
||||
return; // Nothing to do.
|
||||
|
||||
// First move the inline buckets into a temporary storage.
|
||||
AlignedCharArrayUnion<BucketT[InlineBuckets]> TmpStorage;
|
||||
BucketT *TmpBegin = reinterpret_cast<BucketT *>(TmpStorage.buffer);
|
||||
BucketT *TmpBegin = reinterpret_cast<BucketT *>(&TmpStorage);
|
||||
BucketT *TmpEnd = TmpBegin;
|
||||
|
||||
// Loop over the buckets, moving non-empty, non-tombstones into the
|
||||
@@ -1015,10 +1027,13 @@ public:
|
||||
P->getFirst().~KeyT();
|
||||
}
|
||||
|
||||
// Now make this map use the large rep, and move all the entries back
|
||||
// into it.
|
||||
Small = false;
|
||||
new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
|
||||
// AtLeast == InlineBuckets can happen if there are many tombstones,
|
||||
// and grow() is used to remove them. Usually we always switch to the
|
||||
// large rep here.
|
||||
if (AtLeast > InlineBuckets) {
|
||||
Small = false;
|
||||
new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
|
||||
}
|
||||
this->moveFromOldBuckets(TmpBegin, TmpEnd);
|
||||
return;
|
||||
}
|
||||
@@ -1034,7 +1049,8 @@ public:
|
||||
this->moveFromOldBuckets(OldRep.Buckets, OldRep.Buckets+OldRep.NumBuckets);
|
||||
|
||||
// Free the old table.
|
||||
operator delete(OldRep.Buckets);
|
||||
deallocate_buffer(OldRep.Buckets, sizeof(BucketT) * OldRep.NumBuckets,
|
||||
alignof(BucketT));
|
||||
}
|
||||
|
||||
void shrink_and_clear() {
|
||||
@@ -1081,8 +1097,8 @@ private:
|
||||
assert(Small);
|
||||
// Note that this cast does not violate aliasing rules as we assert that
|
||||
// the memory's dynamic type is the small, inline bucket buffer, and the
|
||||
// 'storage.buffer' static type is 'char *'.
|
||||
return reinterpret_cast<const BucketT *>(storage.buffer);
|
||||
// 'storage' is a POD containing a char buffer.
|
||||
return reinterpret_cast<const BucketT *>(&storage);
|
||||
}
|
||||
|
||||
BucketT *getInlineBuckets() {
|
||||
@@ -1093,7 +1109,7 @@ private:
|
||||
const LargeRep *getLargeRep() const {
|
||||
assert(!Small);
|
||||
// Note, same rule about aliasing as with getInlineBuckets.
|
||||
return reinterpret_cast<const LargeRep *>(storage.buffer);
|
||||
return reinterpret_cast<const LargeRep *>(&storage);
|
||||
}
|
||||
|
||||
LargeRep *getLargeRep() {
|
||||
@@ -1118,15 +1134,17 @@ private:
|
||||
if (Small)
|
||||
return;
|
||||
|
||||
operator delete(getLargeRep()->Buckets);
|
||||
deallocate_buffer(getLargeRep()->Buckets,
|
||||
sizeof(BucketT) * getLargeRep()->NumBuckets,
|
||||
alignof(BucketT));
|
||||
getLargeRep()->~LargeRep();
|
||||
}
|
||||
|
||||
LargeRep allocateBuckets(unsigned Num) {
|
||||
assert(Num > InlineBuckets && "Must allocate more buckets than are inline");
|
||||
LargeRep Rep = {
|
||||
static_cast<BucketT*>(operator new(sizeof(BucketT) * Num)), Num
|
||||
};
|
||||
LargeRep Rep = {static_cast<BucketT *>(allocate_buffer(
|
||||
sizeof(BucketT) * Num, alignof(BucketT))),
|
||||
Num};
|
||||
return Rep;
|
||||
}
|
||||
};
|
||||
@@ -1137,8 +1155,6 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
|
||||
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
|
||||
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false>;
|
||||
|
||||
using ConstIterator = DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
|
||||
|
||||
public:
|
||||
using difference_type = ptrdiff_t;
|
||||
using value_type =
|
||||
@@ -1167,7 +1183,7 @@ public:
|
||||
// for const iterator destinations so it doesn't end up as a user defined copy
|
||||
// constructor.
|
||||
template <bool IsConstSrc,
|
||||
typename = typename std::enable_if<!IsConstSrc && IsConst>::type>
|
||||
typename = std::enable_if_t<!IsConstSrc && IsConst>>
|
||||
DenseMapIterator(
|
||||
const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc> &I)
|
||||
: DebugEpochBase::HandleBase(I), Ptr(I.Ptr), End(I.End) {}
|
||||
@@ -1181,19 +1197,18 @@ public:
|
||||
return Ptr;
|
||||
}
|
||||
|
||||
bool operator==(const ConstIterator &RHS) const {
|
||||
assert((!Ptr || isHandleInSync()) && "handle not in sync!");
|
||||
friend bool operator==(const DenseMapIterator &LHS,
|
||||
const DenseMapIterator &RHS) {
|
||||
assert((!LHS.Ptr || LHS.isHandleInSync()) && "handle not in sync!");
|
||||
assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
|
||||
assert(getEpochAddress() == RHS.getEpochAddress() &&
|
||||
assert(LHS.getEpochAddress() == RHS.getEpochAddress() &&
|
||||
"comparing incomparable iterators!");
|
||||
return Ptr == RHS.Ptr;
|
||||
return LHS.Ptr == RHS.Ptr;
|
||||
}
|
||||
bool operator!=(const ConstIterator &RHS) const {
|
||||
assert((!Ptr || isHandleInSync()) && "handle not in sync!");
|
||||
assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
|
||||
assert(getEpochAddress() == RHS.getEpochAddress() &&
|
||||
"comparing incomparable iterators!");
|
||||
return Ptr != RHS.Ptr;
|
||||
|
||||
friend bool operator!=(const DenseMapIterator &LHS,
|
||||
const DenseMapIterator &RHS) {
|
||||
return !(LHS == RHS);
|
||||
}
|
||||
|
||||
inline DenseMapIterator& operator++() { // Preincrement
|
||||
@@ -1236,4 +1251,4 @@ inline size_t capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
|
||||
|
||||
} // end namespace wpi
|
||||
|
||||
#endif // LLVM_ADT_DENSEMAP_H
|
||||
#endif // WPIUTIL_WPI_DENSEMAP_H
|
||||
|
||||
Reference in New Issue
Block a user