[llvm] r223588 - Make the DenseMap bucket type configurable and use a smaller bucket for DenseSet.
David Blaikie
dblaikie at gmail.com
Sat Dec 6 11:37:04 PST 2014
On Sat, Dec 6, 2014 at 11:22 AM, Benjamin Kramer <benny.kra at googlemail.com>
wrote:
> Author: d0k
> Date: Sat Dec 6 13:22:44 2014
> New Revision: 223588
>
> URL: http://llvm.org/viewvc/llvm-project?rev=223588&view=rev
> Log:
> Make the DenseMap bucket type configurable and use a smaller bucket for
> DenseSet.
>
Would it be possible/more natural to invert this relationship and implement
DenseMap in terms of DenseSet instead of the other way around?
>
> DenseSet used to be implemented as DenseMap<Key, char>, which usually
> doubled
> the memory footprint of the map. Now we use a compressed set so the second
> element uses no memory at all. This required some surgery on DenseMap as
> all accesses to the bucket now have to go through methods; this should
> have no impact on the behavior of DenseMap though. The new default bucket
> type for DenseMap is a slightly extended std::pair as we expose it through
> DenseMap's iterator and don't want to break any existing users.
>
> Modified:
> llvm/trunk/include/llvm/ADT/DenseMap.h
> llvm/trunk/include/llvm/ADT/DenseSet.h
> llvm/trunk/include/llvm/IR/Module.h
> llvm/trunk/lib/Target/AArch64/AArch64PromoteConstant.cpp
>
> Modified: llvm/trunk/include/llvm/ADT/DenseMap.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=223588&r1=223587&r2=223588&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/DenseMap.h (original)
> +++ llvm/trunk/include/llvm/ADT/DenseMap.h Sat Dec 6 13:22:44 2014
> @@ -31,26 +31,35 @@
>
> namespace llvm {
>
> -template<typename KeyT, typename ValueT,
> - typename KeyInfoT = DenseMapInfo<KeyT>,
> - bool IsConst = false>
> +namespace detail {
> +// We extend a pair to allow users to override the bucket type with their
> own
> +// implementation without requiring two members.
> +template <typename KeyT, typename ValueT>
> +struct DenseMapPair : public std::pair<KeyT, ValueT> {
> + KeyT &getFirst() { return std::pair<KeyT, ValueT>::first; }
> + const KeyT &getFirst() const { return std::pair<KeyT, ValueT>::first; }
> + ValueT &getSecond() { return std::pair<KeyT, ValueT>::second; }
> + const ValueT &getSecond() const { return std::pair<KeyT,
> ValueT>::second; }
> +};
> +}
> +
> +template <
> + typename KeyT, typename ValueT, typename KeyInfoT =
> DenseMapInfo<KeyT>,
> + typename Bucket = detail::DenseMapPair<KeyT, ValueT>, bool IsConst =
> false>
> class DenseMapIterator;
>
> -template<typename DerivedT,
> - typename KeyT, typename ValueT, typename KeyInfoT>
> +template <typename DerivedT, typename KeyT, typename ValueT, typename
> KeyInfoT,
> + typename BucketT>
> class DenseMapBase {
> -protected:
> - typedef std::pair<KeyT, ValueT> BucketT;
> -
> public:
> typedef unsigned size_type;
> typedef KeyT key_type;
> typedef ValueT mapped_type;
> typedef BucketT value_type;
>
> - typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
> - typedef DenseMapIterator<KeyT, ValueT,
> - KeyInfoT, true> const_iterator;
> + typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT> iterator;
> + typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT, true>
> + const_iterator;
> inline iterator begin() {
> // When the map is empty, avoid the overhead of
> AdvancePastEmptyBuckets().
> return empty() ? end() : iterator(getBuckets(), getBucketsEnd());
> @@ -88,12 +97,12 @@ public:
>
> const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
> for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
> - if (!KeyInfoT::isEqual(P->first, EmptyKey)) {
> - if (!KeyInfoT::isEqual(P->first, TombstoneKey)) {
> - P->second.~ValueT();
> + if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) {
> + if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) {
> + P->getSecond().~ValueT();
> decrementNumEntries();
> }
> - P->first = EmptyKey;
> + P->getFirst() = EmptyKey;
> }
> }
> assert(getNumEntries() == 0 && "Node count imbalance!");
> @@ -144,7 +153,7 @@ public:
> ValueT lookup(const KeyT &Val) const {
> const BucketT *TheBucket;
> if (LookupBucketFor(Val, TheBucket))
> - return TheBucket->second;
> + return TheBucket->getSecond();
> return ValueT();
> }
>
> @@ -191,16 +200,16 @@ public:
> if (!LookupBucketFor(Val, TheBucket))
> return false; // not in map.
>
> - TheBucket->second.~ValueT();
> - TheBucket->first = getTombstoneKey();
> + TheBucket->getSecond().~ValueT();
> + TheBucket->getFirst() = getTombstoneKey();
> decrementNumEntries();
> incrementNumTombstones();
> return true;
> }
> void erase(iterator I) {
> BucketT *TheBucket = &*I;
> - TheBucket->second.~ValueT();
> - TheBucket->first = getTombstoneKey();
> + TheBucket->getSecond().~ValueT();
> + TheBucket->getFirst() = getTombstoneKey();
> decrementNumEntries();
> incrementNumTombstones();
> }
> @@ -250,10 +259,10 @@ protected:
>
> const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
> for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
> - if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
> - !KeyInfoT::isEqual(P->first, TombstoneKey))
> - P->second.~ValueT();
> - P->first.~KeyT();
> + if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey) &&
> + !KeyInfoT::isEqual(P->getFirst(), TombstoneKey))
> + P->getSecond().~ValueT();
> + P->getFirst().~KeyT();
> }
>
> #ifndef NDEBUG
> @@ -269,7 +278,7 @@ protected:
> "# initial buckets must be a power of two!");
> const KeyT EmptyKey = getEmptyKey();
> for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B)
> - new (&B->first) KeyT(EmptyKey);
> + new (&B->getFirst()) KeyT(EmptyKey);
> }
>
> void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT
> *OldBucketsEnd) {
> @@ -279,21 +288,21 @@ protected:
> const KeyT EmptyKey = getEmptyKey();
> const KeyT TombstoneKey = getTombstoneKey();
> for (BucketT *B = OldBucketsBegin, *E = OldBucketsEnd; B != E; ++B) {
> - if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
> - !KeyInfoT::isEqual(B->first, TombstoneKey)) {
> + if (!KeyInfoT::isEqual(B->getFirst(), EmptyKey) &&
> + !KeyInfoT::isEqual(B->getFirst(), TombstoneKey)) {
> // Insert the key/value into the new table.
> BucketT *DestBucket;
> - bool FoundVal = LookupBucketFor(B->first, DestBucket);
> + bool FoundVal = LookupBucketFor(B->getFirst(), DestBucket);
> (void)FoundVal; // silence warning.
> assert(!FoundVal && "Key already in new map?");
> - DestBucket->first = std::move(B->first);
> - new (&DestBucket->second) ValueT(std::move(B->second));
> + DestBucket->getFirst() = std::move(B->getFirst());
> + new (&DestBucket->getSecond()) ValueT(std::move(B->getSecond()));
> incrementNumEntries();
>
> // Free the value.
> - B->second.~ValueT();
> + B->getSecond().~ValueT();
> }
> - B->first.~KeyT();
> + B->getFirst().~KeyT();
> }
>
> #ifndef NDEBUG
> @@ -304,7 +313,8 @@ protected:
> }
>
> template <typename OtherBaseT>
> - void copyFrom(const DenseMapBase<OtherBaseT, KeyT, ValueT, KeyInfoT>&
> other) {
> + void copyFrom(
> + const DenseMapBase<OtherBaseT, KeyT, ValueT, KeyInfoT, BucketT>
> &other) {
> assert(&other != this);
> assert(getNumBuckets() == other.getNumBuckets());
>
> @@ -316,10 +326,12 @@ protected:
> getNumBuckets() * sizeof(BucketT));
> else
> for (size_t i = 0; i < getNumBuckets(); ++i) {
> - new (&getBuckets()[i].first) KeyT(other.getBuckets()[i].first);
> - if (!KeyInfoT::isEqual(getBuckets()[i].first, getEmptyKey()) &&
> - !KeyInfoT::isEqual(getBuckets()[i].first, getTombstoneKey()))
> - new (&getBuckets()[i].second)
> ValueT(other.getBuckets()[i].second);
> + new (&getBuckets()[i].getFirst())
> + KeyT(other.getBuckets()[i].getFirst());
> + if (!KeyInfoT::isEqual(getBuckets()[i].getFirst(), getEmptyKey())
> &&
> + !KeyInfoT::isEqual(getBuckets()[i].getFirst(),
> getTombstoneKey()))
> + new (&getBuckets()[i].getSecond())
> + ValueT(other.getBuckets()[i].getSecond());
> }
> }
>
> @@ -396,8 +408,8 @@ private:
> BucketT *TheBucket) {
> TheBucket = InsertIntoBucketImpl(Key, TheBucket);
>
> - TheBucket->first = Key;
> - new (&TheBucket->second) ValueT(Value);
> + TheBucket->getFirst() = Key;
> + new (&TheBucket->getSecond()) ValueT(Value);
> return TheBucket;
> }
>
> @@ -405,16 +417,16 @@ private:
> BucketT *TheBucket) {
> TheBucket = InsertIntoBucketImpl(Key, TheBucket);
>
> - TheBucket->first = Key;
> - new (&TheBucket->second) ValueT(std::move(Value));
> + TheBucket->getFirst() = Key;
> + new (&TheBucket->getSecond()) ValueT(std::move(Value));
> return TheBucket;
> }
>
> BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, BucketT
> *TheBucket) {
> TheBucket = InsertIntoBucketImpl(Key, TheBucket);
>
> - TheBucket->first = std::move(Key);
> - new (&TheBucket->second) ValueT(std::move(Value));
> + TheBucket->getFirst() = std::move(Key);
> + new (&TheBucket->getSecond()) ValueT(std::move(Value));
> return TheBucket;
> }
>
> @@ -446,7 +458,7 @@ private:
>
> // If we are writing over a tombstone, remember this.
> const KeyT EmptyKey = getEmptyKey();
> - if (!KeyInfoT::isEqual(TheBucket->first, EmptyKey))
> + if (!KeyInfoT::isEqual(TheBucket->getFirst(), EmptyKey))
> decrementNumTombstones();
>
> return TheBucket;
> @@ -480,14 +492,14 @@ private:
> while (1) {
> const BucketT *ThisBucket = BucketsPtr + BucketNo;
> // Found Val's bucket? If so, return it.
> - if (KeyInfoT::isEqual(Val, ThisBucket->first)) {
> + if (KeyInfoT::isEqual(Val, ThisBucket->getFirst())) {
> FoundBucket = ThisBucket;
> return true;
> }
>
> // If we found an empty bucket, the key doesn't exist in the set.
> // Insert it and return the default value.
> - if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
> + if (KeyInfoT::isEqual(ThisBucket->getFirst(), EmptyKey)) {
> // If we've already seen a tombstone while probing, fill it in
> instead
> // of the empty bucket we eventually probed to.
> FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
> @@ -496,7 +508,8 @@ private:
>
> // If this is a tombstone, remember it. If Val ends up not in the
> map, we
> // prefer to return it than something that would require more
> probing.
> - if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) &&
> !FoundTombstone)
> + if (KeyInfoT::isEqual(ThisBucket->getFirst(), TombstoneKey) &&
> + !FoundTombstone)
> FoundTombstone = ThisBucket; // Remember the first tombstone
> found.
>
> // Otherwise, it's a hash collision or a tombstone, continue
> quadratic
> @@ -525,16 +538,15 @@ public:
> }
> };
>
> -template<typename KeyT, typename ValueT,
> - typename KeyInfoT = DenseMapInfo<KeyT> >
> -class DenseMap
> - : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT>,
> - KeyT, ValueT, KeyInfoT> {
> +template <typename KeyT, typename ValueT,
> + typename KeyInfoT = DenseMapInfo<KeyT>,
> + typename BucketT = detail::DenseMapPair<KeyT, ValueT>>
> +class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT,
> BucketT>,
> + KeyT, ValueT, KeyInfoT, BucketT> {
> // Lift some types from the dependent base class into this class for
> // simplicity of referring to them.
> - typedef DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT> BaseT;
> - typedef typename BaseT::BucketT BucketT;
> - friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT>;
> + typedef DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT> BaseT;
> + friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
>
> BucketT *Buckets;
> unsigned NumEntries;
> @@ -677,17 +689,17 @@ private:
> }
> };
>
> -template<typename KeyT, typename ValueT,
> - unsigned InlineBuckets = 4,
> - typename KeyInfoT = DenseMapInfo<KeyT> >
> +template <typename KeyT, typename ValueT, unsigned InlineBuckets = 4,
> + typename KeyInfoT = DenseMapInfo<KeyT>,
> + typename BucketT = detail::DenseMapPair<KeyT, ValueT>>
> class SmallDenseMap
> - : public DenseMapBase<SmallDenseMap<KeyT, ValueT, InlineBuckets,
> KeyInfoT>,
> - KeyT, ValueT, KeyInfoT> {
> + : public DenseMapBase<
> + SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT, BucketT>,
> KeyT,
> + ValueT, KeyInfoT, BucketT> {
> // Lift some types from the dependent base class into this class for
> // simplicity of referring to them.
> - typedef DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT> BaseT;
> - typedef typename BaseT::BucketT BucketT;
> - friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT>;
> + typedef DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT>
> BaseT;
> + friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT,
> BucketT>;
>
> unsigned Small : 1;
> unsigned NumEntries : 31;
> @@ -744,23 +756,23 @@ public:
> for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
> BucketT *LHSB = &getInlineBuckets()[i],
> *RHSB = &RHS.getInlineBuckets()[i];
> - bool hasLHSValue = (!KeyInfoT::isEqual(LHSB->first, EmptyKey) &&
> - !KeyInfoT::isEqual(LHSB->first,
> TombstoneKey));
> - bool hasRHSValue = (!KeyInfoT::isEqual(RHSB->first, EmptyKey) &&
> - !KeyInfoT::isEqual(RHSB->first,
> TombstoneKey));
> + bool hasLHSValue = (!KeyInfoT::isEqual(LHSB->getFirst(),
> EmptyKey) &&
> + !KeyInfoT::isEqual(LHSB->getFirst(),
> TombstoneKey));
> + bool hasRHSValue = (!KeyInfoT::isEqual(RHSB->getFirst(),
> EmptyKey) &&
> + !KeyInfoT::isEqual(RHSB->getFirst(),
> TombstoneKey));
> if (hasLHSValue && hasRHSValue) {
> // Swap together if we can...
> std::swap(*LHSB, *RHSB);
> continue;
> }
> // Swap separately and handle any assymetry.
> - std::swap(LHSB->first, RHSB->first);
> + std::swap(LHSB->getFirst(), RHSB->getFirst());
> if (hasLHSValue) {
> - new (&RHSB->second) ValueT(std::move(LHSB->second));
> - LHSB->second.~ValueT();
> + new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond()));
> + LHSB->getSecond().~ValueT();
> } else if (hasRHSValue) {
> - new (&LHSB->second) ValueT(std::move(RHSB->second));
> - RHSB->second.~ValueT();
> + new (&LHSB->getSecond()) ValueT(std::move(RHSB->getSecond()));
> + RHSB->getSecond().~ValueT();
> }
> }
> return;
> @@ -785,12 +797,12 @@ public:
> for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
> BucketT *NewB = &LargeSide.getInlineBuckets()[i],
> *OldB = &SmallSide.getInlineBuckets()[i];
> - 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(std::move(OldB->second));
> - OldB->second.~ValueT();
> + new (&NewB->getFirst()) KeyT(std::move(OldB->getFirst()));
> + OldB->getFirst().~KeyT();
> + if (!KeyInfoT::isEqual(NewB->getFirst(), EmptyKey) &&
> + !KeyInfoT::isEqual(NewB->getFirst(), TombstoneKey)) {
> + new (&NewB->getSecond()) ValueT(std::move(OldB->getSecond()));
> + OldB->getSecond().~ValueT();
> }
> }
>
> @@ -852,16 +864,16 @@ public:
> const KeyT EmptyKey = this->getEmptyKey();
> const KeyT TombstoneKey = this->getTombstoneKey();
> for (BucketT *P = getBuckets(), *E = P + InlineBuckets; P != E;
> ++P) {
> - if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
> - !KeyInfoT::isEqual(P->first, TombstoneKey)) {
> + if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey) &&
> + !KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) {
> assert(size_t(TmpEnd - TmpBegin) < InlineBuckets &&
> "Too many inline buckets!");
> - new (&TmpEnd->first) KeyT(std::move(P->first));
> - new (&TmpEnd->second) ValueT(std::move(P->second));
> + new (&TmpEnd->getFirst()) KeyT(std::move(P->getFirst()));
> + new (&TmpEnd->getSecond()) ValueT(std::move(P->getSecond()));
> ++TmpEnd;
> - P->second.~ValueT();
> + P->getSecond().~ValueT();
> }
> - P->first.~KeyT();
> + P->getFirst().~KeyT();
> }
>
> // Now make this map use the large rep, and move all the entries
> back
> @@ -972,13 +984,12 @@ private:
> }
> };
>
> -template<typename KeyT, typename ValueT,
> - typename KeyInfoT, bool IsConst>
> +template <typename KeyT, typename ValueT, typename KeyInfoT, typename
> Bucket,
> + bool IsConst>
> class DenseMapIterator {
> - typedef std::pair<KeyT, ValueT> Bucket;
> - typedef DenseMapIterator<KeyT, ValueT,
> - KeyInfoT, true> ConstIterator;
> - friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>;
> + typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>
> ConstIterator;
> + friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
> +
> public:
> typedef ptrdiff_t difference_type;
> typedef typename std::conditional<IsConst, const Bucket, Bucket>::type
> @@ -999,9 +1010,9 @@ public:
> // If IsConst is true this is a converting constructor from iterator to
> // const_iterator and the default copy constructor is used.
> // Otherwise this is a copy constructor for iterator.
> - DenseMapIterator(const DenseMapIterator<KeyT, ValueT,
> - KeyInfoT, false>& I)
> - : Ptr(I.Ptr), End(I.End) {}
> + DenseMapIterator(
> + const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false> &I)
> + : Ptr(I.Ptr), End(I.End) {}
>
> reference operator*() const {
> return *Ptr;
> @@ -1031,9 +1042,8 @@ private:
> const KeyT Empty = KeyInfoT::getEmptyKey();
> const KeyT Tombstone = KeyInfoT::getTombstoneKey();
>
> - while (Ptr != End &&
> - (KeyInfoT::isEqual(Ptr->first, Empty) ||
> - KeyInfoT::isEqual(Ptr->first, Tombstone)))
> + while (Ptr != End && (KeyInfoT::isEqual(Ptr->getFirst(), Empty) ||
> + KeyInfoT::isEqual(Ptr->getFirst(), Tombstone)))
> ++Ptr;
> }
> };
>
> Modified: llvm/trunk/include/llvm/ADT/DenseSet.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseSet.h?rev=223588&r1=223587&r2=223588&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/DenseSet.h (original)
> +++ llvm/trunk/include/llvm/ADT/DenseSet.h Sat Dec 6 13:22:44 2014
> @@ -18,13 +18,29 @@
>
> namespace llvm {
>
> +namespace detail {
> +struct DenseSetEmpty {};
> +
> +// Use the empty base class trick so we can create a DenseMap where the
> buckets
> +// contain only a single item.
> +template <typename KeyT> class DenseSetPair : public DenseSetEmpty {
> + KeyT key;
> +
> +public:
> + KeyT &getFirst() { return key; }
> + const KeyT &getFirst() const { return key; }
> + DenseSetEmpty &getSecond() { return *this; }
> + const DenseSetEmpty &getSecond() const { return *this; }
> +};
> +}
> +
> /// DenseSet - This implements a dense probed hash-table based set.
> -///
> -/// FIXME: This is currently implemented directly in terms of DenseMap,
> this
> -/// should be optimized later if there is a need.
> template<typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT> >
> class DenseSet {
> - typedef DenseMap<ValueT, char, ValueInfoT> MapTy;
> + typedef DenseMap<ValueT, detail::DenseSetEmpty, ValueInfoT,
> + detail::DenseSetPair<ValueT>> MapTy;
> + static_assert(sizeof(typename MapTy::value_type) == sizeof(ValueT),
> + "DenseMap buckets unexpectedly large!");
> MapTy TheMap;
> public:
> typedef ValueT key_type;
> @@ -72,8 +88,8 @@ public:
>
> Iterator(const typename MapTy::iterator &i) : I(i) {}
>
> - ValueT& operator*() { return I->first; }
> - ValueT* operator->() { return &I->first; }
> + ValueT &operator*() { return I->getFirst(); }
> + ValueT *operator->() { return &I->getFirst(); }
>
> Iterator& operator++() { ++I; return *this; }
> bool operator==(const Iterator& X) const { return I == X.I; }
> @@ -92,8 +108,8 @@ public:
>
> ConstIterator(const typename MapTy::const_iterator &i) : I(i) {}
>
> - const ValueT& operator*() { return I->first; }
> - const ValueT* operator->() { return &I->first; }
> + const ValueT &operator*() { return I->getFirst(); }
> + const ValueT *operator->() { return &I->getFirst(); }
>
> ConstIterator& operator++() { ++I; return *this; }
> bool operator==(const ConstIterator& X) const { return I == X.I; }
> @@ -129,7 +145,8 @@ public:
> void erase(ConstIterator CI) { return TheMap.erase(CI.I); }
>
> std::pair<iterator, bool> insert(const ValueT &V) {
> - return TheMap.insert(std::make_pair(V, 0));
> + detail::DenseSetEmpty Empty;
> + return TheMap.insert(std::make_pair(V, Empty));
> }
>
> // Range insertion of values.
>
> Modified: llvm/trunk/include/llvm/IR/Module.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=223588&r1=223587&r2=223588&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/Module.h (original)
> +++ llvm/trunk/include/llvm/IR/Module.h Sat Dec 6 13:22:44 2014
> @@ -33,8 +33,6 @@ class GVMaterializer;
> class LLVMContext;
> class RandomNumberGenerator;
> class StructType;
> -template<typename T> struct DenseMapInfo;
> -template<typename KeyT, typename ValueT, typename KeyInfoT> class
> DenseMap;
>
> template<> struct ilist_traits<Function>
> : public SymbolTableListTraits<Function, Module> {
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64PromoteConstant.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64PromoteConstant.cpp?rev=223588&r1=223587&r2=223588&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64PromoteConstant.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64PromoteConstant.cpp Sat Dec 6
> 13:22:44 2014
> @@ -193,7 +193,7 @@ private:
> // Inserting into the DenseMap may invalidate existing iterator.
> // Keep a copy of the key to find the iterator to erase.
> Instruction *OldInstr = IPI->first;
> - InsertPts.insert(InsertionPoints::value_type(NewPt, IPI->second));
> + InsertPts[NewPt] = std::move(IPI->second);
> // Erase IPI.
> IPI = InsertPts.find(OldInstr);
> InsertPts.erase(IPI);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141206/caeee75b/attachment.html>
More information about the llvm-commits
mailing list