21#ifndef LLVM_ADT_SPARSEMULTISET_H 
   22#define LLVM_ADT_SPARSEMULTISET_H 
   84template <
typename ValueT, 
typename KeyT = unsigned,
 
   85          typename KeyFunctorT = 
identity, 
typename SparseT = uint8_t>
 
   87  static_assert(std::is_unsigned_v<SparseT>,
 
   88                "SparseT must be an unsigned integer type");
 
   97    static constexpr unsigned INVALID = ~0U;
 
  103    SMSNode(ValueT 
D, 
unsigned P, 
unsigned N) : 
Data(
D), Prev(
P), 
Next(
N) {}
 
  109    bool isTombstone()
 const { 
return Prev == 
INVALID; }
 
  118  SparseT *Sparse = 
nullptr;
 
  119  unsigned Universe = 0;
 
  120  KeyFunctorT KeyIndexOf;
 
  126  unsigned FreelistIdx = SMSNode::INVALID;
 
  127  unsigned NumFree = 0;
 
  129  unsigned sparseIndex(
const ValueT &Val)
 const {
 
  130    assert(ValIndexOf(Val) < Universe &&
 
  131           "Invalid key in set. Did object mutate?");
 
  132    return ValIndexOf(Val);
 
  134  unsigned sparseIndex(
const SMSNode &
N)
 const { 
return sparseIndex(
N.Data); }
 
  139  bool isHead(
const SMSNode &
D)
 const {
 
  140    assert(
D.isValid() && 
"Invalid node for head");
 
  141    return Dense[
D.Prev].isTail();
 
  146  bool isSingleton(
const SMSNode &
N)
 const {
 
  147    assert(
N.isValid() && 
"Invalid node for singleton");
 
  149    return &Dense[
N.Prev] == &
N;
 
  154  unsigned addValue(
const ValueT &V, 
unsigned Prev, 
unsigned Next) {
 
  156      Dense.push_back(SMSNode(V, Prev, 
Next));
 
  157      return Dense.size() - 1;
 
  161    unsigned Idx = FreelistIdx;
 
  162    unsigned NextFree = Dense[Idx].Next;
 
  163    assert(Dense[Idx].isTombstone() && 
"Non-tombstone free?");
 
  165    Dense[Idx] = SMSNode(V, Prev, 
Next);
 
  166    FreelistIdx = NextFree;
 
  172  void makeTombstone(
unsigned Idx) {
 
  173    Dense[Idx].Prev = SMSNode::INVALID;
 
  174    Dense[Idx].Next = FreelistIdx;
 
  200    assert(
empty() && 
"Can only resize universe on an empty map");
 
  202    if (U >= Universe / 4 && U <= Universe)
 
  208    Sparse = 
static_cast<SparseT *
>(
safe_calloc(U, 
sizeof(SparseT)));
 
 
  214  template <
typename SMSPtrTy> 
class iterator_base {
 
  229    iterator_base(SMSPtrTy 
P, 
unsigned I, 
unsigned SI)
 
  230        : SMS(
P), Idx(
I), SparseIdx(
SI) {}
 
  234      if (Idx == SMSNode::INVALID)
 
  237      assert(Idx < SMS->Dense.size() && 
"Out of range, non-INVALID Idx?");
 
  242    bool isKeyed()
 const { 
return SparseIdx < SMS->Universe; }
 
  244    unsigned Prev()
 const { 
return SMS->Dense[Idx].Prev; }
 
  245    unsigned Next()
 const { 
return SMS->Dense[Idx].Next; }
 
  247    void setPrev(
unsigned P) { SMS->Dense[Idx].Prev = 
P; }
 
  248    void setNext(
unsigned N) { SMS->Dense[Idx].Next = 
N; }
 
  252      assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx &&
 
  253             "Dereferencing iterator of invalid key or index");
 
  255      return SMS->Dense[Idx].Data;
 
 
  262      if (SMS == 
RHS.SMS && Idx == 
RHS.Idx) {
 
  263        assert((isEnd() || SparseIdx == 
RHS.SparseIdx) &&
 
  264               "Same dense entry, but different keys?");
 
 
  275      assert(isKeyed() && 
"Decrementing an invalid iterator");
 
  276      assert((isEnd() || !SMS->isHead(SMS->Dense[Idx])) &&
 
  277             "Decrementing head of list");
 
  281        Idx = SMS->findIndex(SparseIdx).Prev();
 
 
  288      assert(!isEnd() && isKeyed() && 
"Incrementing an invalid/end iterator");
 
 
  293      iterator_base 
I(*
this);
 
 
  298      iterator_base 
I(*
this);
 
 
 
  329    assert(NumFree <= Dense.size() && 
"Out-of-bounds free entries");
 
  330    return Dense.size() - NumFree;
 
 
  339    FreelistIdx = SMSNode::INVALID;
 
 
  348    assert(Idx < Universe && 
"Key out of range");
 
  349    const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u;
 
  350    for (
unsigned i = Sparse[Idx], e = Dense.size(); i < e; i += Stride) {
 
  351      const unsigned FoundIdx = sparseIndex(Dense[i]);
 
  354      if (Idx == FoundIdx && Dense[i].
isValid() && isHead(Dense[i]))
 
 
  409    unsigned Idx = sparseIndex(Val);
 
  412    unsigned NodeIdx = addValue(Val, SMSNode::INVALID, SMSNode::INVALID);
 
  416      Sparse[Idx] = NodeIdx;
 
  417      Dense[NodeIdx].Prev = NodeIdx;
 
  418      return iterator(
this, NodeIdx, Idx);
 
  422    unsigned HeadIdx = 
I.Idx;
 
  423    unsigned TailIdx = 
I.Prev();
 
  424    Dense[TailIdx].Next = NodeIdx;
 
  425    Dense[HeadIdx].Prev = NodeIdx;
 
  426    Dense[NodeIdx].Prev = TailIdx;
 
  428    return iterator(
this, NodeIdx, Idx);
 
 
  456    assert(
I.isKeyed() && !
I.isEnd() && !Dense[
I.Idx].isTombstone() &&
 
  457           "erasing invalid/end/tombstone iterator");
 
  464    makeTombstone(
I.Idx);
 
 
  479    if (isSingleton(
N)) {
 
  481      assert(
N.Next == SMSNode::INVALID && 
"Singleton has next?");
 
  482      return iterator(
this, SMSNode::INVALID, ValIndexOf(
N.Data));
 
  487      Sparse[sparseIndex(
N)] = 
N.Next;
 
  489      return iterator(
this, 
N.Next, ValIndexOf(
N.Data));
 
  495      Dense[
N.Prev].Next = 
N.Next;
 
  503    Dense[
N.Next].Prev = 
N.Prev;
 
  504    Dense[
N.Prev].Next = 
N.Next;
 
  505    return iterator(
this, 
N.Next, ValIndexOf(
N.Data));
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file contains library features backported from future STL versions.
This file defines the SmallVector class.
This file defines the SparseSet class derived from the version described in Briggs,...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Our iterators are iterators over the collection of objects that share a key.
std::ptrdiff_t difference_type
friend class SparseMultiSet
iterator_base & operator++()
iterator_base & operator--()
Increment and decrement operators.
bool operator!=(const iterator_base &RHS) const
iterator_base operator--(int)
reference operator*() const
std::bidirectional_iterator_tag iterator_category
pointer operator->() const
bool operator==(const iterator_base &RHS) const
Comparison operators.
iterator_base operator++(int)
void clear()
Clears the set.
iterator end()
Returns an iterator past this container.
const_iterator end() const
iterator find(const KeyT &Key)
Find an element by its key.
bool contains(const KeyT &Key) const
Returns true if this set contains an element identified by Key.
iterator getTail(const KeyT &Key)
RangePair equal_range(const KeyT &K)
The bounds of the range of items sharing Key K.
const ValueT & const_reference
iterator findIndex(unsigned Idx)
Find an element by its index.
iterator erase(iterator I)
Erases an existing element identified by a valid iterator.
bool empty() const
Returns true if the set is empty.
iterator insert(const ValueT &Val)
Insert a new element at the tail of the subset list.
const_iterator find(const KeyT &Key) const
void setUniverse(unsigned U)
Set the universe size which determines the largest key the set can hold.
SparseMultiSet & operator=(const SparseMultiSet &)=delete
iterator_base< const SparseMultiSet * > const_iterator
size_type size() const
Returns the number of elements in the set.
void eraseAll(const KeyT &K)
Erase all elements with the given key.
size_type count(const KeyT &Key) const
Returns the number of elements identified by Key.
std::pair< iterator, iterator > RangePair
iterator_base< SparseMultiSet * > iterator
const ValueT * const_pointer
SparseMultiSet(const SparseMultiSet &)=delete
iterator getHead(const KeyT &Key)
Return the head and tail of the subset's list, otherwise returns end().
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_calloc(size_t Count, size_t Sz)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
FunctionAddr VTableAddr uintptr_t uintptr_t Data
FunctionAddr VTableAddr Next
SparseSetValFunctor - Helper class for getting a value's index.