10 #ifndef LLVM_ADT_STRATIFIEDSETS_H
11 #define LLVM_ADT_STRATIFIEDSETS_H
21 #include <type_traits>
92 std::vector<StratifiedLink> Links)
93 : Values(std::move(Map)), Links(std::move(Links)) {}
96 auto Iter = Values.find(Elem);
97 if (Iter == Values.end())
109 std::vector<StratifiedLink> Links;
111 bool inbounds(
StratifiedIndex Idx)
const {
return Idx < Links.size(); }
185 bool hasAbove()
const {
187 return Link.hasAbove();
190 bool hasBelow()
const {
192 return Link.hasBelow();
269 void finalizeSets(std::vector<StratifiedLink> &StratLinks) {
271 for (
auto &
Link : Links) {
272 if (
Link.isRemapped())
276 Remaps.
insert(std::make_pair(
Link.Number, Number));
277 StratLinks.push_back(
Link.getLink());
280 for (
auto &
Link : StratLinks) {
281 if (
Link.hasAbove()) {
282 auto &Above = linksAt(
Link.Above);
283 auto Iter = Remaps.
find(Above.Number);
285 Link.Above = Iter->second;
288 if (
Link.hasBelow()) {
289 auto &Below = linksAt(
Link.Below);
290 auto Iter = Remaps.
find(Below.Number);
292 Link.Below = Iter->second;
296 for (
auto &Pair : Values) {
297 auto &Info = Pair.second;
298 auto &
Link = linksAt(Info.Index);
299 auto Iter = Remaps.
find(
Link.Number);
301 Info.Index = Iter->second;
307 static void propagateAttrs(std::vector<StratifiedLink> &Links) {
309 const auto *
Link = &Links[Idx];
310 while (
Link->hasAbove()) {
318 for (
unsigned I = 0,
E = Links.size();
I <
E; ++
I) {
319 auto CurrentIndex = getHighestParentAbove(
I);
320 if (!Visited.
insert(CurrentIndex).second)
323 while (Links[CurrentIndex].hasBelow()) {
324 auto &CurrentBits = Links[CurrentIndex].Attrs;
325 auto NextIndex = Links[CurrentIndex].Below;
326 auto &NextBits = Links[NextIndex].Attrs;
327 NextBits |= CurrentBits;
328 CurrentIndex = NextIndex;
337 std::vector<StratifiedLink> StratLinks;
338 finalizeSets(StratLinks);
339 propagateAttrs(StratLinks);
344 bool has(
const T &Elem)
const {
return get(Elem).hasValue(); }
347 if (
get(Main).hasValue())
350 auto NewIndex = getNewUnlinkedIndex();
351 return addAtMerging(Main, NewIndex);
359 auto Index = *indexOf(Main);
360 if (!linksAt(Index).hasAbove())
363 auto Above = linksAt(Index).getAbove();
364 return addAtMerging(ToAdd, Above);
372 auto Index = *indexOf(Main);
373 if (!linksAt(Index).hasBelow())
376 auto Below = linksAt(Index).getBelow();
377 return addAtMerging(ToAdd, Below);
382 auto MainIndex = *indexOf(Main);
383 return addAtMerging(ToAdd, MainIndex);
388 auto *Info = *
get(Main);
389 auto &
Link = linksAt(Info->Index);
390 Link.setAttrs(NewAttrs);
395 std::vector<BuilderLink> Links;
400 auto Pair = Values.insert(std::make_pair(ToAdd, Info));
404 auto &Iter = Pair.first;
405 auto &IterSet = linksAt(Iter->second.Index);
406 auto &ReqSet = linksAt(Index);
409 if (&IterSet != &ReqSet)
410 merge(IterSet.Number, ReqSet.Number);
418 auto *Start = &Links[Index];
419 if (!Start->isRemapped())
422 auto *Current = Start;
423 while (Current->isRemapped())
424 Current = &Links[Current->getRemapIndex()];
426 auto NewRemap = Current->Number;
431 while (Current->isRemapped()) {
432 auto *Next = &Links[Current->getRemapIndex()];
433 Current->updateRemap(NewRemap);
443 assert(inbounds(Idx1) && inbounds(Idx2));
444 assert(&linksAt(Idx1) != &linksAt(Idx2) &&
445 "Merging a set into itself is not allowed");
450 if (tryMergeUpwards(Idx1, Idx2))
453 if (tryMergeUpwards(Idx2, Idx1))
458 mergeDirect(Idx1, Idx2);
464 assert(inbounds(Idx1) && inbounds(Idx2));
466 auto *LinksInto = &linksAt(Idx1);
467 auto *LinksFrom = &linksAt(Idx2);
470 while (LinksInto->hasAbove() && LinksFrom->hasAbove()) {
471 LinksInto = &linksAt(LinksInto->getAbove());
472 LinksFrom = &linksAt(LinksFrom->getAbove());
475 if (LinksFrom->hasAbove()) {
476 LinksInto->setAbove(LinksFrom->getAbove());
477 auto &NewAbove = linksAt(LinksInto->getAbove());
478 NewAbove.setBelow(LinksInto->Number);
487 while (LinksInto->hasBelow() && LinksFrom->hasBelow()) {
488 auto FromAttrs = LinksFrom->getAttrs();
489 LinksInto->setAttrs(FromAttrs);
493 auto *NewLinksFrom = &linksAt(LinksFrom->getBelow());
494 LinksFrom->remapTo(LinksInto->Number);
495 LinksFrom = NewLinksFrom;
496 LinksInto = &linksAt(LinksInto->getBelow());
499 if (LinksFrom->hasBelow()) {
500 LinksInto->setBelow(LinksFrom->getBelow());
501 auto &NewBelow = linksAt(LinksInto->getBelow());
502 NewBelow.setAbove(LinksInto->Number);
505 LinksInto->setAttrs(LinksFrom->getAttrs());
506 LinksFrom->remapTo(LinksInto->Number);
513 assert(inbounds(LowerIndex) && inbounds(UpperIndex));
514 auto *
Lower = &linksAt(LowerIndex);
515 auto *
Upper = &linksAt(UpperIndex);
519 SmallVector<BuilderLink *, 8> Found;
520 auto *Current =
Lower;
521 auto Attrs = Current->getAttrs();
522 while (Current->hasAbove() && Current !=
Upper) {
523 Found.push_back(Current);
524 Attrs |= Current->getAttrs();
525 Current = &linksAt(Current->getAbove());
528 if (Current != Upper)
531 Upper->setAttrs(Attrs);
533 if (
Lower->hasBelow()) {
534 auto NewBelowIndex =
Lower->getBelow();
535 Upper->setBelow(NewBelowIndex);
536 auto &NewBelow = linksAt(NewBelowIndex);
537 NewBelow.setAbove(UpperIndex);
542 for (
const auto &
Ptr : Found)
548 Optional<const StratifiedInfo *>
get(
const T &Val)
const {
549 auto Result = Values.find(Val);
550 if (Result == Values.end())
552 return &Result->second;
555 Optional<StratifiedInfo *>
get(
const T &Val) {
556 auto Result = Values.find(Val);
557 if (Result == Values.end())
559 return &Result->second;
562 Optional<StratifiedIndex> indexOf(
const T &Val) {
563 auto MaybeVal =
get(Val);
564 if (!MaybeVal.hasValue())
566 auto *Info = *MaybeVal;
572 auto At = addLinks();
573 Links[Set].setBelow(At);
574 Links[At].setAbove(Set);
579 auto At = addLinks();
580 Links[At].setBelow(Set);
581 Links[Set].setAbove(At);
588 auto Link = Links.size();
589 Links.push_back(BuilderLink(
Link));
597 #endif // LLVM_ADT_STRATIFIEDSETS_H
StratifiedSets< T > build()
Builds a StratifiedSet from the information we've been given since either construction or the prior b...
StratifiedIndex Below
The link for the set "below" current.
bool addAbove(const T &Main, const T &ToAdd)
Restructures the stratified sets as necessary to make "ToAdd" in a set above "Main".
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
unsigned StratifiedIndex
An index into Stratified Sets.
Optional< StratifiedInfo > find(const T &Elem) const
bool addWith(const T &Main, const T &ToAdd)
static const StratifiedIndex SetSentinel
This is a value used to signify "does not exist" where the StratifiedIndex type is used...
These are stratified sets, as described in "Fast algorithms for Dyck-CFL-reachability with applicatio...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
A "link" between two StratifiedSets.
bool addBelow(const T &Main, const T &ToAdd)
Restructures the stratified sets as necessary to make "ToAdd" in a set below "Main".
const StratifiedLink & getLink(StratifiedIndex Index) const
AliasAttrs Attrs
Attributes for these StratifiedSets.
This file defines various utility types and functions useful to summary-based alias analysis...
StratifiedSets(DenseMap< T, StratifiedInfo > Map, std::vector< StratifiedLink > Links)
StratifiedSets & operator=(StratifiedSets &&)=default
bool has(const T &Elem) const
iterator find(const KeyT &Val)
std::bitset< NumAliasAttrs > AliasAttrs
These are attributes that an alias analysis can use to mark certain special properties of a given poi...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Generic Builder class that produces StratifiedSets instances.
NOTE: ^ This can't be a short – bootstrapping clang has a case where ~1M sets exist.
StratifiedIndex Above
The index for the set "above" current.
void noteAttributes(const T &Main, AliasAttrs NewAttrs)