10 #ifndef LLVM_ADT_STRATIFIEDSETS_H
11 #define LLVM_ADT_STRATIFIEDSETS_H
23 #include <type_traits>
101 std::vector<StratifiedLink> Links)
102 : Values(std::move(Map)), Links(std::move(Links)) {}
107 Values = std::move(
Other.Values);
108 Links = std::move(
Other.Links);
113 auto Iter = Values.find(Elem);
114 if (Iter == Values.end()) {
121 assert(inbounds(Index));
127 std::vector<StratifiedLink> Links;
129 bool inbounds(
StratifiedIndex Idx)
const {
return Idx < Links.size(); }
224 bool hasAbove()
const {
225 assert(!isRemapped());
226 return Link.hasAbove();
229 bool hasBelow()
const {
230 assert(!isRemapped());
231 return Link.hasBelow();
235 assert(!isRemapped());
240 assert(!isRemapped());
245 assert(!isRemapped());
250 assert(!isRemapped());
255 assert(!isRemapped());
261 assert(!isRemapped());
267 assert(!isRemapped());
271 void setAttr(
unsigned index) {
272 assert(!isRemapped());
274 Link.Attrs.set(index);
278 assert(!isRemapped());
286 assert(!isRemapped());
291 assert(isRemapped());
297 assert(isRemapped());
314 void finalizeSets(std::vector<StratifiedLink> &StratLinks) {
316 for (
auto &
Link : Links) {
317 if (
Link.isRemapped()) {
322 Remaps.
insert(std::make_pair(
Link.Number, Number));
323 StratLinks.push_back(
Link.getLink());
326 for (
auto &
Link : StratLinks) {
327 if (
Link.hasAbove()) {
328 auto &Above = linksAt(
Link.Above);
329 auto Iter = Remaps.
find(Above.Number);
330 assert(Iter != Remaps.
end());
331 Link.Above = Iter->second;
334 if (
Link.hasBelow()) {
335 auto &Below = linksAt(
Link.Below);
336 auto Iter = Remaps.
find(Below.Number);
337 assert(Iter != Remaps.
end());
338 Link.Below = Iter->second;
342 for (
auto &Pair : Values) {
343 auto &Info = Pair.second;
344 auto &
Link = linksAt(Info.Index);
345 auto Iter = Remaps.
find(
Link.Number);
346 assert(Iter != Remaps.
end());
347 Info.Index = Iter->second;
353 static void propagateAttrs(std::vector<StratifiedLink> &Links) {
355 const auto *
Link = &Links[Idx];
356 while (
Link->hasAbove()) {
364 for (
unsigned I = 0, E = Links.size();
I < E; ++
I) {
365 auto CurrentIndex = getHighestParentAbove(
I);
366 if (!Visited.
insert(CurrentIndex).second) {
370 while (Links[CurrentIndex].hasBelow()) {
371 auto &CurrentBits = Links[CurrentIndex].Attrs;
372 auto NextIndex = Links[CurrentIndex].Below;
373 auto &NextBits = Links[NextIndex].Attrs;
374 NextBits |= CurrentBits;
375 CurrentIndex = NextIndex;
384 std::vector<StratifiedLink> StratLinks;
385 finalizeSets(StratLinks);
386 propagateAttrs(StratLinks);
391 std::size_t
size()
const {
return Values.size(); }
392 std::size_t
numSets()
const {
return Links.size(); }
394 bool has(
const T &Elem)
const {
return get(Elem).hasValue(); }
397 if (
get(Main).hasValue())
400 auto NewIndex = getNewUnlinkedIndex();
401 return addAtMerging(Main, NewIndex);
409 auto Index = *indexOf(Main);
410 if (!linksAt(Index).hasAbove())
413 auto Above = linksAt(Index).getAbove();
414 return addAtMerging(ToAdd, Above);
422 auto Index = *indexOf(Main);
423 if (!linksAt(Index).hasBelow())
426 auto Below = linksAt(Index).getBelow();
427 return addAtMerging(ToAdd, Below);
432 auto MainIndex = *indexOf(Main);
433 return addAtMerging(ToAdd, MainIndex);
439 auto *Info = *
get(Main);
440 auto &
Link = linksAt(Info->Index);
441 Link.setAttr(AttrNum);
446 auto *Info = *
get(Main);
447 auto &
Link = linksAt(Info->Index);
448 Link.setAttrs(NewAttrs);
453 auto *Info = *
get(Main);
454 auto *
Link = &linksAt(Info->Index);
455 auto Attrs =
Link->getAttrs();
456 while (
Link->hasAbove()) {
458 Attrs |=
Link->getAttrs();
467 return Attrs[AttrNum];
475 auto *Info = *
get(Main);
476 auto &
Link = linksAt(Info->Index);
477 return Link.getAttrs();
486 return Attrs[AttrNum];
491 std::vector<BuilderLink> Links;
497 auto Pair = Values.insert(std::make_pair(ToAdd, Info));
501 auto &Iter = Pair.first;
502 auto &IterSet = linksAt(Iter->second.Index);
503 auto &ReqSet = linksAt(Index);
506 if (&IterSet != &ReqSet)
507 merge(IterSet.Number, ReqSet.Number);
515 auto *Start = &Links[Index];
516 if (!Start->isRemapped())
519 auto *Current = Start;
520 while (Current->isRemapped())
521 Current = &Links[Current->getRemapIndex()];
523 auto NewRemap = Current->Number;
528 while (Current->isRemapped()) {
529 auto *Next = &Links[Current->getRemapIndex()];
530 Current->updateRemap(NewRemap);
540 assert(inbounds(Idx1) && inbounds(Idx2));
541 assert(&linksAt(Idx1) != &linksAt(Idx2) &&
542 "Merging a set into itself is not allowed");
547 if (tryMergeUpwards(Idx1, Idx2))
550 if (tryMergeUpwards(Idx2, Idx1))
555 mergeDirect(Idx1, Idx2);
561 assert(inbounds(Idx1) && inbounds(Idx2));
563 auto *LinksInto = &linksAt(Idx1);
564 auto *LinksFrom = &linksAt(Idx2);
567 while (LinksInto->hasAbove() && LinksFrom->hasAbove()) {
568 LinksInto = &linksAt(LinksInto->getAbove());
569 LinksFrom = &linksAt(LinksFrom->getAbove());
572 if (LinksFrom->hasAbove()) {
573 LinksInto->setAbove(LinksFrom->getAbove());
574 auto &NewAbove = linksAt(LinksInto->getAbove());
575 NewAbove.setBelow(LinksInto->Number);
584 while (LinksInto->hasBelow() && LinksFrom->hasBelow()) {
585 auto &FromAttrs = LinksFrom->getAttrs();
586 LinksInto->setAttrs(FromAttrs);
590 auto *NewLinksFrom = &linksAt(LinksFrom->getBelow());
591 LinksFrom->remapTo(LinksInto->Number);
592 LinksFrom = NewLinksFrom;
593 LinksInto = &linksAt(LinksInto->getBelow());
596 if (LinksFrom->hasBelow()) {
597 LinksInto->setBelow(LinksFrom->getBelow());
598 auto &NewBelow = linksAt(LinksInto->getBelow());
599 NewBelow.setAbove(LinksInto->Number);
602 LinksFrom->remapTo(LinksInto->Number);
609 assert(inbounds(LowerIndex) && inbounds(UpperIndex));
610 auto *Lower = &linksAt(LowerIndex);
611 auto *Upper = &linksAt(UpperIndex);
615 SmallVector<BuilderLink *, 8>
Found;
616 auto *Current = Lower;
617 auto Attrs = Current->getAttrs();
618 while (Current->hasAbove() && Current != Upper) {
619 Found.push_back(Current);
620 Attrs |= Current->getAttrs();
621 Current = &linksAt(Current->getAbove());
624 if (Current != Upper)
627 Upper->setAttrs(Attrs);
629 if (Lower->hasBelow()) {
630 auto NewBelowIndex = Lower->getBelow();
631 Upper->setBelow(NewBelowIndex);
632 auto &NewBelow = linksAt(NewBelowIndex);
633 NewBelow.setAbove(UpperIndex);
638 for (
const auto &Ptr : Found)
639 Ptr->remapTo(Upper->Number);
644 Optional<const StratifiedInfo *>
get(
const T &Val)
const {
645 auto Result = Values.find(Val);
646 if (Result == Values.end())
648 return &Result->second;
651 Optional<StratifiedInfo *>
get(
const T &Val) {
652 auto Result = Values.find(Val);
653 if (Result == Values.end())
655 return &Result->second;
658 Optional<StratifiedIndex> indexOf(
const T &Val) {
659 auto MaybeVal =
get(Val);
660 if (!MaybeVal.hasValue())
662 auto *Info = *MaybeVal;
668 auto At = addLinks();
669 Links[Set].setBelow(At);
670 Links[At].setAbove(Set);
675 auto At = addLinks();
676 Links[At].setBelow(Set);
677 Links[Set].setAbove(At);
684 auto Link = Links.size();
685 Links.push_back(BuilderLink(
Link));
692 #endif // LLVM_ADT_STRATIFIEDSETS_H
StratifiedSets< T > build()
NoneType
A simple null object to allow implicit construction of Optional<T> and similar types without having to ...
static const unsigned NumStratifiedAttrs
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool getAttribute(const T &Main, unsigned AttrNum)
bool addAbove(const T &Main, const T &ToAdd)
void noteAttribute(const T &Main, unsigned AttrNum)
const StratifiedLink & getLink(StratifiedIndex Index) const
StratifiedAttrs getRawAttributes(const T &Main)
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::size_t numSets() const
Optional< StratifiedInfo > find(const T &Elem) const
void noteAttributes(const T &Main, const StratifiedAttrs &NewAttrs)
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
bool has(const T &Elem) const
bool addWith(const T &Main, const T &ToAdd)
StratifiedSets(DenseMap< T, StratifiedInfo > Map, std::vector< StratifiedLink > Links)
bool addBelow(const T &Main, const T &ToAdd)
static const StratifiedIndex SetSentinel
std::bitset< NumStratifiedAttrs > StratifiedAttrs
iterator find(const KeyT &Val)
bool getRawAttribute(const T &Main, unsigned AttrNum)
StratifiedSets & operator=(StratifiedSets< T > &&Other)
StratifiedAttrs getAttributes(const T &Main)
StratifiedSets(StratifiedSets< T > &&Other)