diff options
author | Stephen Hines <srhines@google.com> | 2014-04-23 16:57:46 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-04-24 15:53:16 -0700 |
commit | 36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch) | |
tree | e6cfb69fbbd937f450eeb83bfb83b9da3b01275a /include/llvm/ADT | |
parent | 69a8640022b04415ae9fac62f8ab090601d8f889 (diff) | |
download | external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2 |
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'include/llvm/ADT')
35 files changed, 686 insertions, 937 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 43a7866..acfefe9 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -1,4 +1,4 @@ -//== llvm/Support/APFloat.h - Arbitrary Precision Floating Point -*- C++ -*-==// +//===- llvm/ADT/APFloat.h - Arbitrary Precision Floating Point ---*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -196,6 +196,7 @@ public: explicit APFloat(double d); explicit APFloat(float f); APFloat(const APFloat &); + APFloat(APFloat &&); ~APFloat(); /// @} @@ -411,6 +412,7 @@ public: /// @} APFloat &operator=(const APFloat &); + APFloat &operator=(APFloat &&); /// \brief Overload to compute a hash code for an APFloat value. /// diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index d494ad2..aa3c3f6 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -284,12 +284,10 @@ public: initSlowCase(that); } -#if LLVM_HAS_RVALUE_REFERENCES /// \brief Move Constructor. APInt(APInt &&that) : BitWidth(that.BitWidth), VAL(that.VAL) { that.BitWidth = 0; } -#endif /// \brief Destructor. ~APInt() { @@ -656,7 +654,6 @@ public: return AssignSlowCase(RHS); } -#if LLVM_HAS_RVALUE_REFERENCES /// @brief Move assignment operator. APInt &operator=(APInt &&that) { if (!isSingleWord()) @@ -669,7 +666,6 @@ public: return *this; } -#endif /// \brief Assignment operator. /// @@ -1265,7 +1261,7 @@ public: /// \returns the number of words to hold the integer value with a given bit /// width. static unsigned getNumWords(unsigned BitWidth) { - return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; + return ((uint64_t)BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; } /// \brief Compute the number of active bits in the value @@ -1504,6 +1500,35 @@ public: return BitWidth - (*this - 1).countLeadingZeros(); } + /// \returns the nearest log base 2 of this APInt. Ties round up. + /// + /// NOTE: When we have a BitWidth of 1, we define: + /// + /// log2(0) = UINT32_MAX + /// log2(1) = 0 + /// + /// to get around any mathematical concerns resulting from + /// referencing 2 in a space where 2 does no exist. + unsigned nearestLogBase2() const { + // Special case when we have a bitwidth of 1. If VAL is 1, then we + // get 0. If VAL is 0, we get UINT64_MAX which gets truncated to + // UINT32_MAX. + if (BitWidth == 1) + return VAL - 1; + + // Handle the zero case. + if (!getBoolValue()) + return UINT32_MAX; + + // The non-zero case is handled by computing: + // + // nearestLogBase2(x) = logBase2(x) + x[logBase2(x)-1]. + // + // where x[i] is referring to the value of the ith bit of x. + unsigned lg = logBase2(); + return lg + unsigned((*this)[lg - 1]); + } + /// \returns the log base 2 of this APInt if its an exact power of two, -1 /// otherwise int32_t exactLogBase2() const { diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index ad035a7..053deff 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -30,18 +30,12 @@ public: explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {} - explicit APSInt(const APInt &I, bool isUnsigned = true) - : APInt(I), IsUnsigned(isUnsigned) {} + explicit APSInt(APInt I, bool isUnsigned = true) + : APInt(std::move(I)), IsUnsigned(isUnsigned) {} - APSInt &operator=(const APSInt &RHS) { - APInt::operator=(RHS); - IsUnsigned = RHS.IsUnsigned; - return *this; - } - - APSInt &operator=(const APInt &RHS) { + APSInt &operator=(APInt RHS) { // Retain our current sign. - APInt::operator=(RHS); + APInt::operator=(std::move(RHS)); return *this; } diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index e5562c3..fcf280d 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -12,6 +12,7 @@ #include "llvm/ADT/None.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Allocator.h" #include <vector> namespace llvm { @@ -76,7 +77,7 @@ namespace llvm { /// Construct an ArrayRef from a std::vector. template<typename A> /*implicit*/ ArrayRef(const std::vector<T, A> &Vec) - : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {} + : Data(Vec.data()), Length(Vec.size()) {} /// Construct an ArrayRef from a C array. template <size_t N> @@ -120,6 +121,13 @@ namespace llvm { return Data[Length-1]; } + // copy - Allocate copy in BumpPtrAllocator and return ArrayRef<T> to it. + ArrayRef<T> copy(BumpPtrAllocator &Allocator) { + T *Buff = Allocator.Allocate<T>(Length); + std::copy(begin(), end(), Buff); + return ArrayRef<T>(Buff, Length); + } + /// equals - Check for element-wise equality. bool equals(ArrayRef RHS) const { if (Length != RHS.Length) diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 8fb538f..b531820 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -58,14 +58,14 @@ public: reference& operator=(bool t) { if (t) - *WordRef |= 1L << BitPos; + *WordRef |= BitWord(1) << BitPos; else - *WordRef &= ~(1L << BitPos); + *WordRef &= ~(BitWord(1) << BitPos); return *this; } operator bool() const { - return ((*WordRef) & (1L << BitPos)) ? true : false; + return ((*WordRef) & (BitWord(1) << BitPos)) ? true : false; } }; @@ -98,12 +98,10 @@ public: std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); } -#if LLVM_HAS_RVALUE_REFERENCES BitVector(BitVector &&RHS) : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) { RHS.Bits = 0; } -#endif ~BitVector() { std::free(Bits); @@ -240,7 +238,7 @@ public: } BitVector &set(unsigned Idx) { - Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE); + Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE); return *this; } @@ -267,7 +265,8 @@ public: Bits[I / BITWORD_SIZE] = ~0UL; BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1; - Bits[I / BITWORD_SIZE] |= PostfixMask; + if (I < E) + Bits[I / BITWORD_SIZE] |= PostfixMask; return *this; } @@ -278,7 +277,7 @@ public: } BitVector &reset(unsigned Idx) { - Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE)); + Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE)); return *this; } @@ -305,7 +304,8 @@ public: Bits[I / BITWORD_SIZE] = 0UL; BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1; - Bits[I / BITWORD_SIZE] &= ~PostfixMask; + if (I < E) + Bits[I / BITWORD_SIZE] &= ~PostfixMask; return *this; } @@ -318,7 +318,7 @@ public: } BitVector &flip(unsigned Idx) { - Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE); + Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE); return *this; } @@ -330,7 +330,7 @@ public: bool operator[](unsigned Idx) const { 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; } @@ -459,7 +459,6 @@ public: return *this; } -#if LLVM_HAS_RVALUE_REFERENCES const BitVector &operator=(BitVector &&RHS) { if (this == &RHS) return *this; @@ -472,7 +471,6 @@ public: return *this; } -#endif void swap(BitVector &RHS) { std::swap(Bits, RHS.Bits); diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index ce322cc..037989f 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -161,7 +161,6 @@ public: return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true); } -#if LLVM_HAS_RVALUE_REFERENCES // Inserts key,value pair into the map if the key isn't already in the map. // If the key is already in the map, it returns false and doesn't update the // value. @@ -177,8 +176,7 @@ public: TheBucket); return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true); } -#endif - + /// insert - Range insertion of pairs. template<typename InputIt> void insert(InputIt I, InputIt E) { @@ -218,7 +216,6 @@ public: return FindAndConstruct(Key).second; } -#if LLVM_HAS_RVALUE_REFERENCES value_type& FindAndConstruct(KeyT &&Key) { BucketT *TheBucket; if (LookupBucketFor(Key, TheBucket)) @@ -230,7 +227,6 @@ public: ValueT &operator[](KeyT &&Key) { return FindAndConstruct(std::move(Key)).second; } -#endif /// isPointerIntoBucketsArray - Return true if the specified pointer points /// somewhere into the DenseMap's array of buckets (i.e. either to a key or @@ -289,8 +285,8 @@ protected: bool FoundVal = LookupBucketFor(B->first, DestBucket); (void)FoundVal; // silence warning. assert(!FoundVal && "Key already in new map?"); - DestBucket->first = llvm_move(B->first); - new (&DestBucket->second) ValueT(llvm_move(B->second)); + DestBucket->first = std::move(B->first); + new (&DestBucket->second) ValueT(std::move(B->second)); incrementNumEntries(); // Free the value. @@ -403,7 +399,6 @@ private: return TheBucket; } -#if LLVM_HAS_RVALUE_REFERENCES BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value, BucketT *TheBucket) { TheBucket = InsertIntoBucketImpl(Key, TheBucket); @@ -420,7 +415,6 @@ private: new (&TheBucket->second) ValueT(std::move(Value)); return TheBucket; } -#endif BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) { // If the load of the hash table is more than 3/4, or if fewer than 1/8 of @@ -555,12 +549,10 @@ public: copyFrom(other); } -#if LLVM_HAS_RVALUE_REFERENCES DenseMap(DenseMap &&other) : BaseT() { init(0); swap(other); } -#endif template<typename InputIt> DenseMap(const InputIt &I, const InputIt &E) { @@ -585,7 +577,6 @@ public: return *this; } -#if LLVM_HAS_RVALUE_REFERENCES DenseMap& operator=(DenseMap &&other) { this->destroyAll(); operator delete(Buckets); @@ -593,7 +584,6 @@ public: swap(other); return *this; } -#endif void copyFrom(const DenseMap& other) { this->destroyAll(); @@ -719,12 +709,10 @@ public: copyFrom(other); } -#if LLVM_HAS_RVALUE_REFERENCES SmallDenseMap(SmallDenseMap &&other) : BaseT() { init(0); swap(other); } -#endif template<typename InputIt> SmallDenseMap(const InputIt &I, const InputIt &E) { @@ -765,10 +753,10 @@ public: // Swap separately and handle any assymetry. std::swap(LHSB->first, RHSB->first); if (hasLHSValue) { - new (&RHSB->second) ValueT(llvm_move(LHSB->second)); + new (&RHSB->second) ValueT(std::move(LHSB->second)); LHSB->second.~ValueT(); } else if (hasRHSValue) { - new (&LHSB->second) ValueT(llvm_move(RHSB->second)); + new (&LHSB->second) ValueT(std::move(RHSB->second)); RHSB->second.~ValueT(); } } @@ -784,7 +772,7 @@ public: SmallDenseMap &LargeSide = Small ? RHS : *this; // First stash the large side's rep and move the small side across. - LargeRep TmpRep = llvm_move(*LargeSide.getLargeRep()); + LargeRep TmpRep = std::move(*LargeSide.getLargeRep()); LargeSide.getLargeRep()->~LargeRep(); LargeSide.Small = true; // This is similar to the standard move-from-old-buckets, but the bucket @@ -794,11 +782,11 @@ public: for (unsigned i = 0, e = InlineBuckets; i != e; ++i) { BucketT *NewB = &LargeSide.getInlineBuckets()[i], *OldB = &SmallSide.getInlineBuckets()[i]; - new (&NewB->first) KeyT(llvm_move(OldB->first)); + new (&NewB->first) KeyT(std::move(OldB->first)); OldB->first.~KeyT(); if (!KeyInfoT::isEqual(NewB->first, EmptyKey) && !KeyInfoT::isEqual(NewB->first, TombstoneKey)) { - new (&NewB->second) ValueT(llvm_move(OldB->second)); + new (&NewB->second) ValueT(std::move(OldB->second)); OldB->second.~ValueT(); } } @@ -806,7 +794,7 @@ public: // The hard part of moving the small buckets across is done, just move // the TmpRep into its new home. SmallSide.Small = false; - new (SmallSide.getLargeRep()) LargeRep(llvm_move(TmpRep)); + new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep)); } SmallDenseMap& operator=(const SmallDenseMap& other) { @@ -814,7 +802,6 @@ public: return *this; } -#if LLVM_HAS_RVALUE_REFERENCES SmallDenseMap& operator=(SmallDenseMap &&other) { this->destroyAll(); deallocateBuckets(); @@ -822,7 +809,6 @@ public: swap(other); return *this; } -#endif void copyFrom(const SmallDenseMap& other) { this->destroyAll(); @@ -830,7 +816,7 @@ public: Small = true; if (other.getNumBuckets() > InlineBuckets) { Small = false; - allocateBuckets(other.getNumBuckets()); + new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets())); } this->BaseT::copyFrom(other); } @@ -866,8 +852,8 @@ public: !KeyInfoT::isEqual(P->first, TombstoneKey)) { assert(size_t(TmpEnd - TmpBegin) < InlineBuckets && "Too many inline buckets!"); - new (&TmpEnd->first) KeyT(llvm_move(P->first)); - new (&TmpEnd->second) ValueT(llvm_move(P->second)); + new (&TmpEnd->first) KeyT(std::move(P->first)); + new (&TmpEnd->second) ValueT(std::move(P->second)); ++TmpEnd; P->second.~ValueT(); } @@ -882,7 +868,7 @@ public: return; } - LargeRep OldRep = llvm_move(*getLargeRep()); + LargeRep OldRep = std::move(*getLargeRep()); getLargeRep()->~LargeRep(); if (AtLeast <= InlineBuckets) { Small = true; @@ -991,7 +977,8 @@ class DenseMapIterator { friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>; public: typedef ptrdiff_t difference_type; - typedef typename conditional<IsConst, const Bucket, Bucket>::type value_type; + typedef typename std::conditional<IsConst, const Bucket, Bucket>::type + value_type; typedef value_type *pointer; typedef value_type &reference; typedef std::forward_iterator_tag iterator_category; diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h index d699ad5..1d8c39c 100644 --- a/include/llvm/ADT/DenseSet.h +++ b/include/llvm/ADT/DenseSet.h @@ -27,7 +27,9 @@ class DenseSet { typedef DenseMap<ValueT, char, ValueInfoT> MapTy; MapTy TheMap; public: - DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {} + typedef ValueT key_type; + typedef ValueT value_type; + explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {} bool empty() const { return TheMap.empty(); } @@ -54,11 +56,6 @@ public: TheMap.swap(RHS.TheMap); } - DenseSet &operator=(const DenseSet &RHS) { - TheMap = RHS.TheMap; - return *this; - } - // Iterators. class Iterator { diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h index 1d81772..2256ee7 100644 --- a/include/llvm/ADT/EquivalenceClasses.h +++ b/include/llvm/ADT/EquivalenceClasses.h @@ -249,7 +249,6 @@ public: explicit member_iterator() {} explicit member_iterator(const ECValue *N) : Node(N) {} - member_iterator(const member_iterator &I) : Node(I.Node) {} reference operator*() const { assert(Node != 0 && "Dereferencing end()!"); diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index 1b2c94c..188010d 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -18,12 +18,12 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/DataTypes.h" namespace llvm { class APFloat; class APInt; - class BumpPtrAllocator; /// This folding set used for two purposes: /// 1. Given information about a node we want to create, look up the unique @@ -278,6 +278,8 @@ public: bool operator==(FoldingSetNodeIDRef) const; + bool operator!=(FoldingSetNodeIDRef RHS) const { return !(*this == RHS); } + /// Used to compare the "ordering" of two nodes as defined by the /// profiled bits and their ordering defined by memcmp(). bool operator<(FoldingSetNodeIDRef) const; @@ -331,6 +333,9 @@ public: bool operator==(const FoldingSetNodeID &RHS) const; bool operator==(const FoldingSetNodeIDRef RHS) const; + bool operator!=(const FoldingSetNodeID &RHS) const { return !(*this == RHS); } + bool operator!=(const FoldingSetNodeIDRef RHS) const { return !(*this ==RHS);} + /// Used to compare the "ordering" of two nodes as defined by the /// profiled bits and their ordering defined by memcmp(). bool operator<(const FoldingSetNodeID &RHS) const; @@ -391,20 +396,20 @@ template<class T> class FoldingSet : public FoldingSetImpl { private: /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a /// way to convert nodes into a unique specifier. - virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const { + void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const override { T *TN = static_cast<T *>(N); FoldingSetTrait<T>::Profile(*TN, ID); } /// NodeEquals - Instantiations may optionally provide a way to compare a /// node with a specified ID. - virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash, - FoldingSetNodeID &TempID) const { + bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash, + FoldingSetNodeID &TempID) const override { T *TN = static_cast<T *>(N); return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID); } /// ComputeNodeHash - Instantiations may optionally provide a way to compute a /// hash value directly from a node. - virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const { + unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const override { T *TN = static_cast<T *>(N); return FoldingSetTrait<T>::ComputeHash(*TN, TempID); } @@ -468,20 +473,19 @@ private: /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a /// way to convert nodes into a unique specifier. - virtual void GetNodeProfile(FoldingSetImpl::Node *N, - FoldingSetNodeID &ID) const { + void GetNodeProfile(FoldingSetImpl::Node *N, + FoldingSetNodeID &ID) const override { T *TN = static_cast<T *>(N); ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context); } - virtual bool NodeEquals(FoldingSetImpl::Node *N, - const FoldingSetNodeID &ID, unsigned IDHash, - FoldingSetNodeID &TempID) const { + bool NodeEquals(FoldingSetImpl::Node *N, const FoldingSetNodeID &ID, + unsigned IDHash, FoldingSetNodeID &TempID) const override { T *TN = static_cast<T *>(N); return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID, Context); } - virtual unsigned ComputeNodeHash(FoldingSetImpl::Node *N, - FoldingSetNodeID &TempID) const { + unsigned ComputeNodeHash(FoldingSetImpl::Node *N, + FoldingSetNodeID &TempID) const override { T *TN = static_cast<T *>(N); return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context); } diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h index e434417..4bffd8e 100644 --- a/include/llvm/ADT/Hashing.h +++ b/include/llvm/ADT/Hashing.h @@ -109,7 +109,8 @@ public: /// differing argument types even if they would implicit promote to a common /// type without changing the value. template <typename T> -typename enable_if<is_integral_or_enum<T>, hash_code>::type hash_value(T value); +typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type +hash_value(T value); /// \brief Compute a hash_code for a pointer's address. /// @@ -352,24 +353,24 @@ inline size_t get_execution_seed() { // 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 - : integral_constant<bool, ((is_integral_or_enum<T>::value || - is_pointer<T>::value) && - 64 % sizeof(T) == 0)> {}; + : 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> > - : integral_constant<bool, (is_hashable_data<T>::value && - is_hashable_data<U>::value && - (sizeof(T) + sizeof(U)) == - sizeof(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>))> {}; /// \brief Helper to get the hashable data representation for a type. /// This variant is enabled when the type itself can be used. template <typename T> -typename enable_if<is_hashable_data<T>, T>::type +typename std::enable_if<is_hashable_data<T>::value, T>::type get_hashable_data(const T &value) { return value; } @@ -377,7 +378,7 @@ get_hashable_data(const T &value) { /// This variant is enabled when we must first call hash_value and use the /// result as our data. template <typename T> -typename enable_if_c<!is_hashable_data<T>::value, size_t>::type +typename std::enable_if<!is_hashable_data<T>::value, size_t>::type get_hashable_data(const T &value) { using ::llvm::hash_value; return hash_value(value); @@ -451,7 +452,7 @@ hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) { /// are stored in contiguous memory, this routine avoids copying each value /// and directly reads from the underlying memory. template <typename ValueT> -typename enable_if<is_hashable_data<ValueT>, hash_code>::type +typename std::enable_if<is_hashable_data<ValueT>::value, hash_code>::type hash_combine_range_impl(ValueT *first, ValueT *last) { const size_t seed = get_execution_seed(); const char *s_begin = reinterpret_cast<const char *>(first); @@ -734,7 +735,7 @@ inline hash_code hash_integer_value(uint64_t value) { // Declared and documented above, but defined here so that any of the hashing // infrastructure is available. template <typename T> -typename enable_if<is_integral_or_enum<T>, hash_code>::type +typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type hash_value(T value) { return ::llvm::hashing::detail::hash_integer_value(value); } diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index b8b8861..729e37f 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -23,6 +23,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include <atomic> #include <memory> namespace llvm { @@ -88,6 +89,31 @@ namespace llvm { static void retain(T *obj) { obj->Retain(); } static void release(T *obj) { obj->Release(); } }; + +/// \brief A thread-safe version of \c llvm::RefCountedBase. +/// +/// A generic base class for objects that wish to have their lifetimes managed +/// using reference counts. Classes subclass \c ThreadSafeRefCountedBase to +/// obtain such functionality, and are typically handled with +/// \c IntrusiveRefCntPtr "smart pointers" which automatically handle the +/// management of reference counts. +template <class Derived> +class ThreadSafeRefCountedBase { + mutable std::atomic<int> RefCount; + +protected: + ThreadSafeRefCountedBase() : RefCount(0) {} + +public: + void Retain() const { ++RefCount; } + + void Release() const { + int NewRefCount = --RefCount; + assert(NewRefCount >= 0 && "Reference count was already zero."); + if (NewRefCount == 0) + delete static_cast<const Derived*>(this); + } +}; //===----------------------------------------------------------------------===// /// IntrusiveRefCntPtr - A template class that implements a "smart pointer" @@ -109,7 +135,7 @@ namespace llvm { template <typename T> class IntrusiveRefCntPtr { T* Obj; - typedef IntrusiveRefCntPtr this_type; + public: typedef T element_type; @@ -123,7 +149,6 @@ namespace llvm { retain(); } -#if LLVM_HAS_RVALUE_REFERENCES IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) { S.Obj = 0; } @@ -132,7 +157,6 @@ namespace llvm { IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.getPtr()) { S.Obj = 0; } -#endif template <class X> IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S) diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h index f6fcb08..7fd1570 100644 --- a/include/llvm/ADT/MapVector.h +++ b/include/llvm/ADT/MapVector.h @@ -1,4 +1,4 @@ -//===- llvm/ADT/MapVector.h - Map with deterministic value order *- C++ -*-===// +//===- llvm/ADT/MapVector.h - Map w/ deterministic value order --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -17,9 +17,7 @@ #ifndef LLVM_ADT_MAPVECTOR_H #define LLVM_ADT_MAPVECTOR_H -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/STLExtras.h" #include <vector> namespace llvm { @@ -97,7 +95,7 @@ public: if (Result.second) { Vector.push_back(std::make_pair(KV.first, KV.second)); I = Vector.size() - 1; - return std::make_pair(llvm::prior(end()), true); + return std::make_pair(std::prev(end()), true); } return std::make_pair(begin() + I, false); } diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index 194e53f..ae8344d 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -17,13 +17,10 @@ #define LLVM_ADT_OPTIONAL_H #include "llvm/ADT/None.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/AlignOf.h" +#include "llvm/Support/Compiler.h" #include <cassert> - -#if LLVM_HAS_RVALUE_REFERENCES #include <utility> -#endif namespace llvm { @@ -42,7 +39,6 @@ public: new (storage.buffer) T(*O); } -#if LLVM_HAS_RVALUE_REFERENCES Optional(T &&y) : hasVal(true) { new (storage.buffer) T(std::forward<T>(y)); } @@ -70,7 +66,6 @@ public: } return *this; } -#endif static inline Optional create(const T* y) { return y ? Optional(*y) : Optional(); diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h index 6b9e42e..034bcfd 100644 --- a/include/llvm/ADT/OwningPtr.h +++ b/include/llvm/ADT/OwningPtr.h @@ -17,6 +17,7 @@ #include "llvm/Support/Compiler.h" #include <cassert> #include <cstddef> +#include <memory> namespace llvm { @@ -32,13 +33,22 @@ class OwningPtr { public: explicit OwningPtr(T *P = 0) : Ptr(P) {} -#if LLVM_HAS_RVALUE_REFERENCES OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {} OwningPtr &operator=(OwningPtr &&Other) { reset(Other.take()); return *this; } + + OwningPtr(std::unique_ptr<T> Other) : Ptr(Other.release()) {} + + OwningPtr &operator=(std::unique_ptr<T> Other) { + reset(Other.release()); + return *this; + } + +#if LLVM_HAS_RVALUE_REFERENCE_THIS + operator std::unique_ptr<T>() && { return std::unique_ptr<T>(take()); } #endif ~OwningPtr() { @@ -63,6 +73,10 @@ public: return Tmp; } + T *release() { return take(); } + + std::unique_ptr<T> take_unique() { return std::unique_ptr<T>(take()); } + T &operator*() const { assert(Ptr && "Cannot dereference null pointer"); return *Ptr; @@ -96,14 +110,12 @@ class OwningArrayPtr { public: explicit OwningArrayPtr(T *P = 0) : Ptr(P) {} -#if LLVM_HAS_RVALUE_REFERENCES OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {} OwningArrayPtr &operator=(OwningArrayPtr &&Other) { reset(Other.take()); return *this; } -#endif ~OwningArrayPtr() { delete [] Ptr; diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 0cfd470..45a40db 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -17,6 +17,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include <cassert> +#include <limits> namespace llvm { @@ -41,7 +42,12 @@ template <typename PointerTy, unsigned IntBits, typename IntType=unsigned, typename PtrTraits = PointerLikeTypeTraits<PointerTy> > class PointerIntPair { intptr_t Value; - enum LLVM_ENUM_INT_TYPE(uintptr_t) { + static_assert(PtrTraits::NumLowBitsAvailable < + std::numeric_limits<uintptr_t>::digits, + "cannot use a pointer type that has all bits free"); + static_assert(IntBits <= PtrTraits::NumLowBitsAvailable, + "PointerIntPair with integer size too large for pointer"); + enum : uintptr_t { /// PointerBitMask - The bits that come from the pointer. PointerBitMask = ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1), @@ -59,8 +65,6 @@ class PointerIntPair { public: PointerIntPair() : Value(0) {} PointerIntPair(PointerTy PtrVal, IntType IntVal) { - assert(IntBits <= PtrTraits::NumLowBitsAvailable && - "PointerIntPair formed with integer size too large for pointer"); setPointerAndInt(PtrVal, IntVal); } explicit PointerIntPair(PointerTy PtrVal) { @@ -79,7 +83,7 @@ public: void setPointer(PointerTy PtrVal) { intptr_t PtrWord = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal)); - assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && + assert((PtrWord & ~PointerBitMask) == 0 && "Pointer is not sufficiently aligned"); // Preserve all low bits, just update the pointer. Value = PtrWord | (Value & ~PointerBitMask); @@ -87,7 +91,7 @@ public: void setInt(IntType IntVal) { intptr_t IntWord = static_cast<intptr_t>(IntVal); - assert(IntWord < (1 << IntBits) && "Integer too large for field"); + assert((IntWord & ~IntMask) == 0 && "Integer too large for field"); // Preserve all bits other than the ones we are updating. Value &= ~ShiftedIntMask; // Remove integer field. @@ -97,7 +101,7 @@ public: void initWithPointer(PointerTy PtrVal) { intptr_t PtrWord = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal)); - assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && + assert((PtrWord & ~PointerBitMask) == 0 && "Pointer is not sufficiently aligned"); Value = PtrWord; } @@ -105,10 +109,10 @@ public: void setPointerAndInt(PointerTy PtrVal, IntType IntVal) { intptr_t PtrWord = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal)); - assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && + assert((PtrWord & ~PointerBitMask) == 0 && "Pointer is not sufficiently aligned"); intptr_t IntWord = static_cast<intptr_t>(IntVal); - assert(IntWord < (1 << IntBits) && "Integer too large for field"); + assert((IntWord & ~IntMask) == 0 && "Integer too large for field"); Value = PtrWord | (IntWord << IntShift); } @@ -158,13 +162,13 @@ struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > { typedef PointerIntPair<PointerTy, IntBits, IntType> Ty; static Ty getEmptyKey() { uintptr_t Val = static_cast<uintptr_t>(-1); - Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable; - return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1)); + Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable; + return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val)); } static Ty getTombstoneKey() { uintptr_t Val = static_cast<uintptr_t>(-2); Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable; - return Ty(reinterpret_cast<PointerTy>(Val), IntType(0)); + return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val)); } static unsigned getHashValue(Ty V) { uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue()); diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index 05d362f..8cbe8d1 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -15,8 +15,8 @@ #ifndef LLVM_ADT_POINTERUNION_H #define LLVM_ADT_POINTERUNION_H -#include "llvm/Support/Compiler.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/Compiler.h" namespace llvm { diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h index 8ce4fd5..58ac149 100644 --- a/include/llvm/ADT/SCCIterator.h +++ b/include/llvm/ADT/SCCIterator.h @@ -6,16 +6,18 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected -// components (SCCs) of a graph in O(N+E) time using Tarjan's DFS algorithm. -// -// The SCC iterator has the important property that if a node in SCC S1 has an -// edge to a node in SCC S2, then it visits S1 *after* S2. -// -// To visit S1 *before* S2, use the scc_iterator on the Inverse graph. -// (NOTE: This requires some simple wrappers and is not supported yet.) -// +/// \file +/// +/// This builds on the llvm/ADT/GraphTraits.h file to find the strongly +/// connected components (SCCs) of a graph in O(N+E) time using Tarjan's DFS +/// algorithm. +/// +/// The SCC iterator has the important property that if a node in SCC S1 has an +/// edge to a node in SCC S2, then it visits S1 *after* S2. +/// +/// To visit S1 *before* S2, use the scc_iterator on the Inverse graph. (NOTE: +/// This requires some simple wrappers and is not supported yet.) +/// //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_SCCITERATOR_H @@ -27,90 +29,111 @@ namespace llvm { -//===----------------------------------------------------------------------===// +/// \brief Enumerate the SCCs of a directed graph in reverse topological order +/// of the SCC DAG. /// -/// scc_iterator - Enumerate the SCCs of a directed graph, in -/// reverse topological order of the SCC DAG. -/// -template<class GraphT, class GT = GraphTraits<GraphT> > +/// This is implemented using Tarjan's DFS algorithm using an internal stack to +/// build up a vector of nodes in a particular SCC. Note that it is a forward +/// iterator and thus you cannot backtrack or re-visit nodes. +template <class GraphT, class GT = GraphTraits<GraphT> > class scc_iterator - : public std::iterator<std::forward_iterator_tag, - std::vector<typename GT::NodeType>, ptrdiff_t> { - typedef typename GT::NodeType NodeType; + : public std::iterator<std::forward_iterator_tag, + std::vector<typename GT::NodeType>, ptrdiff_t> { + typedef typename GT::NodeType NodeType; typedef typename GT::ChildIteratorType ChildItTy; - typedef std::vector<NodeType*> SccTy; + typedef std::vector<NodeType *> SccTy; typedef std::iterator<std::forward_iterator_tag, std::vector<typename GT::NodeType>, ptrdiff_t> super; typedef typename super::reference reference; typedef typename super::pointer pointer; + // Element of VisitStack during DFS. + struct StackElement { + NodeType *Node; ///< The current node pointer. + ChildItTy NextChild; ///< The next child, modified inplace during DFS. + unsigned MinVisited; ///< Minimum uplink value of all children of Node. + + StackElement(NodeType *Node, const ChildItTy &Child, unsigned Min) + : Node(Node), NextChild(Child), MinVisited(Min) {} + + bool operator==(const StackElement &Other) const { + return Node == Other.Node && + NextChild == Other.NextChild && + MinVisited == Other.MinVisited; + } + }; + // The visit counters used to detect when a complete SCC is on the stack. // visitNum is the global counter. // nodeVisitNumbers are per-node visit numbers, also used as DFS flags. unsigned visitNum; DenseMap<NodeType *, unsigned> nodeVisitNumbers; - // SCCNodeStack - Stack holding nodes of the SCC. + // Stack holding nodes of the SCC. std::vector<NodeType *> SCCNodeStack; - // CurrentSCC - The current SCC, retrieved using operator*(). + // The current SCC, retrieved using operator*(). SccTy CurrentSCC; - // VisitStack - Used to maintain the ordering. Top = current block - // First element is basic block pointer, second is the 'next child' to visit - std::vector<std::pair<NodeType *, ChildItTy> > VisitStack; - // MinVisitNumStack - Stack holding the "min" values for each node in the DFS. - // This is used to track the minimum uplink values for all children of - // the corresponding node on the VisitStack. - std::vector<unsigned> MinVisitNumStack; + // DFS stack, Used to maintain the ordering. The top contains the current + // node, the next child to visit, and the minimum uplink value of all child + std::vector<StackElement> VisitStack; // A single "visit" within the non-recursive DFS traversal. void DFSVisitOne(NodeType *N) { - ++visitNum; // Global counter for the visit order + ++visitNum; nodeVisitNumbers[N] = visitNum; SCCNodeStack.push_back(N); - MinVisitNumStack.push_back(visitNum); - VisitStack.push_back(std::make_pair(N, GT::child_begin(N))); - //dbgs() << "TarjanSCC: Node " << N << - // " : visitNum = " << visitNum << "\n"; + VisitStack.push_back(StackElement(N, GT::child_begin(N), visitNum)); +#if 0 // Enable if needed when debugging. + dbgs() << "TarjanSCC: Node " << N << + " : visitNum = " << visitNum << "\n"; +#endif } // The stack-based DFS traversal; defined below. void DFSVisitChildren() { assert(!VisitStack.empty()); - while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) { + while (VisitStack.back().NextChild != + GT::child_end(VisitStack.back().Node)) { // TOS has at least one more child so continue DFS - NodeType *childN = *VisitStack.back().second++; - if (!nodeVisitNumbers.count(childN)) { + NodeType *childN = *VisitStack.back().NextChild++; + typename DenseMap<NodeType *, unsigned>::iterator Visited = + nodeVisitNumbers.find(childN); + if (Visited == nodeVisitNumbers.end()) { // this node has never been seen. DFSVisitOne(childN); continue; } - unsigned childNum = nodeVisitNumbers[childN]; - if (MinVisitNumStack.back() > childNum) - MinVisitNumStack.back() = childNum; + unsigned childNum = Visited->second; + if (VisitStack.back().MinVisited > childNum) + VisitStack.back().MinVisited = childNum; } } // Compute the next SCC using the DFS traversal. void GetNextSCC() { - assert(VisitStack.size() == MinVisitNumStack.size()); - CurrentSCC.clear(); // Prepare to compute the next SCC + CurrentSCC.clear(); // Prepare to compute the next SCC while (!VisitStack.empty()) { DFSVisitChildren(); - assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first)); - NodeType *visitingN = VisitStack.back().first; - unsigned minVisitNum = MinVisitNumStack.back(); + + // Pop the leaf on top of the VisitStack. + NodeType *visitingN = VisitStack.back().Node; + unsigned minVisitNum = VisitStack.back().MinVisited; + assert(VisitStack.back().NextChild == GT::child_end(visitingN)); VisitStack.pop_back(); - MinVisitNumStack.pop_back(); - if (!MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum) - MinVisitNumStack.back() = minVisitNum; - //dbgs() << "TarjanSCC: Popped node " << visitingN << - // " : minVisitNum = " << minVisitNum << "; Node visit num = " << - // nodeVisitNumbers[visitingN] << "\n"; + // Propagate MinVisitNum to parent so we can detect the SCC starting node. + if (!VisitStack.empty() && VisitStack.back().MinVisited > minVisitNum) + VisitStack.back().MinVisited = minVisitNum; + +#if 0 // Enable if needed when debugging. + dbgs() << "TarjanSCC: Popped node " << visitingN << + " : minVisitNum = " << minVisitNum << "; Node visit num = " << + nodeVisitNumbers[visitingN] << "\n"; +#endif if (minVisitNum != nodeVisitNumbers[visitingN]) continue; @@ -132,36 +155,38 @@ class scc_iterator DFSVisitOne(entryN); GetNextSCC(); } - inline scc_iterator() { /* End is when DFS stack is empty */ } -public: - typedef scc_iterator<GraphT, GT> _Self; + // End is when the DFS stack is empty. + inline scc_iterator() {} - // Provide static "constructors"... - static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));} - static inline _Self end (const GraphT &) { return _Self(); } +public: + static inline scc_iterator begin(const GraphT &G) { + return scc_iterator(GT::getEntryNode(G)); + } + static inline scc_iterator end(const GraphT &) { return scc_iterator(); } - // Direct loop termination test: I.isAtEnd() is more efficient than I == end() + /// \brief Direct loop termination test which is more efficient than + /// comparison with \c end(). inline bool isAtEnd() const { assert(!CurrentSCC.empty() || VisitStack.empty()); return CurrentSCC.empty(); } - inline bool operator==(const _Self& x) const { + inline bool operator==(const scc_iterator &x) const { return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC; } - inline bool operator!=(const _Self& x) const { return !operator==(x); } + inline bool operator!=(const scc_iterator &x) const { return !operator==(x); } - // Iterator traversal: forward iteration only - inline _Self& operator++() { // Preincrement + inline scc_iterator &operator++() { GetNextSCC(); return *this; } - inline _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; + inline scc_iterator operator++(int) { + scc_iterator tmp = *this; + ++*this; + return tmp; } - // Retrieve a reference to the current SCC inline const SccTy &operator*() const { assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!"); return CurrentSCC; @@ -171,21 +196,24 @@ public: return CurrentSCC; } - // hasLoop() -- Test if the current SCC has a loop. If it has more than one - // node, this is trivially true. If not, it may still contain a loop if the - // node has an edge back to itself. + /// \brief Test if the current SCC has a loop. + /// + /// If the SCC has more than one node, this is trivially true. If not, it may + /// still contain a loop if the node has an edge back to itself. bool hasLoop() const { assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!"); - if (CurrentSCC.size() > 1) return true; + if (CurrentSCC.size() > 1) + return true; NodeType *N = CurrentSCC.front(); - for (ChildItTy CI = GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI) + for (ChildItTy CI = GT::child_begin(N), CE = GT::child_end(N); CI != CE; + ++CI) if (*CI == N) return true; return false; } - /// ReplaceNode - This informs the scc_iterator that the specified Old node - /// has been deleted, and New is to be used in its place. + /// This informs the \c scc_iterator that the specified \c Old node + /// has been deleted, and \c New is to be used in its place. void ReplaceNode(NodeType *Old, NodeType *New) { assert(nodeVisitNumbers.count(Old) && "Old not in scc_iterator?"); nodeVisitNumbers[New] = nodeVisitNumbers[Old]; @@ -193,25 +221,23 @@ public: } }; - -// Global constructor for the SCC iterator. -template <class T> -scc_iterator<T> scc_begin(const T &G) { +/// \brief Construct the begin iterator for a deduced graph type T. +template <class T> scc_iterator<T> scc_begin(const T &G) { return scc_iterator<T>::begin(G); } -template <class T> -scc_iterator<T> scc_end(const T &G) { +/// \brief Construct the end iterator for a deduced graph type T. +template <class T> scc_iterator<T> scc_end(const T &G) { return scc_iterator<T>::end(G); } -template <class T> -scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) { +/// \brief Construct the begin iterator for a deduced graph type T's Inverse<T>. +template <class T> scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) { return scc_iterator<Inverse<T> >::begin(G); } -template <class T> -scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) { +/// \brief Construct the end iterator for a deduced graph type T's Inverse<T>. +template <class T> scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) { return scc_iterator<Inverse<T> >::end(G); } diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 3aa8183..ab6884f 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -17,10 +17,12 @@ #ifndef LLVM_ADT_STLEXTRAS_H #define LLVM_ADT_STLEXTRAS_H +#include "llvm/Support/Compiler.h" #include <cstddef> // for std::size_t #include <cstdlib> // for qsort #include <functional> #include <iterator> +#include <memory> #include <utility> // for std::pair namespace llvm { @@ -95,8 +97,6 @@ public: inline explicit mapped_iterator(const RootIt &I, UnaryFunc F) : current(I), Fn(F) {} - inline mapped_iterator(const mapped_iterator &It) - : current(It.current), Fn(It.Fn) {} inline value_type operator*() const { // All this work to do this return Fn(*current); // little change @@ -141,82 +141,10 @@ inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) { return mapped_iterator<ItTy, FuncTy>(I, F); } - -// next/prior - These functions unlike std::advance do not modify the -// passed iterator but return a copy. -// -// next(myIt) returns copy of myIt incremented once -// next(myIt, n) returns copy of myIt incremented n times -// prior(myIt) returns copy of myIt decremented once -// prior(myIt, n) returns copy of myIt decremented n times - -template <typename ItTy, typename Dist> -inline ItTy next(ItTy it, Dist n) -{ - std::advance(it, n); - return it; -} - -template <typename ItTy> -inline ItTy next(ItTy it) -{ - return ++it; -} - -template <typename ItTy, typename Dist> -inline ItTy prior(ItTy it, Dist n) -{ - std::advance(it, -n); - return it; -} - -template <typename ItTy> -inline ItTy prior(ItTy it) -{ - return --it; -} - //===----------------------------------------------------------------------===// // Extra additions to <utility> //===----------------------------------------------------------------------===// -// tie - this function ties two objects and returns a temporary object -// that is assignable from a std::pair. This can be used to make code -// more readable when using values returned from functions bundled in -// a std::pair. Since an example is worth 1000 words: -// -// typedef std::map<int, int> Int2IntMap; -// -// Int2IntMap myMap; -// Int2IntMap::iterator where; -// bool inserted; -// tie(where, inserted) = myMap.insert(std::make_pair(123,456)); -// -// if (inserted) -// // do stuff -// else -// // do other stuff -template <typename T1, typename T2> -struct tier { - typedef T1 &first_type; - typedef T2 &second_type; - - first_type first; - second_type second; - - tier(first_type f, second_type s) : first(f), second(s) { } - tier& operator=(const std::pair<T1, T2>& p) { - first = p.first; - second = p.second; - return *this; - } -}; - -template <typename T1, typename T2> -inline tier<T1, T2> tie(T1& f, T2& s) { - return tier<T1, T2>(f, s); -} - /// \brief Function object to check whether the first component of a std::pair /// compares less than the first component of another std::pair. struct less_first { @@ -327,6 +255,163 @@ void DeleteContainerSeconds(Container &C) { C.clear(); } +//===----------------------------------------------------------------------===// +// Extra additions to <memory> +//===----------------------------------------------------------------------===// + +#if LLVM_HAS_VARIADIC_TEMPLATES + +// Implement make_unique according to N3656. + +/// \brief Constructs a `new T()` with the given args and returns a +/// `unique_ptr<T>` which owns the object. +/// +/// Example: +/// +/// auto p = make_unique<int>(); +/// auto p = make_unique<std::tuple<int, int>>(0, 1); +template <class T, class... Args> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Args &&... args) { + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); +} + +/// \brief Constructs a `new T[n]` with the given args and returns a +/// `unique_ptr<T[]>` which owns the object. +/// +/// \param n size of the new array. +/// +/// Example: +/// +/// auto p = make_unique<int[]>(2); // value-initializes the array with 0's. +template <class T> +typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0, + std::unique_ptr<T>>::type +make_unique(size_t n) { + return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]()); +} + +/// This function isn't used and is only here to provide better compile errors. +template <class T, class... Args> +typename std::enable_if<std::extent<T>::value != 0>::type +make_unique(Args &&...) LLVM_DELETED_FUNCTION; + +#else + +template <class T> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique() { + return std::unique_ptr<T>(new T()); +} + +template <class T, class Arg1> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Arg1 &&arg1) { + return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1))); +} + +template <class T, class Arg1, class Arg2> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Arg1 &&arg1, Arg2 &&arg2) { + return std::unique_ptr<T>( + new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2))); +} + +template <class T, class Arg1, class Arg2, class Arg3> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3) { + return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1), + std::forward<Arg2>(arg2), + std::forward<Arg3>(arg3))); +} + +template <class T, class Arg1, class Arg2, class Arg3, class Arg4> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4) { + return std::unique_ptr<T>( + new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), + std::forward<Arg3>(arg3), std::forward<Arg4>(arg4))); +} + +template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5) { + return std::unique_ptr<T>( + new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), + std::forward<Arg3>(arg3), std::forward<Arg4>(arg4), + std::forward<Arg5>(arg5))); +} + +template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, + class Arg6> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5, + Arg6 &&arg6) { + return std::unique_ptr<T>( + new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), + std::forward<Arg3>(arg3), std::forward<Arg4>(arg4), + std::forward<Arg5>(arg5), std::forward<Arg6>(arg6))); +} + +template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, + class Arg6, class Arg7> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5, + Arg6 &&arg6, Arg7 &&arg7) { + return std::unique_ptr<T>( + new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), + std::forward<Arg3>(arg3), std::forward<Arg4>(arg4), + std::forward<Arg5>(arg5), std::forward<Arg6>(arg6), + std::forward<Arg7>(arg7))); +} + +template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, + class Arg6, class Arg7, class Arg8> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5, + Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8) { + return std::unique_ptr<T>( + new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), + std::forward<Arg3>(arg3), std::forward<Arg4>(arg4), + std::forward<Arg5>(arg5), std::forward<Arg6>(arg6), + std::forward<Arg7>(arg7), std::forward<Arg8>(arg8))); +} + +template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, + class Arg6, class Arg7, class Arg8, class Arg9> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5, + Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8, Arg9 &&arg9) { + return std::unique_ptr<T>( + new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), + std::forward<Arg3>(arg3), std::forward<Arg4>(arg4), + std::forward<Arg5>(arg5), std::forward<Arg6>(arg6), + std::forward<Arg7>(arg7), std::forward<Arg8>(arg8), + std::forward<Arg9>(arg9))); +} + +template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, + class Arg6, class Arg7, class Arg8, class Arg9, class Arg10> +typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5, + Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8, Arg9 &&arg9, Arg10 &&arg10) { + return std::unique_ptr<T>( + new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), + std::forward<Arg3>(arg3), std::forward<Arg4>(arg4), + std::forward<Arg5>(arg5), std::forward<Arg6>(arg6), + std::forward<Arg7>(arg7), std::forward<Arg8>(arg8), + std::forward<Arg9>(arg9), std::forward<Arg10>(arg10))); +} + +template <class T> +typename std::enable_if<std::is_array<T>::value &&std::extent<T>::value == 0, + std::unique_ptr<T>>::type +make_unique(size_t n) { + return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]()); +} + +#endif + } // End llvm namespace #endif diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h index 5eda37c..1e7d237 100644 --- a/include/llvm/ADT/SetVector.h +++ b/include/llvm/ADT/SetVector.h @@ -195,11 +195,10 @@ private: set_type &set_; public: - typedef typename UnaryPredicate::argument_type argument_type; - TestAndEraseFromSet(UnaryPredicate P, set_type &set_) : P(P), set_(set_) {} - bool operator()(argument_type Arg) { + template <typename ArgumentT> + bool operator()(const ArgumentT &Arg) { if (P(Arg)) { set_.erase(Arg); return true; diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 86949b2..e965bc4 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -153,11 +153,9 @@ public: switchToLarge(new BitVector(*RHS.getPointer())); } -#if LLVM_HAS_RVALUE_REFERENCES SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) { RHS.X = 1; } -#endif ~SmallBitVector() { if (!isSmall()) @@ -506,7 +504,6 @@ public: return *this; } -#if LLVM_HAS_RVALUE_REFERENCES const SmallBitVector &operator=(SmallBitVector &&RHS) { if (this != &RHS) { clear(); @@ -514,7 +511,6 @@ public: } return *this; } -#endif void swap(SmallBitVector &RHS) { std::swap(X, RHS.X); diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index bd0d883..67104f3 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file defines the SmallPtrSet class. See the doxygen comment for -// SmallPtrSetImpl for more details on the algorithm used. +// SmallPtrSetImplBase for more details on the algorithm used. // //===----------------------------------------------------------------------===// @@ -27,7 +27,7 @@ namespace llvm { class SmallPtrSetIteratorImpl; -/// SmallPtrSetImpl - This is the common code shared among all the +/// SmallPtrSetImplBase - This is the common code shared among all the /// SmallPtrSet<>'s, which is almost everything. SmallPtrSet has two modes, one /// for small and one for large sets. /// @@ -45,7 +45,7 @@ class SmallPtrSetIteratorImpl; /// (-2), to allow deletion. The hash table is resized when the table is 3/4 or /// more. When this happens, the table is doubled in size. /// -class SmallPtrSetImpl { +class SmallPtrSetImplBase { friend class SmallPtrSetIteratorImpl; protected: /// SmallArray - Points to a fixed size set of buckets, used in 'small mode'. @@ -60,15 +60,17 @@ protected: unsigned NumElements; unsigned NumTombstones; - // Helper to copy construct a SmallPtrSet. - SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl& that); - explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize) : + // Helpers to copy and move construct a SmallPtrSet. + SmallPtrSetImplBase(const void **SmallStorage, const SmallPtrSetImplBase &that); + SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize, + SmallPtrSetImplBase &&that); + explicit SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize) : SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) { assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 && "Initial size must be a power of two!"); clear(); } - ~SmallPtrSetImpl(); + ~SmallPtrSetImplBase(); public: bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return size() == 0; } @@ -128,13 +130,14 @@ private: /// Grow - Allocate a larger backing store for the buckets and move it over. void Grow(unsigned NewSize); - void operator=(const SmallPtrSetImpl &RHS) LLVM_DELETED_FUNCTION; + void operator=(const SmallPtrSetImplBase &RHS) LLVM_DELETED_FUNCTION; protected: /// swap - Swaps the elements of two sets. /// Note: This method assumes that both sets have the same small size. - void swap(SmallPtrSetImpl &RHS); + void swap(SmallPtrSetImplBase &RHS); - void CopyFrom(const SmallPtrSetImpl &RHS); + void CopyFrom(const SmallPtrSetImplBase &RHS); + void MoveFrom(unsigned SmallSize, SmallPtrSetImplBase &&RHS); }; /// SmallPtrSetIteratorImpl - This is the common base class shared between all @@ -163,8 +166,8 @@ protected: void AdvanceIfNotValid() { assert(Bucket <= End); while (Bucket != End && - (*Bucket == SmallPtrSetImpl::getEmptyMarker() || - *Bucket == SmallPtrSetImpl::getTombstoneMarker())) + (*Bucket == SmallPtrSetImplBase::getEmptyMarker() || + *Bucket == SmallPtrSetImplBase::getTombstoneMarker())) ++Bucket; } }; @@ -228,26 +231,25 @@ struct RoundUpToPowerOfTwo { }; -/// SmallPtrSet - This class implements a set which is optimized for holding -/// SmallSize or less elements. This internally rounds up SmallSize to the next -/// power of two if it is not already a power of two. See the comments above -/// SmallPtrSetImpl for details of the algorithm. -template<class PtrType, unsigned SmallSize> -class SmallPtrSet : public SmallPtrSetImpl { - // Make sure that SmallSize is a power of two, round up if not. - enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val }; - /// SmallStorage - Fixed size storage used in 'small mode'. - const void *SmallStorage[SmallSizePowTwo]; +/// \brief A templated base class for \c SmallPtrSet which provides the +/// typesafe interface that is common across all small sizes. +/// +/// This is particularly useful for passing around between interface boundaries +/// to avoid encoding a particular small size in the interface boundary. +template <typename PtrType> +class SmallPtrSetImpl : public SmallPtrSetImplBase { typedef PointerLikeTypeTraits<PtrType> PtrTraits; -public: - SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {} - SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(SmallStorage, that) {} - - template<typename It> - SmallPtrSet(It I, It E) : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) { - insert(I, E); - } +protected: + // Constructors that forward to the base. + SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl &that) + : SmallPtrSetImplBase(SmallStorage, that) {} + SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize, + SmallPtrSetImpl &&that) + : SmallPtrSetImplBase(SmallStorage, SmallSize, std::move(that)) {} + explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize) + : SmallPtrSetImplBase(SmallStorage, SmallSize) {} +public: /// insert - This returns true if the pointer was new to the set, false if it /// was already in the set. bool insert(PtrType Ptr) { @@ -260,9 +262,9 @@ public: return erase_imp(PtrTraits::getAsVoidPointer(Ptr)); } - /// count - Return true if the specified pointer is in the set. - bool count(PtrType Ptr) const { - return count_imp(PtrTraits::getAsVoidPointer(Ptr)); + /// count - Return 1 if the specified pointer is in the set, 0 otherwise. + unsigned count(PtrType Ptr) const { + return count_imp(PtrTraits::getAsVoidPointer(Ptr)) ? 1 : 0; } template <typename IterT> @@ -279,18 +281,48 @@ public: inline iterator end() const { return iterator(CurArray+CurArraySize, CurArray+CurArraySize); } +}; - // Allow assignment from any smallptrset with the same element type even if it - // doesn't have the same smallsize. - const SmallPtrSet<PtrType, SmallSize>& +/// SmallPtrSet - This class implements a set which is optimized for holding +/// SmallSize or less elements. This internally rounds up SmallSize to the next +/// power of two if it is not already a power of two. See the comments above +/// SmallPtrSetImplBase for details of the algorithm. +template<class PtrType, unsigned SmallSize> +class SmallPtrSet : public SmallPtrSetImpl<PtrType> { + typedef SmallPtrSetImpl<PtrType> BaseT; + + // Make sure that SmallSize is a power of two, round up if not. + enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val }; + /// SmallStorage - Fixed size storage used in 'small mode'. + const void *SmallStorage[SmallSizePowTwo]; +public: + SmallPtrSet() : BaseT(SmallStorage, SmallSizePowTwo) {} + SmallPtrSet(const SmallPtrSet &that) : BaseT(SmallStorage, that) {} + SmallPtrSet(SmallPtrSet &&that) + : BaseT(SmallStorage, SmallSizePowTwo, std::move(that)) {} + + template<typename It> + SmallPtrSet(It I, It E) : BaseT(SmallStorage, SmallSizePowTwo) { + this->insert(I, E); + } + + SmallPtrSet<PtrType, SmallSize> & operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) { - CopyFrom(RHS); + if (&RHS != this) + this->CopyFrom(RHS); + return *this; + } + + SmallPtrSet<PtrType, SmallSize>& + operator=(SmallPtrSet<PtrType, SmallSize> &&RHS) { + if (&RHS != this) + this->MoveFrom(SmallSizePowTwo, std::move(RHS)); return *this; } /// swap - Swaps the elements of two sets. void swap(SmallPtrSet<PtrType, SmallSize> &RHS) { - SmallPtrSetImpl::swap(RHS); + SmallPtrSetImplBase::swap(RHS); } }; diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h index 5dfe924..6f36234 100644 --- a/include/llvm/ADT/SmallSet.h +++ b/include/llvm/ADT/SmallSet.h @@ -39,16 +39,19 @@ class SmallSet { public: SmallSet() {} - bool empty() const { return Vector.empty() && Set.empty(); } + bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { + return Vector.empty() && Set.empty(); + } + unsigned size() const { return isSmall() ? Vector.size() : Set.size(); } - /// count - Return true if the element is in the set. - bool count(const T &V) const { + /// count - Return 1 if the element is in the set, 0 otherwise. + unsigned count(const T &V) const { if (isSmall()) { // Since the collection is small, just do a linear search. - return vfind(V) != Vector.end(); + return vfind(V) == Vector.end() ? 0 : 1; } else { return Set.count(V); } diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h index 2cfb5b9..e569f54 100644 --- a/include/llvm/ADT/SmallString.h +++ b/include/llvm/ADT/SmallString.h @@ -34,9 +34,6 @@ public: template<typename ItTy> SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {} - /// Copy ctor. - SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {} - // Note that in order to add new overloads for append & assign, we have to // duplicate the inherited versions so as not to inadvertently hide them. diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 505aa8d..0a4140e 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -14,6 +14,7 @@ #ifndef LLVM_ADT_SMALLVECTOR_H #define LLVM_ADT_SMALLVECTOR_H +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MathExtras.h" @@ -183,13 +184,9 @@ protected: /// std::move, but not all stdlibs actually provide that. template<typename It1, typename It2> static It2 move(It1 I, It1 E, It2 Dest) { -#if LLVM_HAS_RVALUE_REFERENCES for (; I != E; ++I, ++Dest) *Dest = ::std::move(*I); return Dest; -#else - return ::std::copy(I, E, Dest); -#endif } /// move_backward - Use move-assignment to move the range @@ -198,25 +195,17 @@ protected: /// std::move_backward, but not all stdlibs actually provide that. template<typename It1, typename It2> static It2 move_backward(It1 I, It1 E, It2 Dest) { -#if LLVM_HAS_RVALUE_REFERENCES while (I != E) *--Dest = ::std::move(*--E); return Dest; -#else - return ::std::copy_backward(I, E, Dest); -#endif } /// uninitialized_move - Move the range [I, E) into the uninitialized /// memory starting with "Dest", constructing elements as needed. template<typename It1, typename It2> static void uninitialized_move(It1 I, It1 E, It2 Dest) { -#if LLVM_HAS_RVALUE_REFERENCES for (; I != E; ++I, ++Dest) ::new ((void*) &*Dest) T(::std::move(*I)); -#else - ::std::uninitialized_copy(I, E, Dest); -#endif } /// uninitialized_copy - Copy the range [I, E) onto the uninitialized @@ -244,7 +233,6 @@ public: goto Retry; } -#if LLVM_HAS_RVALUE_REFERENCES void push_back(T &&Elt) { if (this->EndX < this->CapacityX) { Retry: @@ -255,8 +243,7 @@ public: this->grow(); goto Retry; } -#endif - + void pop_back() { this->setEnd(this->end()-1); this->end()->~T(); @@ -428,11 +415,7 @@ public: } T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() { -#if LLVM_HAS_RVALUE_REFERENCES T Result = ::std::move(this->back()); -#else - T Result = this->back(); -#endif this->pop_back(); return Result; } @@ -501,7 +484,6 @@ public: return(N); } -#if LLVM_HAS_RVALUE_REFERENCES iterator insert(iterator I, T &&Elt) { if (I == this->end()) { // Important special case for empty vector. this->push_back(::std::move(Elt)); @@ -532,7 +514,6 @@ public: I = this->begin()+EltNo; goto Retry; } -#endif iterator insert(iterator I, const T &Elt) { if (I == this->end()) { // Important special case for empty vector. @@ -673,9 +654,7 @@ public: SmallVectorImpl &operator=(const SmallVectorImpl &RHS); -#if LLVM_HAS_RVALUE_REFERENCES SmallVectorImpl &operator=(SmallVectorImpl &&RHS); -#endif bool operator==(const SmallVectorImpl &RHS) const { if (this->size() != RHS.size()) return false; @@ -793,7 +772,6 @@ SmallVectorImpl<T> &SmallVectorImpl<T>:: return *this; } -#if LLVM_HAS_RVALUE_REFERENCES template <typename T> SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) { // Avoid self-assignment. @@ -855,7 +833,6 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) { RHS.clear(); return *this; } -#endif /// Storage for the SmallVector elements which aren't contained in /// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1' @@ -894,6 +871,12 @@ public: this->append(S, E); } + template <typename RangeTy> + explicit SmallVector(const llvm::iterator_range<RangeTy> R) + : SmallVectorImpl<T>(N) { + this->append(R.begin(), R.end()); + } + SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) { if (!RHS.empty()) SmallVectorImpl<T>::operator=(RHS); @@ -904,7 +887,6 @@ public: return *this; } -#if LLVM_HAS_RVALUE_REFERENCES SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) { if (!RHS.empty()) SmallVectorImpl<T>::operator=(::std::move(RHS)); @@ -914,8 +896,6 @@ public: SmallVectorImpl<T>::operator=(::std::move(RHS)); return *this; } -#endif - }; template<typename T, unsigned N> diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h index 7a10f85..706f248 100644 --- a/include/llvm/ADT/SparseBitVector.h +++ b/include/llvm/ADT/SparseBitVector.h @@ -382,7 +382,7 @@ class SparseBitVector { AtEnd = true; return; } - // Set up for next non zero word in bitmap. + // Set up for next non-zero word in bitmap. BitNumber = Iter->index() * ElementSize; NextSetBitNumber = Iter->find_first(); BitNumber += NextSetBitNumber; diff --git a/include/llvm/ADT/SparseMultiSet.h b/include/llvm/ADT/SparseMultiSet.h index 7f2a6f7..797a898 100644 --- a/include/llvm/ADT/SparseMultiSet.h +++ b/include/llvm/ADT/SparseMultiSet.h @@ -76,6 +76,10 @@ template<typename ValueT, typename KeyFunctorT = llvm::identity<unsigned>, typename SparseT = uint8_t> class SparseMultiSet { + static_assert(std::numeric_limits<SparseT>::is_integer && + !std::numeric_limits<SparseT>::is_signed, + "SparseT must be an unsigned integer type"); + /// The actual data that's stored, as a doubly-linked list implemented via /// indices into the DenseVector. The doubly linked list is implemented /// circular in Prev indices, and INVALID-terminated in Next indices. This @@ -245,16 +249,6 @@ public: typedef typename super::pointer pointer; typedef typename super::reference reference; - iterator_base(const iterator_base &RHS) - : SMS(RHS.SMS), Idx(RHS.Idx), SparseIdx(RHS.SparseIdx) { } - - const iterator_base &operator=(const iterator_base &RHS) { - SMS = RHS.SMS; - Idx = RHS.Idx; - SparseIdx = RHS.SparseIdx; - return *this; - } - reference operator*() const { assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx && "Dereferencing iterator of invalid key or index"); @@ -354,9 +348,6 @@ public: /// iterator findIndex(unsigned Idx) { assert(Idx < Universe && "Key out of range"); - assert(std::numeric_limits<SparseT>::is_integer && - !std::numeric_limits<SparseT>::is_signed && - "SparseT must be an unsigned integer type"); const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u; for (unsigned i = Sparse[Idx], e = Dense.size(); i < e; i += Stride) { const unsigned FoundIdx = sparseIndex(Dense[i]); diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h index 267a340..b46ccc9 100644 --- a/include/llvm/ADT/SparseSet.h +++ b/include/llvm/ADT/SparseSet.h @@ -118,6 +118,10 @@ template<typename ValueT, typename KeyFunctorT = llvm::identity<unsigned>, typename SparseT = uint8_t> class SparseSet { + static_assert(std::numeric_limits<SparseT>::is_integer && + !std::numeric_limits<SparseT>::is_signed, + "SparseT must be an unsigned integer type"); + typedef typename KeyFunctorT::argument_type KeyT; typedef SmallVector<ValueT, 8> DenseT; DenseT Dense; @@ -198,9 +202,6 @@ public: /// iterator findIndex(unsigned Idx) { assert(Idx < Universe && "Key out of range"); - assert(std::numeric_limits<SparseT>::is_integer && - !std::numeric_limits<SparseT>::is_signed && - "SparseT must be an unsigned integer type"); const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u; for (unsigned i = Sparse[Idx], e = size(); i < e; i += Stride) { const unsigned FoundIdx = ValIndexOf(Dense[i]); @@ -227,10 +228,11 @@ public: return const_cast<SparseSet*>(this)->findIndex(KeyIndexOf(Key)); } - /// count - Returns true if this set contains an element identified by Key. + /// count - Returns 1 if this set contains an element identified by Key, + /// 0 otherwise. /// - bool count(const KeyT &Key) const { - return find(Key) != end(); + unsigned count(const KeyT &Key) const { + return find(Key) == end() ? 0 : 1; } /// insert - Attempts to insert a new element. diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 56dbb5b..a0b3fe7 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -14,9 +14,9 @@ #ifndef LLVM_ADT_STRINGEXTRAS_H #define LLVM_ADT_STRINGEXTRAS_H -#include <iterator> #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" +#include <iterator> namespace llvm { template<typename T> class SmallVectorImpl; @@ -28,6 +28,11 @@ static inline char hexdigit(unsigned X, bool LowerCase = false) { return X < 10 ? '0' + X : HexChar + X - 10; } +/// Construct a string ref from a boolean. +static inline StringRef toStringRef(bool B) { + return StringRef(B ? "true" : "false"); +} + /// Interpret the given character \p C as a hexadecimal digit and return its /// value. /// diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index 0838ebe..4e74cf6 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -26,19 +26,6 @@ namespace llvm { template<typename ValueTy> class StringMapEntry; -/// StringMapEntryInitializer - This datatype can be partially specialized for -/// various datatypes in a stringmap to allow them to be initialized when an -/// entry is default constructed for the map. -template<typename ValueTy> -class StringMapEntryInitializer { -public: - template <typename InitTy> - static void Initialize(StringMapEntry<ValueTy> &T, InitTy InitVal) { - T.second = InitVal; - } -}; - - /// StringMapEntryBase - Shared base class of StringMapEntry instances. class StringMapEntryBase { unsigned StrLen; @@ -149,10 +136,8 @@ public: InitType InitVal) { unsigned KeyLength = static_cast<unsigned>(KeyEnd-KeyStart); - // Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill - // in. Allocate a new item with space for the string at the end and a null + // Allocate a new item with space for the string at the end and a null // terminator. - unsigned AllocSize = static_cast<unsigned>(sizeof(StringMapEntry))+ KeyLength+1; unsigned Alignment = alignOf<StringMapEntry>(); @@ -161,15 +146,12 @@ public: static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment)); // Default construct the value. - new (NewItem) StringMapEntry(KeyLength); + new (NewItem) StringMapEntry(KeyLength, InitVal); // Copy the string information. char *StrBuffer = const_cast<char*>(NewItem->getKeyData()); memcpy(StrBuffer, KeyStart, KeyLength); StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients. - - // Initialize the value if the client wants to. - StringMapEntryInitializer<ValueTy>::Initialize(*NewItem, InitVal); return NewItem; } @@ -313,6 +295,7 @@ public: return GetOrCreateValue(Key).getValue(); } + /// count - Return 1 if the element is in the map, 0 otherwise. size_type count(StringRef Key) const { return find(Key) == end() ? 0 : 1; } @@ -404,7 +387,17 @@ public: } ~StringMap() { - clear(); + // Delete all the elements in the map, but don't reset the elements + // to default values. This is a copy of clear(), but avoids unnecessary + // work not required in the destructor. + if (!empty()) { + for (unsigned I = 0, E = NumBuckets; I != E; ++I) { + StringMapEntryBase *Bucket = TheTable[I]; + if (Bucket && Bucket != getTombstoneVal()) { + static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator); + } + } + } free(TheTable); } }; diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index ec0c284..0514d7b 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -10,7 +10,7 @@ #ifndef LLVM_ADT_STRINGREF_H #define LLVM_ADT_STRINGREF_H -#include "llvm/Support/type_traits.h" +#include "llvm/Support/Allocator.h" #include <algorithm> #include <cassert> #include <cstring> @@ -124,6 +124,13 @@ namespace llvm { return Data[Length-1]; } + // copy - Allocate copy in BumpPtrAllocator and return StringRef to it. + StringRef copy(BumpPtrAllocator &Allocator) { + char *S = Allocator.Allocate<char>(Length); + std::copy(begin(), end(), S); + return StringRef(S, Length); + } + /// equals - Check for string equality, this is more efficient than /// compare() when the relative ordering of inequal strings isn't needed. bool equals(StringRef RHS) const { @@ -333,7 +340,7 @@ namespace llvm { /// this returns true to signify the error. The string is considered /// erroneous if empty or if it overflows T. template <typename T> - typename enable_if_c<std::numeric_limits<T>::is_signed, bool>::type + typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type getAsInteger(unsigned Radix, T &Result) const { long long LLVal; if (getAsSignedInteger(*this, Radix, LLVal) || @@ -344,7 +351,7 @@ namespace llvm { } template <typename T> - typename enable_if_c<!std::numeric_limits<T>::is_signed, bool>::type + typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type getAsInteger(unsigned Radix, T &Result) const { unsigned long long ULLVal; if (getAsUnsignedInteger(*this, Radix, ULLVal) || @@ -553,11 +560,6 @@ namespace llvm { // StringRefs can be treated like a POD type. template <typename T> struct isPodLike; template <> struct isPodLike<StringRef> { static const bool value = true; }; - - /// Construct a string ref from a boolean. - inline StringRef toStringRef(bool B) { - return StringRef(B ? "true" : "false"); - } } #endif diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h index cc0e7b6..1df8d66 100644 --- a/include/llvm/ADT/TinyPtrVector.h +++ b/include/llvm/ADT/TinyPtrVector.h @@ -12,9 +12,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Compiler.h" namespace llvm { @@ -70,7 +68,6 @@ public: return *this; } -#if LLVM_HAS_RVALUE_REFERENCES TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) { RHS.Val = (EltTy)0; } @@ -98,7 +95,6 @@ public: RHS.Val = (EltTy)0; return *this; } -#endif // implicit conversion operator to ArrayRef. operator ArrayRef<EltTy>() const { @@ -250,7 +246,7 @@ public: assert(I <= this->end() && "Inserting past the end of the vector."); if (I == end()) { push_back(Elt); - return llvm::prior(end()); + return std::prev(end()); } assert(!Val.isNull() && "Null value with non-end insert iterator."); if (EltTy V = Val.template dyn_cast<EltTy>()) { @@ -273,7 +269,7 @@ public: // If we have a single value, convert to a vector. ptrdiff_t Offset = I - begin(); if (Val.isNull()) { - if (llvm::next(From) == To) { + if (std::next(From) == To) { Val = *From; return begin(); } diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 84e0b29..185003d 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -46,32 +46,36 @@ public: enum ArchType { UnknownArch, - arm, // ARM: arm, armv.*, xscale - aarch64, // AArch64: aarch64 - hexagon, // Hexagon: hexagon - mips, // MIPS: mips, mipsallegrex - mipsel, // MIPSEL: mipsel, mipsallegrexel - mips64, // MIPS64: mips64 - mips64el,// MIPS64EL: mips64el - msp430, // MSP430: msp430 - ppc, // PPC: powerpc - ppc64, // PPC64: powerpc64, ppu - ppc64le, // PPC64LE: powerpc64le - r600, // R600: AMD GPUs HD2XXX - HD6XXX - sparc, // Sparc: sparc - sparcv9, // Sparcv9: Sparcv9 - systemz, // SystemZ: s390x - tce, // TCE (http://tce.cs.tut.fi/): tce - thumb, // Thumb: thumb, thumbv.* - x86, // X86: i[3-9]86 - x86_64, // X86-64: amd64, x86_64 - xcore, // XCore: xcore - nvptx, // NVPTX: 32-bit - nvptx64, // NVPTX: 64-bit - le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten) - amdil, // amdil: amd IL - spir, // SPIR: standard portable IR for OpenCL 32-bit version - spir64 // SPIR: standard portable IR for OpenCL 64-bit version + arm, // ARM (little endian): arm, armv.*, xscale + armeb, // ARM (big endian): armeb + arm64, // ARM: arm64 + aarch64, // AArch64 (little endian): aarch64 + aarch64_be, // AArch64 (big endian): aarch64_be + hexagon, // Hexagon: hexagon + mips, // MIPS: mips, mipsallegrex + mipsel, // MIPSEL: mipsel, mipsallegrexel + mips64, // MIPS64: mips64 + mips64el, // MIPS64EL: mips64el + msp430, // MSP430: msp430 + ppc, // PPC: powerpc + ppc64, // PPC64: powerpc64, ppu + ppc64le, // PPC64LE: powerpc64le + r600, // R600: AMD GPUs HD2XXX - HD6XXX + sparc, // Sparc: sparc + sparcv9, // Sparcv9: Sparcv9 + systemz, // SystemZ: s390x + tce, // TCE (http://tce.cs.tut.fi/): tce + thumb, // Thumb (little endian): thumb, thumbv.* + thumbeb, // Thumb (big endian): thumbeb + x86, // X86: i[3-9]86 + x86_64, // X86-64: amd64, x86_64 + xcore, // XCore: xcore + nvptx, // NVPTX: 32-bit + nvptx64, // NVPTX: 64-bit + le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten) + amdil, // amdil: amd IL + spir, // SPIR: standard portable IR for OpenCL 32-bit version + spir64 // SPIR: standard portable IR for OpenCL 64-bit version }; enum VendorType { UnknownVendor, @@ -120,10 +124,21 @@ public: GNUEABI, GNUEABIHF, GNUX32, + CODE16, EABI, - MachO, + EABIHF, Android, - ELF + + MSVC, + Itanium, + Cygnus, + }; + enum ObjectFormatType { + UnknownObjectFormat, + + COFF, + ELF, + MachO, }; private: @@ -141,13 +156,16 @@ private: /// The parsed Environment type. EnvironmentType Environment; + /// The object format type. + ObjectFormatType ObjectFormat; + public: /// @name Constructors /// @{ /// \brief Default constructor is the same as an empty string and leaves all /// triple fields unknown. - Triple() : Data(), Arch(), Vendor(), OS(), Environment() {} + Triple() : Data(), Arch(), Vendor(), OS(), Environment(), ObjectFormat() {} explicit Triple(const Twine &Str); Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr); @@ -186,6 +204,9 @@ public: /// getEnvironment - Get the parsed environment type of this triple. EnvironmentType getEnvironment() const { return Environment; } + /// getFormat - Get the object format for this triple. + ObjectFormatType getObjectFormat() const { return ObjectFormat; } + /// getOSVersion - Parse the version number from the OS name component of the /// triple, if present. /// @@ -314,9 +335,29 @@ public: return isMacOSX() || isiOS(); } + bool isWindowsMSVCEnvironment() const { + return getOS() == Triple::Win32 && + (getEnvironment() == Triple::UnknownEnvironment || + getEnvironment() == Triple::MSVC); + } + + bool isKnownWindowsMSVCEnvironment() const { + return getOS() == Triple::Win32 && getEnvironment() == Triple::MSVC; + } + + bool isWindowsCygwinEnvironment() const { + return getOS() == Triple::Cygwin || + (getOS() == Triple::Win32 && getEnvironment() == Triple::Cygnus); + } + + bool isWindowsGNUEnvironment() const { + return getOS() == Triple::MinGW32 || + (getOS() == Triple::Win32 && getEnvironment() == Triple::GNU); + } + /// \brief Tests for either Cygwin or MinGW OS bool isOSCygMing() const { - return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32; + return isWindowsCygwinEnvironment() || isWindowsGNUEnvironment(); } /// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment. @@ -341,18 +382,17 @@ public: /// \brief Tests whether the OS uses the ELF binary format. bool isOSBinFormatELF() const { - return !isOSDarwin() && !isOSWindows(); + return getObjectFormat() == Triple::ELF; } /// \brief Tests whether the OS uses the COFF binary format. bool isOSBinFormatCOFF() const { - return isOSWindows(); + return getObjectFormat() == Triple::COFF; } /// \brief Tests whether the environment is MachO. - // FIXME: Should this be an OSBinFormat predicate? - bool isEnvironmentMachO() const { - return getEnvironment() == Triple::MachO || isOSDarwin(); + bool isOSBinFormatMachO() const { + return getObjectFormat() == Triple::MachO; } /// @} @@ -375,6 +415,9 @@ public: /// to a known type. void setEnvironment(EnvironmentType Kind); + /// setObjectFormat - Set the object file format + void setObjectFormat(ObjectFormatType Kind); + /// setTriple - Set all components to the new triple \p Str. void setTriple(const Twine &Str); diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/ADT/ValueMap.h deleted file mode 100644 index b4fed7a..0000000 --- a/include/llvm/ADT/ValueMap.h +++ /dev/null @@ -1,377 +0,0 @@ -//===- llvm/ADT/ValueMap.h - Safe map from Values to data -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the ValueMap class. ValueMap maps Value* or any subclass -// to an arbitrary other type. It provides the DenseMap interface but updates -// itself to remain safe when keys are RAUWed or deleted. By default, when a -// key is RAUWed from V1 to V2, the old mapping V1->target is removed, and a new -// mapping V2->target is added. If V2 already existed, its old target is -// overwritten. When a key is deleted, its mapping is removed. -// -// You can override a ValueMap's Config parameter to control exactly what -// happens on RAUW and destruction and to get called back on each event. It's -// legal to call back into the ValueMap from a Config's callbacks. Config -// parameters should inherit from ValueMapConfig<KeyT> to get default -// implementations of all the methods ValueMap uses. See ValueMapConfig for -// documentation of the functions you can override. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_VALUEMAP_H -#define LLVM_ADT_VALUEMAP_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/Support/Mutex.h" -#include "llvm/Support/ValueHandle.h" -#include "llvm/Support/type_traits.h" -#include <iterator> - -namespace llvm { - -template<typename KeyT, typename ValueT, typename Config> -class ValueMapCallbackVH; - -template<typename DenseMapT, typename KeyT> -class ValueMapIterator; -template<typename DenseMapT, typename KeyT> -class ValueMapConstIterator; - -/// This class defines the default behavior for configurable aspects of -/// ValueMap<>. User Configs should inherit from this class to be as compatible -/// as possible with future versions of ValueMap. -template<typename KeyT> -struct ValueMapConfig { - /// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's - /// false, the ValueMap will leave the original mapping in place. - enum { FollowRAUW = true }; - - // All methods will be called with a first argument of type ExtraData. The - // default implementations in this class take a templated first argument so - // that users' subclasses can use any type they want without having to - // override all the defaults. - struct ExtraData {}; - - template<typename ExtraDataT> - static void onRAUW(const ExtraDataT & /*Data*/, KeyT /*Old*/, KeyT /*New*/) {} - template<typename ExtraDataT> - static void onDelete(const ExtraDataT &/*Data*/, KeyT /*Old*/) {} - - /// Returns a mutex that should be acquired around any changes to the map. - /// This is only acquired from the CallbackVH (and held around calls to onRAUW - /// and onDelete) and not inside other ValueMap methods. NULL means that no - /// mutex is necessary. - template<typename ExtraDataT> - static sys::Mutex *getMutex(const ExtraDataT &/*Data*/) { return NULL; } -}; - -/// See the file comment. -template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT> > -class ValueMap { - friend class ValueMapCallbackVH<KeyT, ValueT, Config>; - typedef ValueMapCallbackVH<KeyT, ValueT, Config> ValueMapCVH; - typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH> > MapT; - typedef typename Config::ExtraData ExtraData; - MapT Map; - ExtraData Data; - ValueMap(const ValueMap&) LLVM_DELETED_FUNCTION; - ValueMap& operator=(const ValueMap&) LLVM_DELETED_FUNCTION; -public: - typedef KeyT key_type; - typedef ValueT mapped_type; - typedef std::pair<KeyT, ValueT> value_type; - - explicit ValueMap(unsigned NumInitBuckets = 64) - : Map(NumInitBuckets), Data() {} - explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64) - : Map(NumInitBuckets), Data(Data) {} - - ~ValueMap() {} - - typedef ValueMapIterator<MapT, KeyT> iterator; - typedef ValueMapConstIterator<MapT, KeyT> const_iterator; - inline iterator begin() { return iterator(Map.begin()); } - inline iterator end() { return iterator(Map.end()); } - inline const_iterator begin() const { return const_iterator(Map.begin()); } - inline const_iterator end() const { return const_iterator(Map.end()); } - - bool empty() const { return Map.empty(); } - unsigned size() const { return Map.size(); } - - /// Grow the map so that it has at least Size buckets. Does not shrink - void resize(size_t Size) { Map.resize(Size); } - - void clear() { Map.clear(); } - - /// count - Return true if the specified key is in the map. - bool count(const KeyT &Val) const { - return Map.find_as(Val) != Map.end(); - } - - iterator find(const KeyT &Val) { - return iterator(Map.find_as(Val)); - } - const_iterator find(const KeyT &Val) const { - return const_iterator(Map.find_as(Val)); - } - - /// lookup - Return the entry for the specified key, or a default - /// constructed value if no such entry exists. - ValueT lookup(const KeyT &Val) const { - typename MapT::const_iterator I = Map.find_as(Val); - return I != Map.end() ? I->second : ValueT(); - } - - // Inserts key,value pair into the map if the key isn't already in the map. - // If the key is already in the map, it returns false and doesn't update the - // value. - std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) { - std::pair<typename MapT::iterator, bool> map_result= - Map.insert(std::make_pair(Wrap(KV.first), KV.second)); - return std::make_pair(iterator(map_result.first), map_result.second); - } - - /// insert - Range insertion of pairs. - template<typename InputIt> - void insert(InputIt I, InputIt E) { - for (; I != E; ++I) - insert(*I); - } - - - bool erase(const KeyT &Val) { - typename MapT::iterator I = Map.find_as(Val); - if (I == Map.end()) - return false; - - Map.erase(I); - return true; - } - void erase(iterator I) { - return Map.erase(I.base()); - } - - value_type& FindAndConstruct(const KeyT &Key) { - return Map.FindAndConstruct(Wrap(Key)); - } - - ValueT &operator[](const KeyT &Key) { - return Map[Wrap(Key)]; - } - - /// isPointerIntoBucketsArray - Return true if the specified pointer points - /// somewhere into the ValueMap's array of buckets (i.e. either to a key or - /// value in the ValueMap). - bool isPointerIntoBucketsArray(const void *Ptr) const { - return Map.isPointerIntoBucketsArray(Ptr); - } - - /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets - /// array. In conjunction with the previous method, this can be used to - /// determine whether an insertion caused the ValueMap to reallocate. - const void *getPointerIntoBucketsArray() const { - return Map.getPointerIntoBucketsArray(); - } - -private: - // Takes a key being looked up in the map and wraps it into a - // ValueMapCallbackVH, the actual key type of the map. We use a helper - // function because ValueMapCVH is constructed with a second parameter. - ValueMapCVH Wrap(KeyT key) const { - // The only way the resulting CallbackVH could try to modify *this (making - // the const_cast incorrect) is if it gets inserted into the map. But then - // this function must have been called from a non-const method, making the - // const_cast ok. - return ValueMapCVH(key, const_cast<ValueMap*>(this)); - } -}; - -// This CallbackVH updates its ValueMap when the contained Value changes, -// according to the user's preferences expressed through the Config object. -template<typename KeyT, typename ValueT, typename Config> -class ValueMapCallbackVH : public CallbackVH { - friend class ValueMap<KeyT, ValueT, Config>; - friend struct DenseMapInfo<ValueMapCallbackVH>; - typedef ValueMap<KeyT, ValueT, Config> ValueMapT; - typedef typename llvm::remove_pointer<KeyT>::type KeySansPointerT; - - ValueMapT *Map; - - ValueMapCallbackVH(KeyT Key, ValueMapT *Map) - : CallbackVH(const_cast<Value*>(static_cast<const Value*>(Key))), - Map(Map) {} - -public: - KeyT Unwrap() const { return cast_or_null<KeySansPointerT>(getValPtr()); } - - virtual void deleted() { - // Make a copy that won't get changed even when *this is destroyed. - ValueMapCallbackVH Copy(*this); - sys::Mutex *M = Config::getMutex(Copy.Map->Data); - if (M) - M->acquire(); - Config::onDelete(Copy.Map->Data, Copy.Unwrap()); // May destroy *this. - Copy.Map->Map.erase(Copy); // Definitely destroys *this. - if (M) - M->release(); - } - virtual void allUsesReplacedWith(Value *new_key) { - assert(isa<KeySansPointerT>(new_key) && - "Invalid RAUW on key of ValueMap<>"); - // Make a copy that won't get changed even when *this is destroyed. - ValueMapCallbackVH Copy(*this); - sys::Mutex *M = Config::getMutex(Copy.Map->Data); - if (M) - M->acquire(); - - KeyT typed_new_key = cast<KeySansPointerT>(new_key); - // Can destroy *this: - Config::onRAUW(Copy.Map->Data, Copy.Unwrap(), typed_new_key); - if (Config::FollowRAUW) { - typename ValueMapT::MapT::iterator I = Copy.Map->Map.find(Copy); - // I could == Copy.Map->Map.end() if the onRAUW callback already - // removed the old mapping. - if (I != Copy.Map->Map.end()) { - ValueT Target(I->second); - Copy.Map->Map.erase(I); // Definitely destroys *this. - Copy.Map->insert(std::make_pair(typed_new_key, Target)); - } - } - if (M) - M->release(); - } -}; - -template<typename KeyT, typename ValueT, typename Config> -struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config> > { - typedef ValueMapCallbackVH<KeyT, ValueT, Config> VH; - typedef DenseMapInfo<KeyT> PointerInfo; - - static inline VH getEmptyKey() { - return VH(PointerInfo::getEmptyKey(), NULL); - } - static inline VH getTombstoneKey() { - return VH(PointerInfo::getTombstoneKey(), NULL); - } - static unsigned getHashValue(const VH &Val) { - return PointerInfo::getHashValue(Val.Unwrap()); - } - static unsigned getHashValue(const KeyT &Val) { - return PointerInfo::getHashValue(Val); - } - static bool isEqual(const VH &LHS, const VH &RHS) { - return LHS == RHS; - } - static bool isEqual(const KeyT &LHS, const VH &RHS) { - return LHS == RHS.getValPtr(); - } -}; - - -template<typename DenseMapT, typename KeyT> -class ValueMapIterator : - public std::iterator<std::forward_iterator_tag, - std::pair<KeyT, typename DenseMapT::mapped_type>, - ptrdiff_t> { - typedef typename DenseMapT::iterator BaseT; - typedef typename DenseMapT::mapped_type ValueT; - BaseT I; -public: - ValueMapIterator() : I() {} - - ValueMapIterator(BaseT I) : I(I) {} - - BaseT base() const { return I; } - - struct ValueTypeProxy { - const KeyT first; - ValueT& second; - ValueTypeProxy *operator->() { return this; } - operator std::pair<KeyT, ValueT>() const { - return std::make_pair(first, second); - } - }; - - ValueTypeProxy operator*() const { - ValueTypeProxy Result = {I->first.Unwrap(), I->second}; - return Result; - } - - ValueTypeProxy operator->() const { - return operator*(); - } - - bool operator==(const ValueMapIterator &RHS) const { - return I == RHS.I; - } - bool operator!=(const ValueMapIterator &RHS) const { - return I != RHS.I; - } - - inline ValueMapIterator& operator++() { // Preincrement - ++I; - return *this; - } - ValueMapIterator operator++(int) { // Postincrement - ValueMapIterator tmp = *this; ++*this; return tmp; - } -}; - -template<typename DenseMapT, typename KeyT> -class ValueMapConstIterator : - public std::iterator<std::forward_iterator_tag, - std::pair<KeyT, typename DenseMapT::mapped_type>, - ptrdiff_t> { - typedef typename DenseMapT::const_iterator BaseT; - typedef typename DenseMapT::mapped_type ValueT; - BaseT I; -public: - ValueMapConstIterator() : I() {} - ValueMapConstIterator(BaseT I) : I(I) {} - ValueMapConstIterator(ValueMapIterator<DenseMapT, KeyT> Other) - : I(Other.base()) {} - - BaseT base() const { return I; } - - struct ValueTypeProxy { - const KeyT first; - const ValueT& second; - ValueTypeProxy *operator->() { return this; } - operator std::pair<KeyT, ValueT>() const { - return std::make_pair(first, second); - } - }; - - ValueTypeProxy operator*() const { - ValueTypeProxy Result = {I->first.Unwrap(), I->second}; - return Result; - } - - ValueTypeProxy operator->() const { - return operator*(); - } - - bool operator==(const ValueMapConstIterator &RHS) const { - return I == RHS.I; - } - bool operator!=(const ValueMapConstIterator &RHS) const { - return I != RHS.I; - } - - inline ValueMapConstIterator& operator++() { // Preincrement - ++I; - return *this; - } - ValueMapConstIterator operator++(int) { // Postincrement - ValueMapConstIterator tmp = *this; ++*this; return tmp; - } -}; - -} // end namespace llvm - -#endif diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h new file mode 100644 index 0000000..4f2f321 --- /dev/null +++ b/include/llvm/ADT/iterator_range.h @@ -0,0 +1,45 @@ +//===- iterator_range.h - A range adaptor for iterators ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This provides a very simple, boring adaptor for a begin and end iterator +/// into a range type. This should be used to build range views that work well +/// with range based for loops and range based constructors. +/// +/// Note that code here follows more standards-based coding conventions as it +/// is mirroring proposed interfaces for standardization. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_ITERATOR_RANGE_H +#define LLVM_ADT_ITERATOR_RANGE_H + +#include <utility> + +namespace llvm { + +/// \brief A range adaptor for a pair of iterators. +/// +/// This just wraps two iterators into a range-compatible interface. Nothing +/// fancy at all. +template <typename IteratorT> +class iterator_range { + IteratorT begin_iterator, end_iterator; + +public: + iterator_range() {} + iterator_range(IteratorT begin_iterator, IteratorT end_iterator) + : begin_iterator(std::move(begin_iterator)), + end_iterator(std::move(end_iterator)) {} + + IteratorT begin() const { return begin_iterator; } + IteratorT end() const { return end_iterator; } +}; +} + +#endif diff --git a/include/llvm/ADT/polymorphic_ptr.h b/include/llvm/ADT/polymorphic_ptr.h deleted file mode 100644 index b8d8d71..0000000 --- a/include/llvm/ADT/polymorphic_ptr.h +++ /dev/null @@ -1,117 +0,0 @@ -//===- llvm/ADT/polymorphic_ptr.h - Smart copyable owned ptr ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// \file -/// This file provides a polymorphic_ptr class template. See the class comments -/// for details about this API, its intended use cases, etc. -/// -/// The primary motivation here is to work around the necessity of copy -/// semantics in C++98. This is typically used where any actual copies are -/// incidental or unnecessary. As a consequence, it is expected to cease to be -/// useful and be removed when we can directly rely on move-only types. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_POLYMORPHIC_PTR_H -#define LLVM_ADT_POLYMORPHIC_PTR_H - -#include "llvm/Support/Compiler.h" - -namespace llvm { - -/// \brief An owning, copyable polymorphic smart pointer. -/// -/// This pointer exists to provide copyable owned smart pointer. Rather than -/// shared ownership semantics, it has unique ownership semantics and deep copy -/// semantics. It is copyable by requiring that the underlying type exposes -/// a method which can produce a (heap allocated) clone. -/// -/// Note that in almost all scenarios use of this could be avoided if we could -/// build move-only containers of a std::unique_ptr, but until then this -/// provides an effective way to place polymorphic objects in a container. -template <typename T> class polymorphic_ptr { - T *ptr; - -public: - polymorphic_ptr(T *ptr = 0) : ptr(ptr) {} - polymorphic_ptr(const polymorphic_ptr &arg) : ptr(arg ? arg->clone() : 0) {} -#if LLVM_HAS_RVALUE_REFERENCES - polymorphic_ptr(polymorphic_ptr &&arg) : ptr(arg.take()) {} -#endif - ~polymorphic_ptr() { delete ptr; } - - polymorphic_ptr &operator=(polymorphic_ptr arg) { - swap(arg); - return *this; - } - polymorphic_ptr &operator=(T *arg) { - if (arg != ptr) { - delete ptr; - ptr = arg; - } - return *this; - } - - T &operator*() const { return *ptr; } - T *operator->() const { return ptr; } - LLVM_EXPLICIT operator bool() const { return ptr != 0; } - bool operator!() const { return ptr == 0; } - - T *get() const { return ptr; } - - T *take() { - T *tmp = ptr; - ptr = 0; - return tmp; - } - - void swap(polymorphic_ptr &arg) { - T *tmp = ptr; - ptr = arg.ptr; - arg.ptr = tmp; - } -}; - -template <typename T> -void swap(polymorphic_ptr<T> &lhs, polymorphic_ptr<T> &rhs) { - lhs.swap(rhs); -} - -template <typename T, typename U> -bool operator==(const polymorphic_ptr<T> &lhs, const polymorphic_ptr<U> &rhs) { - return lhs.get() == rhs.get(); -} - -template <typename T, typename U> -bool operator!=(const polymorphic_ptr<T> &lhs, const polymorphic_ptr<U> &rhs) { - return lhs.get() != rhs.get(); -} - -template <typename T, typename U> -bool operator==(const polymorphic_ptr<T> &lhs, U *rhs) { - return lhs.get() == rhs; -} - -template <typename T, typename U> -bool operator!=(const polymorphic_ptr<T> &lhs, U *rhs) { - return lhs.get() != rhs; -} - -template <typename T, typename U> -bool operator==(T *lhs, const polymorphic_ptr<U> &rhs) { - return lhs == rhs.get(); -} - -template <typename T, typename U> -bool operator!=(T *lhs, const polymorphic_ptr<U> &rhs) { - return lhs != rhs.get(); -} - -} - -#endif |