[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