1*9880d681SAndroid Build Coastguard Worker //===- StratifiedSets.h - Abstract stratified sets implementation. --------===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_ADT_STRATIFIEDSETS_H 11*9880d681SAndroid Build Coastguard Worker #define LLVM_ADT_STRATIFIEDSETS_H 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker #include "AliasAnalysisSummary.h" 14*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DenseMap.h" 15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Optional.h" 16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallSet.h" 17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h" 18*9880d681SAndroid Build Coastguard Worker #include <bitset> 19*9880d681SAndroid Build Coastguard Worker #include <cassert> 20*9880d681SAndroid Build Coastguard Worker #include <cmath> 21*9880d681SAndroid Build Coastguard Worker #include <type_traits> 22*9880d681SAndroid Build Coastguard Worker #include <utility> 23*9880d681SAndroid Build Coastguard Worker #include <vector> 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker namespace llvm { 26*9880d681SAndroid Build Coastguard Worker namespace cflaa { 27*9880d681SAndroid Build Coastguard Worker /// An index into Stratified Sets. 28*9880d681SAndroid Build Coastguard Worker typedef unsigned StratifiedIndex; 29*9880d681SAndroid Build Coastguard Worker /// NOTE: ^ This can't be a short -- bootstrapping clang has a case where 30*9880d681SAndroid Build Coastguard Worker /// ~1M sets exist. 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker // \brief Container of information related to a value in a StratifiedSet. 33*9880d681SAndroid Build Coastguard Worker struct StratifiedInfo { 34*9880d681SAndroid Build Coastguard Worker StratifiedIndex Index; 35*9880d681SAndroid Build Coastguard Worker /// For field sensitivity, etc. we can tack fields on here. 36*9880d681SAndroid Build Coastguard Worker }; 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker /// A "link" between two StratifiedSets. 39*9880d681SAndroid Build Coastguard Worker struct StratifiedLink { 40*9880d681SAndroid Build Coastguard Worker /// \brief This is a value used to signify "does not exist" where the 41*9880d681SAndroid Build Coastguard Worker /// StratifiedIndex type is used. 42*9880d681SAndroid Build Coastguard Worker /// 43*9880d681SAndroid Build Coastguard Worker /// This is used instead of Optional<StratifiedIndex> because 44*9880d681SAndroid Build Coastguard Worker /// Optional<StratifiedIndex> would eat up a considerable amount of extra 45*9880d681SAndroid Build Coastguard Worker /// memory, after struct padding/alignment is taken into account. 46*9880d681SAndroid Build Coastguard Worker static const StratifiedIndex SetSentinel; 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker /// The index for the set "above" current 49*9880d681SAndroid Build Coastguard Worker StratifiedIndex Above; 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker /// The link for the set "below" current 52*9880d681SAndroid Build Coastguard Worker StratifiedIndex Below; 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker /// Attributes for these StratifiedSets. 55*9880d681SAndroid Build Coastguard Worker AliasAttrs Attrs; 56*9880d681SAndroid Build Coastguard Worker StratifiedLinkStratifiedLink57*9880d681SAndroid Build Coastguard Worker StratifiedLink() : Above(SetSentinel), Below(SetSentinel) {} 58*9880d681SAndroid Build Coastguard Worker hasBelowStratifiedLink59*9880d681SAndroid Build Coastguard Worker bool hasBelow() const { return Below != SetSentinel; } hasAboveStratifiedLink60*9880d681SAndroid Build Coastguard Worker bool hasAbove() const { return Above != SetSentinel; } 61*9880d681SAndroid Build Coastguard Worker clearBelowStratifiedLink62*9880d681SAndroid Build Coastguard Worker void clearBelow() { Below = SetSentinel; } clearAboveStratifiedLink63*9880d681SAndroid Build Coastguard Worker void clearAbove() { Above = SetSentinel; } 64*9880d681SAndroid Build Coastguard Worker }; 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker /// \brief These are stratified sets, as described in "Fast algorithms for 67*9880d681SAndroid Build Coastguard Worker /// Dyck-CFL-reachability with applications to Alias Analysis" by Zhang Q, Lyu M 68*9880d681SAndroid Build Coastguard Worker /// R, Yuan H, and Su Z. -- in short, this is meant to represent different sets 69*9880d681SAndroid Build Coastguard Worker /// of Value*s. If two Value*s are in the same set, or if both sets have 70*9880d681SAndroid Build Coastguard Worker /// overlapping attributes, then the Value*s are said to alias. 71*9880d681SAndroid Build Coastguard Worker /// 72*9880d681SAndroid Build Coastguard Worker /// Sets may be related by position, meaning that one set may be considered as 73*9880d681SAndroid Build Coastguard Worker /// above or below another. In CFL Alias Analysis, this gives us an indication 74*9880d681SAndroid Build Coastguard Worker /// of how two variables are related; if the set of variable A is below a set 75*9880d681SAndroid Build Coastguard Worker /// containing variable B, then at some point, a variable that has interacted 76*9880d681SAndroid Build Coastguard Worker /// with B (or B itself) was either used in order to extract the variable A, or 77*9880d681SAndroid Build Coastguard Worker /// was used as storage of variable A. 78*9880d681SAndroid Build Coastguard Worker /// 79*9880d681SAndroid Build Coastguard Worker /// Sets may also have attributes (as noted above). These attributes are 80*9880d681SAndroid Build Coastguard Worker /// generally used for noting whether a variable in the set has interacted with 81*9880d681SAndroid Build Coastguard Worker /// a variable whose origins we don't quite know (i.e. globals/arguments), or if 82*9880d681SAndroid Build Coastguard Worker /// the variable may have had operations performed on it (modified in a function 83*9880d681SAndroid Build Coastguard Worker /// call). All attributes that exist in a set A must exist in all sets marked as 84*9880d681SAndroid Build Coastguard Worker /// below set A. 85*9880d681SAndroid Build Coastguard Worker template <typename T> class StratifiedSets { 86*9880d681SAndroid Build Coastguard Worker public: 87*9880d681SAndroid Build Coastguard Worker StratifiedSets() = default; 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker // TODO: Figure out how to make MSVC not call the copy ctor here, and delete 90*9880d681SAndroid Build Coastguard Worker // it. 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker // Can't default these due to compile errors in MSVC2013 StratifiedSets(StratifiedSets && Other)93*9880d681SAndroid Build Coastguard Worker StratifiedSets(StratifiedSets &&Other) { *this = std::move(Other); } 94*9880d681SAndroid Build Coastguard Worker StratifiedSets &operator=(StratifiedSets &&Other) { 95*9880d681SAndroid Build Coastguard Worker Values = std::move(Other.Values); 96*9880d681SAndroid Build Coastguard Worker Links = std::move(Other.Links); 97*9880d681SAndroid Build Coastguard Worker return *this; 98*9880d681SAndroid Build Coastguard Worker } 99*9880d681SAndroid Build Coastguard Worker StratifiedSets(DenseMap<T,StratifiedInfo> Map,std::vector<StratifiedLink> Links)100*9880d681SAndroid Build Coastguard Worker StratifiedSets(DenseMap<T, StratifiedInfo> Map, 101*9880d681SAndroid Build Coastguard Worker std::vector<StratifiedLink> Links) 102*9880d681SAndroid Build Coastguard Worker : Values(std::move(Map)), Links(std::move(Links)) {} 103*9880d681SAndroid Build Coastguard Worker find(const T & Elem)104*9880d681SAndroid Build Coastguard Worker Optional<StratifiedInfo> find(const T &Elem) const { 105*9880d681SAndroid Build Coastguard Worker auto Iter = Values.find(Elem); 106*9880d681SAndroid Build Coastguard Worker if (Iter == Values.end()) 107*9880d681SAndroid Build Coastguard Worker return None; 108*9880d681SAndroid Build Coastguard Worker return Iter->second; 109*9880d681SAndroid Build Coastguard Worker } 110*9880d681SAndroid Build Coastguard Worker getLink(StratifiedIndex Index)111*9880d681SAndroid Build Coastguard Worker const StratifiedLink &getLink(StratifiedIndex Index) const { 112*9880d681SAndroid Build Coastguard Worker assert(inbounds(Index)); 113*9880d681SAndroid Build Coastguard Worker return Links[Index]; 114*9880d681SAndroid Build Coastguard Worker } 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker private: 117*9880d681SAndroid Build Coastguard Worker DenseMap<T, StratifiedInfo> Values; 118*9880d681SAndroid Build Coastguard Worker std::vector<StratifiedLink> Links; 119*9880d681SAndroid Build Coastguard Worker inbounds(StratifiedIndex Idx)120*9880d681SAndroid Build Coastguard Worker bool inbounds(StratifiedIndex Idx) const { return Idx < Links.size(); } 121*9880d681SAndroid Build Coastguard Worker }; 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker /// Generic Builder class that produces StratifiedSets instances. 124*9880d681SAndroid Build Coastguard Worker /// 125*9880d681SAndroid Build Coastguard Worker /// The goal of this builder is to efficiently produce correct StratifiedSets 126*9880d681SAndroid Build Coastguard Worker /// instances. To this end, we use a few tricks: 127*9880d681SAndroid Build Coastguard Worker /// > Set chains (A method for linking sets together) 128*9880d681SAndroid Build Coastguard Worker /// > Set remaps (A method for marking a set as an alias [irony?] of another) 129*9880d681SAndroid Build Coastguard Worker /// 130*9880d681SAndroid Build Coastguard Worker /// ==== Set chains ==== 131*9880d681SAndroid Build Coastguard Worker /// This builder has a notion of some value A being above, below, or with some 132*9880d681SAndroid Build Coastguard Worker /// other value B: 133*9880d681SAndroid Build Coastguard Worker /// > The `A above B` relationship implies that there is a reference edge 134*9880d681SAndroid Build Coastguard Worker /// going from A to B. Namely, it notes that A can store anything in B's set. 135*9880d681SAndroid Build Coastguard Worker /// > The `A below B` relationship is the opposite of `A above B`. It implies 136*9880d681SAndroid Build Coastguard Worker /// that there's a dereference edge going from A to B. 137*9880d681SAndroid Build Coastguard Worker /// > The `A with B` relationship states that there's an assignment edge going 138*9880d681SAndroid Build Coastguard Worker /// from A to B, and that A and B should be treated as equals. 139*9880d681SAndroid Build Coastguard Worker /// 140*9880d681SAndroid Build Coastguard Worker /// As an example, take the following code snippet: 141*9880d681SAndroid Build Coastguard Worker /// 142*9880d681SAndroid Build Coastguard Worker /// %a = alloca i32, align 4 143*9880d681SAndroid Build Coastguard Worker /// %ap = alloca i32*, align 8 144*9880d681SAndroid Build Coastguard Worker /// %app = alloca i32**, align 8 145*9880d681SAndroid Build Coastguard Worker /// store %a, %ap 146*9880d681SAndroid Build Coastguard Worker /// store %ap, %app 147*9880d681SAndroid Build Coastguard Worker /// %aw = getelementptr %ap, i32 0 148*9880d681SAndroid Build Coastguard Worker /// 149*9880d681SAndroid Build Coastguard Worker /// Given this, the following relations exist: 150*9880d681SAndroid Build Coastguard Worker /// - %a below %ap & %ap above %a 151*9880d681SAndroid Build Coastguard Worker /// - %ap below %app & %app above %ap 152*9880d681SAndroid Build Coastguard Worker /// - %aw with %ap & %ap with %aw 153*9880d681SAndroid Build Coastguard Worker /// 154*9880d681SAndroid Build Coastguard Worker /// These relations produce the following sets: 155*9880d681SAndroid Build Coastguard Worker /// [{%a}, {%ap, %aw}, {%app}] 156*9880d681SAndroid Build Coastguard Worker /// 157*9880d681SAndroid Build Coastguard Worker /// ...Which state that the only MayAlias relationship in the above program is 158*9880d681SAndroid Build Coastguard Worker /// between %ap and %aw. 159*9880d681SAndroid Build Coastguard Worker /// 160*9880d681SAndroid Build Coastguard Worker /// Because LLVM allows arbitrary casts, code like the following needs to be 161*9880d681SAndroid Build Coastguard Worker /// supported: 162*9880d681SAndroid Build Coastguard Worker /// %ip = alloca i64, align 8 163*9880d681SAndroid Build Coastguard Worker /// %ipp = alloca i64*, align 8 164*9880d681SAndroid Build Coastguard Worker /// %i = bitcast i64** ipp to i64 165*9880d681SAndroid Build Coastguard Worker /// store i64* %ip, i64** %ipp 166*9880d681SAndroid Build Coastguard Worker /// store i64 %i, i64* %ip 167*9880d681SAndroid Build Coastguard Worker /// 168*9880d681SAndroid Build Coastguard Worker /// Which, because %ipp ends up *both* above and below %ip, is fun. 169*9880d681SAndroid Build Coastguard Worker /// 170*9880d681SAndroid Build Coastguard Worker /// This is solved by merging %i and %ipp into a single set (...which is the 171*9880d681SAndroid Build Coastguard Worker /// only way to solve this, since their bit patterns are equivalent). Any sets 172*9880d681SAndroid Build Coastguard Worker /// that ended up in between %i and %ipp at the time of merging (in this case, 173*9880d681SAndroid Build Coastguard Worker /// the set containing %ip) also get conservatively merged into the set of %i 174*9880d681SAndroid Build Coastguard Worker /// and %ipp. In short, the resulting StratifiedSet from the above code would be 175*9880d681SAndroid Build Coastguard Worker /// {%ip, %ipp, %i}. 176*9880d681SAndroid Build Coastguard Worker /// 177*9880d681SAndroid Build Coastguard Worker /// ==== Set remaps ==== 178*9880d681SAndroid Build Coastguard Worker /// More of an implementation detail than anything -- when merging sets, we need 179*9880d681SAndroid Build Coastguard Worker /// to update the numbers of all of the elements mapped to those sets. Rather 180*9880d681SAndroid Build Coastguard Worker /// than doing this at each merge, we note in the BuilderLink structure that a 181*9880d681SAndroid Build Coastguard Worker /// remap has occurred, and use this information so we can defer renumbering set 182*9880d681SAndroid Build Coastguard Worker /// elements until build time. 183*9880d681SAndroid Build Coastguard Worker template <typename T> class StratifiedSetsBuilder { 184*9880d681SAndroid Build Coastguard Worker /// \brief Represents a Stratified Set, with information about the Stratified 185*9880d681SAndroid Build Coastguard Worker /// Set above it, the set below it, and whether the current set has been 186*9880d681SAndroid Build Coastguard Worker /// remapped to another. 187*9880d681SAndroid Build Coastguard Worker struct BuilderLink { 188*9880d681SAndroid Build Coastguard Worker const StratifiedIndex Number; 189*9880d681SAndroid Build Coastguard Worker BuilderLinkBuilderLink190*9880d681SAndroid Build Coastguard Worker BuilderLink(StratifiedIndex N) : Number(N) { 191*9880d681SAndroid Build Coastguard Worker Remap = StratifiedLink::SetSentinel; 192*9880d681SAndroid Build Coastguard Worker } 193*9880d681SAndroid Build Coastguard Worker hasAboveBuilderLink194*9880d681SAndroid Build Coastguard Worker bool hasAbove() const { 195*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 196*9880d681SAndroid Build Coastguard Worker return Link.hasAbove(); 197*9880d681SAndroid Build Coastguard Worker } 198*9880d681SAndroid Build Coastguard Worker hasBelowBuilderLink199*9880d681SAndroid Build Coastguard Worker bool hasBelow() const { 200*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 201*9880d681SAndroid Build Coastguard Worker return Link.hasBelow(); 202*9880d681SAndroid Build Coastguard Worker } 203*9880d681SAndroid Build Coastguard Worker setBelowBuilderLink204*9880d681SAndroid Build Coastguard Worker void setBelow(StratifiedIndex I) { 205*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 206*9880d681SAndroid Build Coastguard Worker Link.Below = I; 207*9880d681SAndroid Build Coastguard Worker } 208*9880d681SAndroid Build Coastguard Worker setAboveBuilderLink209*9880d681SAndroid Build Coastguard Worker void setAbove(StratifiedIndex I) { 210*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 211*9880d681SAndroid Build Coastguard Worker Link.Above = I; 212*9880d681SAndroid Build Coastguard Worker } 213*9880d681SAndroid Build Coastguard Worker clearBelowBuilderLink214*9880d681SAndroid Build Coastguard Worker void clearBelow() { 215*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 216*9880d681SAndroid Build Coastguard Worker Link.clearBelow(); 217*9880d681SAndroid Build Coastguard Worker } 218*9880d681SAndroid Build Coastguard Worker clearAboveBuilderLink219*9880d681SAndroid Build Coastguard Worker void clearAbove() { 220*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 221*9880d681SAndroid Build Coastguard Worker Link.clearAbove(); 222*9880d681SAndroid Build Coastguard Worker } 223*9880d681SAndroid Build Coastguard Worker getBelowBuilderLink224*9880d681SAndroid Build Coastguard Worker StratifiedIndex getBelow() const { 225*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 226*9880d681SAndroid Build Coastguard Worker assert(hasBelow()); 227*9880d681SAndroid Build Coastguard Worker return Link.Below; 228*9880d681SAndroid Build Coastguard Worker } 229*9880d681SAndroid Build Coastguard Worker getAboveBuilderLink230*9880d681SAndroid Build Coastguard Worker StratifiedIndex getAbove() const { 231*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 232*9880d681SAndroid Build Coastguard Worker assert(hasAbove()); 233*9880d681SAndroid Build Coastguard Worker return Link.Above; 234*9880d681SAndroid Build Coastguard Worker } 235*9880d681SAndroid Build Coastguard Worker getAttrsBuilderLink236*9880d681SAndroid Build Coastguard Worker AliasAttrs getAttrs() { 237*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 238*9880d681SAndroid Build Coastguard Worker return Link.Attrs; 239*9880d681SAndroid Build Coastguard Worker } 240*9880d681SAndroid Build Coastguard Worker setAttrsBuilderLink241*9880d681SAndroid Build Coastguard Worker void setAttrs(AliasAttrs Other) { 242*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 243*9880d681SAndroid Build Coastguard Worker Link.Attrs |= Other; 244*9880d681SAndroid Build Coastguard Worker } 245*9880d681SAndroid Build Coastguard Worker isRemappedBuilderLink246*9880d681SAndroid Build Coastguard Worker bool isRemapped() const { return Remap != StratifiedLink::SetSentinel; } 247*9880d681SAndroid Build Coastguard Worker 248*9880d681SAndroid Build Coastguard Worker /// For initial remapping to another set remapToBuilderLink249*9880d681SAndroid Build Coastguard Worker void remapTo(StratifiedIndex Other) { 250*9880d681SAndroid Build Coastguard Worker assert(!isRemapped()); 251*9880d681SAndroid Build Coastguard Worker Remap = Other; 252*9880d681SAndroid Build Coastguard Worker } 253*9880d681SAndroid Build Coastguard Worker getRemapIndexBuilderLink254*9880d681SAndroid Build Coastguard Worker StratifiedIndex getRemapIndex() const { 255*9880d681SAndroid Build Coastguard Worker assert(isRemapped()); 256*9880d681SAndroid Build Coastguard Worker return Remap; 257*9880d681SAndroid Build Coastguard Worker } 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Worker /// Should only be called when we're already remapped. updateRemapBuilderLink260*9880d681SAndroid Build Coastguard Worker void updateRemap(StratifiedIndex Other) { 261*9880d681SAndroid Build Coastguard Worker assert(isRemapped()); 262*9880d681SAndroid Build Coastguard Worker Remap = Other; 263*9880d681SAndroid Build Coastguard Worker } 264*9880d681SAndroid Build Coastguard Worker 265*9880d681SAndroid Build Coastguard Worker /// Prefer the above functions to calling things directly on what's returned 266*9880d681SAndroid Build Coastguard Worker /// from this -- they guard against unexpected calls when the current 267*9880d681SAndroid Build Coastguard Worker /// BuilderLink is remapped. getLinkBuilderLink268*9880d681SAndroid Build Coastguard Worker const StratifiedLink &getLink() const { return Link; } 269*9880d681SAndroid Build Coastguard Worker 270*9880d681SAndroid Build Coastguard Worker private: 271*9880d681SAndroid Build Coastguard Worker StratifiedLink Link; 272*9880d681SAndroid Build Coastguard Worker StratifiedIndex Remap; 273*9880d681SAndroid Build Coastguard Worker }; 274*9880d681SAndroid Build Coastguard Worker 275*9880d681SAndroid Build Coastguard Worker /// \brief This function performs all of the set unioning/value renumbering 276*9880d681SAndroid Build Coastguard Worker /// that we've been putting off, and generates a vector<StratifiedLink> that 277*9880d681SAndroid Build Coastguard Worker /// may be placed in a StratifiedSets instance. finalizeSets(std::vector<StratifiedLink> & StratLinks)278*9880d681SAndroid Build Coastguard Worker void finalizeSets(std::vector<StratifiedLink> &StratLinks) { 279*9880d681SAndroid Build Coastguard Worker DenseMap<StratifiedIndex, StratifiedIndex> Remaps; 280*9880d681SAndroid Build Coastguard Worker for (auto &Link : Links) { 281*9880d681SAndroid Build Coastguard Worker if (Link.isRemapped()) 282*9880d681SAndroid Build Coastguard Worker continue; 283*9880d681SAndroid Build Coastguard Worker 284*9880d681SAndroid Build Coastguard Worker StratifiedIndex Number = StratLinks.size(); 285*9880d681SAndroid Build Coastguard Worker Remaps.insert(std::make_pair(Link.Number, Number)); 286*9880d681SAndroid Build Coastguard Worker StratLinks.push_back(Link.getLink()); 287*9880d681SAndroid Build Coastguard Worker } 288*9880d681SAndroid Build Coastguard Worker 289*9880d681SAndroid Build Coastguard Worker for (auto &Link : StratLinks) { 290*9880d681SAndroid Build Coastguard Worker if (Link.hasAbove()) { 291*9880d681SAndroid Build Coastguard Worker auto &Above = linksAt(Link.Above); 292*9880d681SAndroid Build Coastguard Worker auto Iter = Remaps.find(Above.Number); 293*9880d681SAndroid Build Coastguard Worker assert(Iter != Remaps.end()); 294*9880d681SAndroid Build Coastguard Worker Link.Above = Iter->second; 295*9880d681SAndroid Build Coastguard Worker } 296*9880d681SAndroid Build Coastguard Worker 297*9880d681SAndroid Build Coastguard Worker if (Link.hasBelow()) { 298*9880d681SAndroid Build Coastguard Worker auto &Below = linksAt(Link.Below); 299*9880d681SAndroid Build Coastguard Worker auto Iter = Remaps.find(Below.Number); 300*9880d681SAndroid Build Coastguard Worker assert(Iter != Remaps.end()); 301*9880d681SAndroid Build Coastguard Worker Link.Below = Iter->second; 302*9880d681SAndroid Build Coastguard Worker } 303*9880d681SAndroid Build Coastguard Worker } 304*9880d681SAndroid Build Coastguard Worker 305*9880d681SAndroid Build Coastguard Worker for (auto &Pair : Values) { 306*9880d681SAndroid Build Coastguard Worker auto &Info = Pair.second; 307*9880d681SAndroid Build Coastguard Worker auto &Link = linksAt(Info.Index); 308*9880d681SAndroid Build Coastguard Worker auto Iter = Remaps.find(Link.Number); 309*9880d681SAndroid Build Coastguard Worker assert(Iter != Remaps.end()); 310*9880d681SAndroid Build Coastguard Worker Info.Index = Iter->second; 311*9880d681SAndroid Build Coastguard Worker } 312*9880d681SAndroid Build Coastguard Worker } 313*9880d681SAndroid Build Coastguard Worker 314*9880d681SAndroid Build Coastguard Worker /// \brief There's a guarantee in StratifiedLink where all bits set in a 315*9880d681SAndroid Build Coastguard Worker /// Link.externals will be set in all Link.externals "below" it. propagateAttrs(std::vector<StratifiedLink> & Links)316*9880d681SAndroid Build Coastguard Worker static void propagateAttrs(std::vector<StratifiedLink> &Links) { 317*9880d681SAndroid Build Coastguard Worker const auto getHighestParentAbove = [&Links](StratifiedIndex Idx) { 318*9880d681SAndroid Build Coastguard Worker const auto *Link = &Links[Idx]; 319*9880d681SAndroid Build Coastguard Worker while (Link->hasAbove()) { 320*9880d681SAndroid Build Coastguard Worker Idx = Link->Above; 321*9880d681SAndroid Build Coastguard Worker Link = &Links[Idx]; 322*9880d681SAndroid Build Coastguard Worker } 323*9880d681SAndroid Build Coastguard Worker return Idx; 324*9880d681SAndroid Build Coastguard Worker }; 325*9880d681SAndroid Build Coastguard Worker 326*9880d681SAndroid Build Coastguard Worker SmallSet<StratifiedIndex, 16> Visited; 327*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = Links.size(); I < E; ++I) { 328*9880d681SAndroid Build Coastguard Worker auto CurrentIndex = getHighestParentAbove(I); 329*9880d681SAndroid Build Coastguard Worker if (!Visited.insert(CurrentIndex).second) 330*9880d681SAndroid Build Coastguard Worker continue; 331*9880d681SAndroid Build Coastguard Worker 332*9880d681SAndroid Build Coastguard Worker while (Links[CurrentIndex].hasBelow()) { 333*9880d681SAndroid Build Coastguard Worker auto &CurrentBits = Links[CurrentIndex].Attrs; 334*9880d681SAndroid Build Coastguard Worker auto NextIndex = Links[CurrentIndex].Below; 335*9880d681SAndroid Build Coastguard Worker auto &NextBits = Links[NextIndex].Attrs; 336*9880d681SAndroid Build Coastguard Worker NextBits |= CurrentBits; 337*9880d681SAndroid Build Coastguard Worker CurrentIndex = NextIndex; 338*9880d681SAndroid Build Coastguard Worker } 339*9880d681SAndroid Build Coastguard Worker } 340*9880d681SAndroid Build Coastguard Worker } 341*9880d681SAndroid Build Coastguard Worker 342*9880d681SAndroid Build Coastguard Worker public: 343*9880d681SAndroid Build Coastguard Worker /// Builds a StratifiedSet from the information we've been given since either 344*9880d681SAndroid Build Coastguard Worker /// construction or the prior build() call. build()345*9880d681SAndroid Build Coastguard Worker StratifiedSets<T> build() { 346*9880d681SAndroid Build Coastguard Worker std::vector<StratifiedLink> StratLinks; 347*9880d681SAndroid Build Coastguard Worker finalizeSets(StratLinks); 348*9880d681SAndroid Build Coastguard Worker propagateAttrs(StratLinks); 349*9880d681SAndroid Build Coastguard Worker Links.clear(); 350*9880d681SAndroid Build Coastguard Worker return StratifiedSets<T>(std::move(Values), std::move(StratLinks)); 351*9880d681SAndroid Build Coastguard Worker } 352*9880d681SAndroid Build Coastguard Worker has(const T & Elem)353*9880d681SAndroid Build Coastguard Worker bool has(const T &Elem) const { return get(Elem).hasValue(); } 354*9880d681SAndroid Build Coastguard Worker add(const T & Main)355*9880d681SAndroid Build Coastguard Worker bool add(const T &Main) { 356*9880d681SAndroid Build Coastguard Worker if (get(Main).hasValue()) 357*9880d681SAndroid Build Coastguard Worker return false; 358*9880d681SAndroid Build Coastguard Worker 359*9880d681SAndroid Build Coastguard Worker auto NewIndex = getNewUnlinkedIndex(); 360*9880d681SAndroid Build Coastguard Worker return addAtMerging(Main, NewIndex); 361*9880d681SAndroid Build Coastguard Worker } 362*9880d681SAndroid Build Coastguard Worker 363*9880d681SAndroid Build Coastguard Worker /// \brief Restructures the stratified sets as necessary to make "ToAdd" in a 364*9880d681SAndroid Build Coastguard Worker /// set above "Main". There are some cases where this is not possible (see 365*9880d681SAndroid Build Coastguard Worker /// above), so we merge them such that ToAdd and Main are in the same set. addAbove(const T & Main,const T & ToAdd)366*9880d681SAndroid Build Coastguard Worker bool addAbove(const T &Main, const T &ToAdd) { 367*9880d681SAndroid Build Coastguard Worker assert(has(Main)); 368*9880d681SAndroid Build Coastguard Worker auto Index = *indexOf(Main); 369*9880d681SAndroid Build Coastguard Worker if (!linksAt(Index).hasAbove()) 370*9880d681SAndroid Build Coastguard Worker addLinkAbove(Index); 371*9880d681SAndroid Build Coastguard Worker 372*9880d681SAndroid Build Coastguard Worker auto Above = linksAt(Index).getAbove(); 373*9880d681SAndroid Build Coastguard Worker return addAtMerging(ToAdd, Above); 374*9880d681SAndroid Build Coastguard Worker } 375*9880d681SAndroid Build Coastguard Worker 376*9880d681SAndroid Build Coastguard Worker /// \brief Restructures the stratified sets as necessary to make "ToAdd" in a 377*9880d681SAndroid Build Coastguard Worker /// set below "Main". There are some cases where this is not possible (see 378*9880d681SAndroid Build Coastguard Worker /// above), so we merge them such that ToAdd and Main are in the same set. addBelow(const T & Main,const T & ToAdd)379*9880d681SAndroid Build Coastguard Worker bool addBelow(const T &Main, const T &ToAdd) { 380*9880d681SAndroid Build Coastguard Worker assert(has(Main)); 381*9880d681SAndroid Build Coastguard Worker auto Index = *indexOf(Main); 382*9880d681SAndroid Build Coastguard Worker if (!linksAt(Index).hasBelow()) 383*9880d681SAndroid Build Coastguard Worker addLinkBelow(Index); 384*9880d681SAndroid Build Coastguard Worker 385*9880d681SAndroid Build Coastguard Worker auto Below = linksAt(Index).getBelow(); 386*9880d681SAndroid Build Coastguard Worker return addAtMerging(ToAdd, Below); 387*9880d681SAndroid Build Coastguard Worker } 388*9880d681SAndroid Build Coastguard Worker addWith(const T & Main,const T & ToAdd)389*9880d681SAndroid Build Coastguard Worker bool addWith(const T &Main, const T &ToAdd) { 390*9880d681SAndroid Build Coastguard Worker assert(has(Main)); 391*9880d681SAndroid Build Coastguard Worker auto MainIndex = *indexOf(Main); 392*9880d681SAndroid Build Coastguard Worker return addAtMerging(ToAdd, MainIndex); 393*9880d681SAndroid Build Coastguard Worker } 394*9880d681SAndroid Build Coastguard Worker noteAttributes(const T & Main,AliasAttrs NewAttrs)395*9880d681SAndroid Build Coastguard Worker void noteAttributes(const T &Main, AliasAttrs NewAttrs) { 396*9880d681SAndroid Build Coastguard Worker assert(has(Main)); 397*9880d681SAndroid Build Coastguard Worker auto *Info = *get(Main); 398*9880d681SAndroid Build Coastguard Worker auto &Link = linksAt(Info->Index); 399*9880d681SAndroid Build Coastguard Worker Link.setAttrs(NewAttrs); 400*9880d681SAndroid Build Coastguard Worker } 401*9880d681SAndroid Build Coastguard Worker 402*9880d681SAndroid Build Coastguard Worker private: 403*9880d681SAndroid Build Coastguard Worker DenseMap<T, StratifiedInfo> Values; 404*9880d681SAndroid Build Coastguard Worker std::vector<BuilderLink> Links; 405*9880d681SAndroid Build Coastguard Worker 406*9880d681SAndroid Build Coastguard Worker /// Adds the given element at the given index, merging sets if necessary. addAtMerging(const T & ToAdd,StratifiedIndex Index)407*9880d681SAndroid Build Coastguard Worker bool addAtMerging(const T &ToAdd, StratifiedIndex Index) { 408*9880d681SAndroid Build Coastguard Worker StratifiedInfo Info = {Index}; 409*9880d681SAndroid Build Coastguard Worker auto Pair = Values.insert(std::make_pair(ToAdd, Info)); 410*9880d681SAndroid Build Coastguard Worker if (Pair.second) 411*9880d681SAndroid Build Coastguard Worker return true; 412*9880d681SAndroid Build Coastguard Worker 413*9880d681SAndroid Build Coastguard Worker auto &Iter = Pair.first; 414*9880d681SAndroid Build Coastguard Worker auto &IterSet = linksAt(Iter->second.Index); 415*9880d681SAndroid Build Coastguard Worker auto &ReqSet = linksAt(Index); 416*9880d681SAndroid Build Coastguard Worker 417*9880d681SAndroid Build Coastguard Worker // Failed to add where we wanted to. Merge the sets. 418*9880d681SAndroid Build Coastguard Worker if (&IterSet != &ReqSet) 419*9880d681SAndroid Build Coastguard Worker merge(IterSet.Number, ReqSet.Number); 420*9880d681SAndroid Build Coastguard Worker 421*9880d681SAndroid Build Coastguard Worker return false; 422*9880d681SAndroid Build Coastguard Worker } 423*9880d681SAndroid Build Coastguard Worker 424*9880d681SAndroid Build Coastguard Worker /// Gets the BuilderLink at the given index, taking set remapping into 425*9880d681SAndroid Build Coastguard Worker /// account. linksAt(StratifiedIndex Index)426*9880d681SAndroid Build Coastguard Worker BuilderLink &linksAt(StratifiedIndex Index) { 427*9880d681SAndroid Build Coastguard Worker auto *Start = &Links[Index]; 428*9880d681SAndroid Build Coastguard Worker if (!Start->isRemapped()) 429*9880d681SAndroid Build Coastguard Worker return *Start; 430*9880d681SAndroid Build Coastguard Worker 431*9880d681SAndroid Build Coastguard Worker auto *Current = Start; 432*9880d681SAndroid Build Coastguard Worker while (Current->isRemapped()) 433*9880d681SAndroid Build Coastguard Worker Current = &Links[Current->getRemapIndex()]; 434*9880d681SAndroid Build Coastguard Worker 435*9880d681SAndroid Build Coastguard Worker auto NewRemap = Current->Number; 436*9880d681SAndroid Build Coastguard Worker 437*9880d681SAndroid Build Coastguard Worker // Run through everything that has yet to be updated, and update them to 438*9880d681SAndroid Build Coastguard Worker // remap to NewRemap 439*9880d681SAndroid Build Coastguard Worker Current = Start; 440*9880d681SAndroid Build Coastguard Worker while (Current->isRemapped()) { 441*9880d681SAndroid Build Coastguard Worker auto *Next = &Links[Current->getRemapIndex()]; 442*9880d681SAndroid Build Coastguard Worker Current->updateRemap(NewRemap); 443*9880d681SAndroid Build Coastguard Worker Current = Next; 444*9880d681SAndroid Build Coastguard Worker } 445*9880d681SAndroid Build Coastguard Worker 446*9880d681SAndroid Build Coastguard Worker return *Current; 447*9880d681SAndroid Build Coastguard Worker } 448*9880d681SAndroid Build Coastguard Worker 449*9880d681SAndroid Build Coastguard Worker /// \brief Merges two sets into one another. Assumes that these sets are not 450*9880d681SAndroid Build Coastguard Worker /// already one in the same. merge(StratifiedIndex Idx1,StratifiedIndex Idx2)451*9880d681SAndroid Build Coastguard Worker void merge(StratifiedIndex Idx1, StratifiedIndex Idx2) { 452*9880d681SAndroid Build Coastguard Worker assert(inbounds(Idx1) && inbounds(Idx2)); 453*9880d681SAndroid Build Coastguard Worker assert(&linksAt(Idx1) != &linksAt(Idx2) && 454*9880d681SAndroid Build Coastguard Worker "Merging a set into itself is not allowed"); 455*9880d681SAndroid Build Coastguard Worker 456*9880d681SAndroid Build Coastguard Worker // CASE 1: If the set at `Idx1` is above or below `Idx2`, we need to merge 457*9880d681SAndroid Build Coastguard Worker // both the 458*9880d681SAndroid Build Coastguard Worker // given sets, and all sets between them, into one. 459*9880d681SAndroid Build Coastguard Worker if (tryMergeUpwards(Idx1, Idx2)) 460*9880d681SAndroid Build Coastguard Worker return; 461*9880d681SAndroid Build Coastguard Worker 462*9880d681SAndroid Build Coastguard Worker if (tryMergeUpwards(Idx2, Idx1)) 463*9880d681SAndroid Build Coastguard Worker return; 464*9880d681SAndroid Build Coastguard Worker 465*9880d681SAndroid Build Coastguard Worker // CASE 2: The set at `Idx1` is not in the same chain as the set at `Idx2`. 466*9880d681SAndroid Build Coastguard Worker // We therefore need to merge the two chains together. 467*9880d681SAndroid Build Coastguard Worker mergeDirect(Idx1, Idx2); 468*9880d681SAndroid Build Coastguard Worker } 469*9880d681SAndroid Build Coastguard Worker 470*9880d681SAndroid Build Coastguard Worker /// \brief Merges two sets assuming that the set at `Idx1` is unreachable from 471*9880d681SAndroid Build Coastguard Worker /// traversing above or below the set at `Idx2`. mergeDirect(StratifiedIndex Idx1,StratifiedIndex Idx2)472*9880d681SAndroid Build Coastguard Worker void mergeDirect(StratifiedIndex Idx1, StratifiedIndex Idx2) { 473*9880d681SAndroid Build Coastguard Worker assert(inbounds(Idx1) && inbounds(Idx2)); 474*9880d681SAndroid Build Coastguard Worker 475*9880d681SAndroid Build Coastguard Worker auto *LinksInto = &linksAt(Idx1); 476*9880d681SAndroid Build Coastguard Worker auto *LinksFrom = &linksAt(Idx2); 477*9880d681SAndroid Build Coastguard Worker // Merging everything above LinksInto then proceeding to merge everything 478*9880d681SAndroid Build Coastguard Worker // below LinksInto becomes problematic, so we go as far "up" as possible! 479*9880d681SAndroid Build Coastguard Worker while (LinksInto->hasAbove() && LinksFrom->hasAbove()) { 480*9880d681SAndroid Build Coastguard Worker LinksInto = &linksAt(LinksInto->getAbove()); 481*9880d681SAndroid Build Coastguard Worker LinksFrom = &linksAt(LinksFrom->getAbove()); 482*9880d681SAndroid Build Coastguard Worker } 483*9880d681SAndroid Build Coastguard Worker 484*9880d681SAndroid Build Coastguard Worker if (LinksFrom->hasAbove()) { 485*9880d681SAndroid Build Coastguard Worker LinksInto->setAbove(LinksFrom->getAbove()); 486*9880d681SAndroid Build Coastguard Worker auto &NewAbove = linksAt(LinksInto->getAbove()); 487*9880d681SAndroid Build Coastguard Worker NewAbove.setBelow(LinksInto->Number); 488*9880d681SAndroid Build Coastguard Worker } 489*9880d681SAndroid Build Coastguard Worker 490*9880d681SAndroid Build Coastguard Worker // Merging strategy: 491*9880d681SAndroid Build Coastguard Worker // > If neither has links below, stop. 492*9880d681SAndroid Build Coastguard Worker // > If only `LinksInto` has links below, stop. 493*9880d681SAndroid Build Coastguard Worker // > If only `LinksFrom` has links below, reset `LinksInto.Below` to 494*9880d681SAndroid Build Coastguard Worker // match `LinksFrom.Below` 495*9880d681SAndroid Build Coastguard Worker // > If both have links above, deal with those next. 496*9880d681SAndroid Build Coastguard Worker while (LinksInto->hasBelow() && LinksFrom->hasBelow()) { 497*9880d681SAndroid Build Coastguard Worker auto FromAttrs = LinksFrom->getAttrs(); 498*9880d681SAndroid Build Coastguard Worker LinksInto->setAttrs(FromAttrs); 499*9880d681SAndroid Build Coastguard Worker 500*9880d681SAndroid Build Coastguard Worker // Remap needs to happen after getBelow(), but before 501*9880d681SAndroid Build Coastguard Worker // assignment of LinksFrom 502*9880d681SAndroid Build Coastguard Worker auto *NewLinksFrom = &linksAt(LinksFrom->getBelow()); 503*9880d681SAndroid Build Coastguard Worker LinksFrom->remapTo(LinksInto->Number); 504*9880d681SAndroid Build Coastguard Worker LinksFrom = NewLinksFrom; 505*9880d681SAndroid Build Coastguard Worker LinksInto = &linksAt(LinksInto->getBelow()); 506*9880d681SAndroid Build Coastguard Worker } 507*9880d681SAndroid Build Coastguard Worker 508*9880d681SAndroid Build Coastguard Worker if (LinksFrom->hasBelow()) { 509*9880d681SAndroid Build Coastguard Worker LinksInto->setBelow(LinksFrom->getBelow()); 510*9880d681SAndroid Build Coastguard Worker auto &NewBelow = linksAt(LinksInto->getBelow()); 511*9880d681SAndroid Build Coastguard Worker NewBelow.setAbove(LinksInto->Number); 512*9880d681SAndroid Build Coastguard Worker } 513*9880d681SAndroid Build Coastguard Worker 514*9880d681SAndroid Build Coastguard Worker LinksInto->setAttrs(LinksFrom->getAttrs()); 515*9880d681SAndroid Build Coastguard Worker LinksFrom->remapTo(LinksInto->Number); 516*9880d681SAndroid Build Coastguard Worker } 517*9880d681SAndroid Build Coastguard Worker 518*9880d681SAndroid Build Coastguard Worker /// Checks to see if lowerIndex is at a level lower than upperIndex. If so, it 519*9880d681SAndroid Build Coastguard Worker /// will merge lowerIndex with upperIndex (and all of the sets between) and 520*9880d681SAndroid Build Coastguard Worker /// return true. Otherwise, it will return false. tryMergeUpwards(StratifiedIndex LowerIndex,StratifiedIndex UpperIndex)521*9880d681SAndroid Build Coastguard Worker bool tryMergeUpwards(StratifiedIndex LowerIndex, StratifiedIndex UpperIndex) { 522*9880d681SAndroid Build Coastguard Worker assert(inbounds(LowerIndex) && inbounds(UpperIndex)); 523*9880d681SAndroid Build Coastguard Worker auto *Lower = &linksAt(LowerIndex); 524*9880d681SAndroid Build Coastguard Worker auto *Upper = &linksAt(UpperIndex); 525*9880d681SAndroid Build Coastguard Worker if (Lower == Upper) 526*9880d681SAndroid Build Coastguard Worker return true; 527*9880d681SAndroid Build Coastguard Worker 528*9880d681SAndroid Build Coastguard Worker SmallVector<BuilderLink *, 8> Found; 529*9880d681SAndroid Build Coastguard Worker auto *Current = Lower; 530*9880d681SAndroid Build Coastguard Worker auto Attrs = Current->getAttrs(); 531*9880d681SAndroid Build Coastguard Worker while (Current->hasAbove() && Current != Upper) { 532*9880d681SAndroid Build Coastguard Worker Found.push_back(Current); 533*9880d681SAndroid Build Coastguard Worker Attrs |= Current->getAttrs(); 534*9880d681SAndroid Build Coastguard Worker Current = &linksAt(Current->getAbove()); 535*9880d681SAndroid Build Coastguard Worker } 536*9880d681SAndroid Build Coastguard Worker 537*9880d681SAndroid Build Coastguard Worker if (Current != Upper) 538*9880d681SAndroid Build Coastguard Worker return false; 539*9880d681SAndroid Build Coastguard Worker 540*9880d681SAndroid Build Coastguard Worker Upper->setAttrs(Attrs); 541*9880d681SAndroid Build Coastguard Worker 542*9880d681SAndroid Build Coastguard Worker if (Lower->hasBelow()) { 543*9880d681SAndroid Build Coastguard Worker auto NewBelowIndex = Lower->getBelow(); 544*9880d681SAndroid Build Coastguard Worker Upper->setBelow(NewBelowIndex); 545*9880d681SAndroid Build Coastguard Worker auto &NewBelow = linksAt(NewBelowIndex); 546*9880d681SAndroid Build Coastguard Worker NewBelow.setAbove(UpperIndex); 547*9880d681SAndroid Build Coastguard Worker } else { 548*9880d681SAndroid Build Coastguard Worker Upper->clearBelow(); 549*9880d681SAndroid Build Coastguard Worker } 550*9880d681SAndroid Build Coastguard Worker 551*9880d681SAndroid Build Coastguard Worker for (const auto &Ptr : Found) 552*9880d681SAndroid Build Coastguard Worker Ptr->remapTo(Upper->Number); 553*9880d681SAndroid Build Coastguard Worker 554*9880d681SAndroid Build Coastguard Worker return true; 555*9880d681SAndroid Build Coastguard Worker } 556*9880d681SAndroid Build Coastguard Worker get(const T & Val)557*9880d681SAndroid Build Coastguard Worker Optional<const StratifiedInfo *> get(const T &Val) const { 558*9880d681SAndroid Build Coastguard Worker auto Result = Values.find(Val); 559*9880d681SAndroid Build Coastguard Worker if (Result == Values.end()) 560*9880d681SAndroid Build Coastguard Worker return None; 561*9880d681SAndroid Build Coastguard Worker return &Result->second; 562*9880d681SAndroid Build Coastguard Worker } 563*9880d681SAndroid Build Coastguard Worker get(const T & Val)564*9880d681SAndroid Build Coastguard Worker Optional<StratifiedInfo *> get(const T &Val) { 565*9880d681SAndroid Build Coastguard Worker auto Result = Values.find(Val); 566*9880d681SAndroid Build Coastguard Worker if (Result == Values.end()) 567*9880d681SAndroid Build Coastguard Worker return None; 568*9880d681SAndroid Build Coastguard Worker return &Result->second; 569*9880d681SAndroid Build Coastguard Worker } 570*9880d681SAndroid Build Coastguard Worker indexOf(const T & Val)571*9880d681SAndroid Build Coastguard Worker Optional<StratifiedIndex> indexOf(const T &Val) { 572*9880d681SAndroid Build Coastguard Worker auto MaybeVal = get(Val); 573*9880d681SAndroid Build Coastguard Worker if (!MaybeVal.hasValue()) 574*9880d681SAndroid Build Coastguard Worker return None; 575*9880d681SAndroid Build Coastguard Worker auto *Info = *MaybeVal; 576*9880d681SAndroid Build Coastguard Worker auto &Link = linksAt(Info->Index); 577*9880d681SAndroid Build Coastguard Worker return Link.Number; 578*9880d681SAndroid Build Coastguard Worker } 579*9880d681SAndroid Build Coastguard Worker addLinkBelow(StratifiedIndex Set)580*9880d681SAndroid Build Coastguard Worker StratifiedIndex addLinkBelow(StratifiedIndex Set) { 581*9880d681SAndroid Build Coastguard Worker auto At = addLinks(); 582*9880d681SAndroid Build Coastguard Worker Links[Set].setBelow(At); 583*9880d681SAndroid Build Coastguard Worker Links[At].setAbove(Set); 584*9880d681SAndroid Build Coastguard Worker return At; 585*9880d681SAndroid Build Coastguard Worker } 586*9880d681SAndroid Build Coastguard Worker addLinkAbove(StratifiedIndex Set)587*9880d681SAndroid Build Coastguard Worker StratifiedIndex addLinkAbove(StratifiedIndex Set) { 588*9880d681SAndroid Build Coastguard Worker auto At = addLinks(); 589*9880d681SAndroid Build Coastguard Worker Links[At].setBelow(Set); 590*9880d681SAndroid Build Coastguard Worker Links[Set].setAbove(At); 591*9880d681SAndroid Build Coastguard Worker return At; 592*9880d681SAndroid Build Coastguard Worker } 593*9880d681SAndroid Build Coastguard Worker getNewUnlinkedIndex()594*9880d681SAndroid Build Coastguard Worker StratifiedIndex getNewUnlinkedIndex() { return addLinks(); } 595*9880d681SAndroid Build Coastguard Worker addLinks()596*9880d681SAndroid Build Coastguard Worker StratifiedIndex addLinks() { 597*9880d681SAndroid Build Coastguard Worker auto Link = Links.size(); 598*9880d681SAndroid Build Coastguard Worker Links.push_back(BuilderLink(Link)); 599*9880d681SAndroid Build Coastguard Worker return Link; 600*9880d681SAndroid Build Coastguard Worker } 601*9880d681SAndroid Build Coastguard Worker inbounds(StratifiedIndex N)602*9880d681SAndroid Build Coastguard Worker bool inbounds(StratifiedIndex N) const { return N < Links.size(); } 603*9880d681SAndroid Build Coastguard Worker }; 604*9880d681SAndroid Build Coastguard Worker } 605*9880d681SAndroid Build Coastguard Worker } 606*9880d681SAndroid Build Coastguard Worker #endif // LLVM_ADT_STRATIFIEDSETS_H 607