10 #ifndef LLVM_ADT_STRATIFIEDSETS_H 11 #define LLVM_ADT_STRATIFIEDSETS_H 21 #include <type_traits> 59 bool hasBelow()
const {
return Below != SetSentinel; }
60 bool hasAbove()
const {
return Above != SetSentinel; }
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(); }
179 const StratifiedIndex
Number;
181 BuilderLink(StratifiedIndex
N) : Number(N) {
185 bool hasAbove()
const {
187 return Link.hasAbove();
190 bool hasBelow()
const {
192 return Link.hasBelow();
195 void setBelow(StratifiedIndex
I) {
200 void setAbove(StratifiedIndex I) {
215 StratifiedIndex getBelow()
const {
221 StratifiedIndex getAbove()
const {
240 void remapTo(StratifiedIndex Other) {
245 StratifiedIndex getRemapIndex()
const {
251 void updateRemap(StratifiedIndex Other) {
263 StratifiedIndex Remap;
269 void finalizeSets(std::vector<StratifiedLink> &StratLinks) {
271 for (
auto &
Link : Links) {
272 if (
Link.isRemapped())
275 StratifiedIndex
Number = StratLinks.size();
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;
299 auto Iter = Remaps.
find(
Link.Number);
301 Info.Index = Iter->second;
307 static void propagateAttrs(std::vector<StratifiedLink> &Links) {
308 const auto getHighestParentAbove = [&Links](StratifiedIndex Idx) {
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);
390 Link.setAttrs(NewAttrs);
395 std::vector<BuilderLink> Links;
398 bool addAtMerging(
const T &ToAdd, StratifiedIndex
Index) {
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);
417 BuilderLink &linksAt(StratifiedIndex Index) {
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);
442 void merge(StratifiedIndex Idx1, StratifiedIndex Idx2) {
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);
463 void mergeDirect(StratifiedIndex Idx1, StratifiedIndex 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);
512 bool tryMergeUpwards(StratifiedIndex LowerIndex, StratifiedIndex UpperIndex) {
513 assert(inbounds(LowerIndex) && inbounds(UpperIndex));
514 auto *Lower = &linksAt(LowerIndex);
515 auto *
Upper = &linksAt(UpperIndex);
520 auto *Current = Lower;
521 auto Attrs = Current->getAttrs();
522 while (Current->hasAbove() && Current !=
Upper) {
524 Attrs |= Current->getAttrs();
525 Current = &linksAt(Current->getAbove());
528 if (Current !=
Upper)
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)
543 Ptr->remapTo(
Upper->Number);
549 auto Result = Values.
find(Val);
550 if (Result == Values.
end())
552 return &Result->second;
556 auto Result = Values.
find(Val);
557 if (Result == Values.
end())
559 return &Result->second;
563 auto MaybeVal =
get(Val);
564 if (!MaybeVal.hasValue())
566 auto *
Info = *MaybeVal;
571 StratifiedIndex addLinkBelow(StratifiedIndex Set) {
572 auto At = addLinks();
573 Links[Set].setBelow(At);
574 Links[At].setAbove(Set);
578 StratifiedIndex addLinkAbove(StratifiedIndex Set) {
579 auto At = addLinks();
580 Links[At].setBelow(Set);
581 Links[Set].setAbove(At);
585 StratifiedIndex getNewUnlinkedIndex() {
return addLinks(); }
587 StratifiedIndex addLinks() {
588 auto Link = Links.size();
589 Links.push_back(BuilderLink(
Link));
593 bool inbounds(StratifiedIndex
N)
const {
return N < Links.size(); }
597 #endif // LLVM_ADT_STRATIFIEDSETS_H
This class represents lattice values for constants.
StratifiedSets< T > build()
Builds a StratifiedSet from the information we've been given since either construction or the prior b...
void push_back(const T &Elt)
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.
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...
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
Analysis containing CSE Info
iterator find(const_arg_type_t< KeyT > Val)
const StratifiedLink & getLink(StratifiedIndex Index) const
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.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool addBelow(const T &Main, const T &ToAdd)
Restructures the stratified sets as necessary to make "ToAdd" in a set below "Main".
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)
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)
Optional< StratifiedInfo > find(const T &Elem) const
bool has(const T &Elem) const