104#ifndef LLVM_ADT_INTERVALMAP_H
105#define LLVM_ADT_INTERVALMAP_H
192namespace IntervalMapImpl {
223template <
typename T1,
typename T2,
unsigned N>
236 template <
unsigned M>
238 unsigned j,
unsigned Count) {
239 assert(i + Count <= M &&
"Invalid source range");
240 assert(j + Count <=
N &&
"Invalid dest range");
241 for (
unsigned e = i + Count; i != e; ++i, ++j) {
251 void moveLeft(
unsigned i,
unsigned j,
unsigned Count) {
252 assert(j <= i &&
"Use moveRight shift elements right");
253 copy(*
this, i, j, Count);
260 void moveRight(
unsigned i,
unsigned j,
unsigned Count) {
261 assert(i <= j &&
"Use moveLeft shift elements left");
262 assert(j + Count <=
N &&
"Invalid range");
298 Sib.
copy(*
this, 0, SSize, Count);
310 Sib.
copy(*
this,
Size-Count, 0, Count);
323 unsigned Count = std::min(std::min(
unsigned(
Add), SSize),
N -
Size);
328 unsigned Count = std::min(std::min(
unsigned(-
Add),
Size),
N - SSize);
340template <
typename NodeT>
342 unsigned CurSize[],
const unsigned NewSize[]) {
344 for (
int n = Nodes - 1; n; --n) {
345 if (CurSize[n] == NewSize[n])
347 for (
int m = n - 1; m != -1; --m) {
348 int d =
Node[n]->adjustFromLeftSib(CurSize[n], *
Node[m], CurSize[m],
349 NewSize[n] - CurSize[n]);
353 if (CurSize[n] >= NewSize[n])
362 for (
unsigned n = 0; n != Nodes - 1; ++n) {
363 if (CurSize[n] == NewSize[n])
365 for (
unsigned m = n + 1; m != Nodes; ++m) {
366 int d =
Node[m]->adjustFromLeftSib(CurSize[m], *
Node[n], CurSize[n],
367 CurSize[n] - NewSize[n]);
371 if (CurSize[n] >= NewSize[n])
377 for (
unsigned n = 0; n != Nodes; n++)
378 assert(CurSize[n] == NewSize[n] &&
"Insufficient element shuffle");
416 unsigned Capacity,
const unsigned *CurSize,
417 unsigned NewSize[],
unsigned Position,
bool Grow);
439template <
typename KeyT,
typename ValT>
448 static_cast<unsigned>(2*
sizeof(
KeyT)+
sizeof(
ValT)),
462 static_cast<unsigned>(
sizeof(
KeyT) +
sizeof(
void*))
495 struct CacheAlignedPointerTraits {
496 static inline void *getAsVoidPointer(
void *
P) {
return P; }
497 static inline void *getFromVoidPointer(
void *
P) {
return P; }
510 template <
typename NodeT>
511 NodeRef(NodeT *p,
unsigned n) : pip(p, n - 1) {
512 assert(n <= NodeT::Capacity &&
"Size too big for node");
529 template <
typename NodeT>
531 return *
reinterpret_cast<NodeT*
>(pip.
getPointer());
566template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
585 assert((i == 0 || Traits::stopLess(
stop(i - 1), x)) &&
586 "Index is past the needed point");
587 while (i !=
Size && Traits::stopLess(
stop(i), x)) ++i;
600 assert((i == 0 || Traits::stopLess(
stop(i - 1), x)) &&
601 "Index is past the needed point");
602 while (Traits::stopLess(
stop(i), x)) ++i;
603 assert(i <
N &&
"Unsafe intervals");
614 return Traits::startLess(x,
start(i)) ? NotFound :
value(i);
629template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
634 assert(!Traits::stopLess(b, a) &&
"Invalid interval");
637 assert((i == 0 || Traits::stopLess(stop(i - 1), a)));
638 assert((i ==
Size || !Traits::stopLess(stop(i), a)));
639 assert((i ==
Size || Traits::stopLess(b, start(i))) &&
"Overlapping insert");
642 if (i &&
value(i - 1) == y && Traits::adjacent(stop(i - 1), a)) {
645 if (i !=
Size &&
value(i) == y && Traits::adjacent(b, start(i))) {
646 stop(i - 1) = stop(i);
667 if (
value(i) == y && Traits::adjacent(b, start(i))) {
677 this->shift(i,
Size);
703template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
720 assert((i == 0 || Traits::stopLess(
stop(i - 1), x)) &&
721 "Index to findFrom is past the needed point");
722 while (i !=
Size && Traits::stopLess(
stop(i), x)) ++i;
734 assert((i == 0 || Traits::stopLess(
stop(i - 1), x)) &&
735 "Index is past the needed point");
736 while (Traits::stopLess(
stop(i), x)) ++i;
737 assert(i <
N &&
"Unsafe intervals");
788 NodeRef &subtree(
unsigned i)
const {
789 return reinterpret_cast<NodeRef*
>(node)[i];
798 template <
typename NodeT> NodeT &
node(
unsigned Level)
const {
799 return *
reinterpret_cast<NodeT*
>(path[Level].node);
801 unsigned size(
unsigned Level)
const {
return path[Level].
size; }
802 unsigned offset(
unsigned Level)
const {
return path[Level].offset; }
803 unsigned &
offset(
unsigned Level) {
return path[Level].offset; }
806 template <
typename NodeT> NodeT &
leaf()
const {
807 return *
reinterpret_cast<NodeT*
>(path.
back().node);
826 return path[Level].subtree(path[Level].
offset);
902 for (
unsigned i = 0, e = path.
size(); i != e; ++i)
912 return path[Level].offset == path[Level].
size - 1;
924 ++path[Level].offset;
934template <
typename KeyT,
typename ValT,
935 unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
936 typename Traits = IntervalMapInfo<KeyT>>
948 DesiredRootBranchCap = (
sizeof(
RootLeaf) -
sizeof(
KeyT)) /
950 RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1
957 struct RootBranchData {
982 unsigned rootSize = 0;
987 const RootLeaf &rootLeaf()
const {
988 assert(!branched() &&
"Cannot acces leaf data in branched root");
991 RootLeaf &rootLeaf() {
992 assert(!branched() &&
"Cannot acces leaf data in branched root");
996 const RootBranchData &rootBranchData()
const {
997 assert(branched() &&
"Cannot access branch data in non-branched root");
1000 RootBranchData &rootBranchData() {
1001 assert(branched() &&
"Cannot access branch data in non-branched root");
1005 const RootBranch &rootBranch()
const {
return rootBranchData().node; }
1006 RootBranch &rootBranch() {
return rootBranchData().node; }
1007 KeyT rootBranchStart()
const {
return rootBranchData().start; }
1008 KeyT &rootBranchStart() {
return rootBranchData().start; }
1010 template <
typename NodeT> NodeT *newNode() {
1011 return new (
allocator->template Allocate<NodeT>()) NodeT();
1014 template <
typename NodeT>
void deleteNode(NodeT *
P) {
1019 IdxPair branchRoot(
unsigned Position);
1020 IdxPair splitRoot(
unsigned Position);
1022 void switchRootToBranch() {
1023 rootLeaf().~RootLeaf();
1025 new (&rootBranchData()) RootBranchData();
1028 void switchRootToLeaf() {
1029 rootBranchData().~RootBranchData();
1031 new(&rootLeaf()) RootLeaf();
1034 bool branched()
const {
return height > 0; }
1037 void visitNodes(
void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
1039 void deleteNode(IntervalMapImpl::NodeRef
Node,
unsigned Level);
1059 for (
auto It =
RHS.begin(),
End =
RHS.end(); It !=
End; ++It)
1060 insert(It.start(), It.stop(), It.value());
1068 *
this = std::move(
RHS);
1074 rootLeaf().~RootLeaf();
1076 height =
RHS.height;
1077 rootSize =
RHS.rootSize;
1082 if (
RHS.branched()) {
1083 rootBranch() = std::move(
RHS.rootBranch());
1086 RHS.rootBranch().~RootBranch();
1090 rootLeaf() = std::move(
RHS.rootLeaf());
1098 rootLeaf().~RootLeaf();
1103 return rootSize == 0;
1108 assert(!
empty() &&
"Empty IntervalMap has no start");
1109 return !branched() ? rootLeaf().
start(0) : rootBranchStart();
1114 assert(!
empty() &&
"Empty IntervalMap has no stop");
1115 return !branched() ? rootLeaf().
stop(rootSize - 1) :
1116 rootBranch().
stop(rootSize - 1);
1121 if (
empty() || Traits::startLess(x,
start()) || Traits::stopLess(
stop(), x))
1123 return branched() ? treeSafeLookup(x, NotFound) :
1132 return find(a).insert(a, b, y);
1135 unsigned p = rootLeaf().
findFrom(0, rootSize, a);
1136 rootSize = rootLeaf().
insertFrom(p, rootSize, a, b, y);
1188 assert(Traits::nonEmpty(a, b));
1195 return !Traits::stopLess(b,
I.start());
1201template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1202ValT IntervalMap<KeyT, ValT, N, Traits>::
1203treeSafeLookup(
KeyT x,
ValT NotFound)
const {
1204 assert(branched() &&
"treeLookup assumes a branched root");
1206 IntervalMapImpl::NodeRef NR = rootBranch().safeLookup(x);
1207 for (
unsigned h = height-1; h; --h)
1208 NR = NR.get<Branch>().safeLookup(x);
1209 return NR.get<Leaf>().safeLookup(x, NotFound);
1214template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1216branchRoot(
unsigned Position) {
1217 using namespace IntervalMapImpl;
1219 const unsigned Nodes = RootLeaf::Capacity / Leaf::Capacity + 1;
1222 unsigned size[Nodes];
1223 IdxPair NewOffset(0, Position);
1229 NewOffset =
distribute(Nodes, rootSize, Leaf::Capacity,
nullptr, size,
1235 for (
unsigned n = 0; n != Nodes; ++n) {
1236 Leaf *
L = newNode<Leaf>();
1237 L->copy(rootLeaf(), pos, 0, size[n]);
1238 node[n] =
NodeRef(L, size[n]);
1243 switchRootToBranch();
1244 for (
unsigned n = 0; n != Nodes; ++n) {
1245 rootBranch().stop(n) = node[n].template get<Leaf>().stop(size[n]-1);
1246 rootBranch().subtree(n) = node[n];
1248 rootBranchStart() = node[0].template get<Leaf>().start(0);
1255template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1257splitRoot(
unsigned Position) {
1258 using namespace IntervalMapImpl;
1260 const unsigned Nodes = RootBranch::Capacity / Branch::Capacity + 1;
1263 unsigned Size[Nodes];
1264 IdxPair NewOffset(0, Position);
1270 NewOffset =
distribute(Nodes, rootSize, Leaf::Capacity,
nullptr,
Size,
1276 for (
unsigned n = 0; n != Nodes; ++n) {
1277 Branch *
B = newNode<Branch>();
1278 B->copy(rootBranch(), Pos, 0,
Size[n]);
1283 for (
unsigned n = 0; n != Nodes; ++n) {
1284 rootBranch().stop(n) =
Node[n].template get<Branch>().stop(
Size[n]-1);
1285 rootBranch().subtree(n) =
Node[n];
1293template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1294void IntervalMap<KeyT, ValT, N, Traits>::
1295visitNodes(
void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
unsigned Height)) {
1298 SmallVector<IntervalMapImpl::NodeRef, 4> Refs, NextRefs;
1301 for (
unsigned i = 0; i != rootSize; ++i)
1302 Refs.push_back(rootBranch().subtree(i));
1305 for (
unsigned h = height - 1; h; --h) {
1306 for (
unsigned i = 0, e = Refs.size(); i != e; ++i) {
1307 for (
unsigned j = 0, s = Refs[i].
size();
j != s; ++
j)
1308 NextRefs.push_back(Refs[i].subtree(j));
1309 (this->*f)(Refs[i], h);
1312 Refs.swap(NextRefs);
1316 for (
unsigned i = 0, e = Refs.size(); i !=
e; ++i)
1317 (this->*f)(Refs[i], 0);
1320template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1321void IntervalMap<KeyT, ValT, N, Traits>::
1322deleteNode(IntervalMapImpl::NodeRef
Node,
unsigned Level) {
1324 deleteNode(&
Node.get<Branch>());
1326 deleteNode(&
Node.get<Leaf>());
1329template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1333 visitNodes(&IntervalMap::deleteNode);
1343template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1366 assert(map &&
"Invalid iterator");
1367 return map->branched();
1383 assert(valid() &&
"Cannot access invalid iterator");
1390 assert(valid() &&
"Cannot access invalid iterator");
1397 assert(valid() &&
"Cannot access invalid iterator");
1428 assert(map ==
RHS.map &&
"Cannot compare iterators from different maps");
1430 return !
RHS.valid();
1433 return &path.template leaf<Leaf>() == &
RHS.path.template leaf<Leaf>();
1449 setRoot(map->rootSize);
1454 assert(valid() &&
"Cannot increment end()");
1469 if (path.
leafOffset() && (valid() || !branched()))
1489 setRoot(map->rootLeaf().
findFrom(0, map->rootSize, x));
1508template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1512 for (
unsigned i = map->height - path.height() - 1; i; --i) {
1513 unsigned p = NR.
get<
Branch>().safeFind(0, x);
1522template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1525 setRoot(map->rootBranch().findFrom(0, map->rootSize, x));
1532template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1536 if (!Traits::stopLess(path.leaf<
Leaf>().
stop(path.leafSize() - 1), x)) {
1537 path.leafOffset() = path.leaf<
Leaf>().safeFind(path.leafOffset(), x);
1545 if (path.height()) {
1546 for (
unsigned l = path.height() - 1; l; --l) {
1547 if (!Traits::stopLess(path.node<
Branch>(l).
stop(path.offset(l)), x)) {
1549 path.offset(l + 1) =
1550 path.node<
Branch>(l + 1).safeFind(path.offset(l + 1), x);
1551 return pathFillFind(x);
1556 if (!Traits::stopLess(map->rootBranch().stop(path.offset(0)), x)) {
1557 path.offset(1) = path.node<
Branch>(1).safeFind(path.offset(1), x);
1558 return pathFillFind(x);
1563 setRoot(map->rootBranch().findFrom(path.offset(0), map->rootSize, x));
1572template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1580 void setNodeStop(
unsigned Level,
KeyT Stop);
1582 template <
typename NodeT>
bool overflow(
unsigned Level);
1584 void eraseNode(
unsigned Level);
1585 void treeErase(
bool UpdateRoot =
true);
1586 bool canCoalesceLeft(
KeyT Start,
ValT x);
1587 bool canCoalesceRight(
KeyT Stop,
ValT x);
1619 this->unsafeStop() = b;
1621 if (this->path.atLastEntry(this->path.height()))
1622 setNodeStop(this->path.height(), b);
1664template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1667 using namespace IntervalMapImpl;
1668 Path &
P = this->path;
1669 if (!this->branched()) {
1670 unsigned i =
P.leafOffset();
1671 RootLeaf &
Node =
P.leaf<RootLeaf>();
1673 Traits::adjacent(
Node.stop(i-1), Start);
1676 if (
unsigned i =
P.leafOffset()) {
1677 Leaf &
Node =
P.leaf<Leaf>();
1678 return Node.value(i-1) == Value && Traits::adjacent(
Node.stop(i-1), Start);
1679 }
else if (NodeRef NR =
P.getLeftSibling(
P.height())) {
1680 unsigned i = NR.size() - 1;
1681 Leaf &
Node = NR.get<Leaf>();
1682 return Node.value(i) ==
Value && Traits::adjacent(
Node.stop(i), Start);
1692template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1693bool IntervalMap<KeyT, ValT, N, Traits>::
1694iterator::canCoalesceRight(
KeyT Stop,
ValT Value) {
1695 using namespace IntervalMapImpl;
1696 Path &
P = this->path;
1697 unsigned i =
P.leafOffset() + 1;
1698 if (!this->branched()) {
1699 if (i >=
P.leafSize())
1701 RootLeaf &
Node =
P.leaf<RootLeaf>();
1702 return Node.value(i) ==
Value && Traits::adjacent(Stop,
Node.start(i));
1705 if (i <
P.leafSize()) {
1706 Leaf &
Node =
P.leaf<Leaf>();
1707 return Node.value(i) ==
Value && Traits::adjacent(Stop,
Node.start(i));
1708 }
else if (NodeRef NR =
P.getRightSibling(
P.height())) {
1709 Leaf &
Node = NR.get<Leaf>();
1710 return Node.value(0) ==
Value && Traits::adjacent(Stop,
Node.start(0));
1716template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1717void IntervalMap<KeyT, ValT, N, Traits>::
1718iterator::setNodeStop(
unsigned Level,
KeyT Stop) {
1722 IntervalMapImpl::Path &
P = this->path;
1725 P.node<
Branch>(Level).stop(
P.offset(Level)) = Stop;
1726 if (!
P.atLastEntry(Level))
1730 P.node<RootBranch>(Level).stop(
P.offset(Level)) = Stop;
1733template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1736 assert(Traits::nonEmpty(a, this->stop()) &&
"Cannot move start beyond stop");
1737 KeyT &CurStart = this->unsafeStart();
1738 if (!Traits::startLess(a, CurStart) || !canCoalesceLeft(a, this->
value())) {
1746 setStartUnchecked(a);
1749template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1752 assert(Traits::nonEmpty(this->start(), b) &&
"Cannot move stop beyond start");
1753 if (Traits::startLess(b, this->stop()) ||
1754 !canCoalesceRight(b, this->
value())) {
1755 setStopUnchecked(b);
1759 KeyT a = this->start();
1761 setStartUnchecked(a);
1764template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1767 setValueUnchecked(x);
1768 if (canCoalesceRight(this->stop(), x)) {
1769 KeyT a = this->start();
1771 setStartUnchecked(a);
1773 if (canCoalesceLeft(this->start(), x)) {
1775 KeyT a = this->start();
1777 setStartUnchecked(a);
1787template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1790 assert(Level &&
"Cannot insert next to the root");
1791 bool SplitRoot =
false;
1797 if (IM.rootSize < RootBranch::Capacity) {
1798 IM.rootBranch().
insert(
P.offset(0), IM.rootSize,
Node, Stop);
1799 P.setSize(0, ++IM.rootSize);
1806 IdxPair
Offset = IM.splitRoot(
P.offset(0));
1807 P.replaceRoot(&IM.rootBranch(), IM.rootSize,
Offset);
1814 P.legalizeForInsert(--Level);
1817 if (
P.size(Level) == Branch::Capacity) {
1819 assert(!SplitRoot &&
"Cannot overflow after splitting the root");
1820 SplitRoot = overflow<Branch>(Level);
1823 P.node<
Branch>(Level).insert(
P.offset(Level),
P.size(Level),
Node, Stop);
1824 P.setSize(Level,
P.size(Level) + 1);
1825 if (
P.atLastEntry(Level))
1826 setNodeStop(Level, Stop);
1832template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1835 if (this->branched())
1836 return treeInsert(a, b, y);
1841 unsigned Size = IM.rootLeaf().
insertFrom(
P.leafOffset(), IM.rootSize, a, b, y);
1844 if (
Size <= RootLeaf::Capacity) {
1845 P.setSize(0, IM.rootSize =
Size);
1850 IdxPair
Offset = IM.branchRoot(
P.leafOffset());
1851 P.replaceRoot(&IM.rootBranch(), IM.rootSize,
Offset);
1854 treeInsert(a, b, y);
1857template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1860 using namespace IntervalMapImpl;
1861 Path &
P = this->path;
1864 P.legalizeForInsert(this->map->height);
1867 if (
P.leafOffset() == 0 && Traits::startLess(a,
P.leaf<
Leaf>().
start(0))) {
1869 if (NodeRef Sib =
P.getLeftSibling(
P.height())) {
1871 unsigned SibOfs = Sib.size() - 1;
1872 if (SibLeaf.
value(SibOfs) == y &&
1873 Traits::adjacent(SibLeaf.
stop(SibOfs), a)) {
1880 P.moveLeft(
P.height());
1881 if (Traits::stopLess(b, CurLeaf.
start(0)) &&
1882 (y != CurLeaf.
value(0) || !Traits::adjacent(b, CurLeaf.
start(0)))) {
1884 setNodeStop(
P.height(), SibLeaf.
stop(SibOfs) = b);
1889 a = SibLeaf.
start(SibOfs);
1895 this->map->rootBranchStart() = a;
1900 unsigned Size =
P.leafSize();
1901 bool Grow =
P.leafOffset() ==
Size;
1902 Size =
P.leaf<Leaf>().insertFrom(
P.leafOffset(),
Size, a,
b,
y);
1905 if (
Size > Leaf::Capacity) {
1906 overflow<Leaf>(
P.height());
1907 Grow =
P.leafOffset() ==
P.leafSize();
1908 Size =
P.leaf<Leaf>().insertFrom(
P.leafOffset(),
P.leafSize(), a,
b,
y);
1909 assert(
Size <= Leaf::Capacity &&
"overflow() didn't make room");
1913 P.setSize(
P.height(),
Size);
1917 setNodeStop(
P.height(), b);
1921template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1926 assert(
P.valid() &&
"Cannot erase end()");
1927 if (this->branched())
1929 IM.rootLeaf().
erase(
P.leafOffset(), IM.rootSize);
1930 P.setSize(0, --IM.rootSize);
1934template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1942 if (
P.leafSize() == 1) {
1943 IM.deleteNode(&
Node);
1944 eraseNode(IM.height);
1946 if (UpdateRoot && IM.branched() &&
P.valid() &&
P.atBegin())
1947 IM.rootBranchStart() =
P.leaf<
Leaf>().start(0);
1952 Node.erase(
P.leafOffset(),
P.leafSize());
1953 unsigned NewSize =
P.leafSize() - 1;
1954 P.setSize(IM.height, NewSize);
1956 if (
P.leafOffset() == NewSize) {
1957 setNodeStop(IM.height,
Node.stop(NewSize - 1));
1958 P.moveRight(IM.height);
1959 }
else if (UpdateRoot &&
P.atBegin())
1960 IM.rootBranchStart() =
P.leaf<Leaf>().start(0);
1967template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1968void IntervalMap<KeyT, ValT, N, Traits>::
1969iterator::eraseNode(
unsigned Level) {
1970 assert(Level &&
"Cannot erase root node");
1971 IntervalMap &IM = *this->map;
1972 IntervalMapImpl::Path &
P = this->path;
1975 IM.rootBranch().erase(
P.offset(0), IM.rootSize);
1976 P.setSize(0, --IM.rootSize);
1979 IM.switchRootToLeaf();
1986 if (
P.size(Level) == 1) {
1988 IM.deleteNode(&Parent);
1992 Parent.erase(
P.offset(Level),
P.size(Level));
1993 unsigned NewSize =
P.size(Level) - 1;
1994 P.setSize(Level, NewSize);
1996 if (
P.offset(Level) == NewSize) {
1997 setNodeStop(Level, Parent.stop(NewSize - 1));
2005 P.offset(Level + 1) = 0;
2015template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
2016template <
typename NodeT>
2017bool IntervalMap<KeyT, ValT, N, Traits>::
2018iterator::overflow(
unsigned Level) {
2019 using namespace IntervalMapImpl;
2020 Path &
P = this->path;
2021 unsigned CurSize[4];
2025 unsigned Offset =
P.offset(Level);
2028 NodeRef LeftSib =
P.getLeftSibling(Level);
2031 Node[Nodes++] = &LeftSib.get<NodeT>();
2035 Elements += CurSize[Nodes] =
P.size(Level);
2036 Node[Nodes++] = &
P.node<NodeT>(Level);
2039 NodeRef RightSib =
P.getRightSibling(Level);
2041 Elements += CurSize[Nodes] = RightSib.size();
2042 Node[Nodes++] = &RightSib.get<NodeT>();
2046 unsigned NewNode = 0;
2047 if (Elements + 1 > Nodes * NodeT::Capacity) {
2049 NewNode = Nodes == 1 ? 1 : Nodes - 1;
2050 CurSize[Nodes] = CurSize[NewNode];
2052 CurSize[NewNode] = 0;
2053 Node[NewNode] = this->map->template newNode<NodeT>();
2058 unsigned NewSize[4];
2060 CurSize, NewSize,
Offset,
true);
2068 bool SplitRoot =
false;
2071 KeyT Stop =
Node[Pos]->stop(NewSize[Pos]-1);
2072 if (NewNode && Pos == NewNode) {
2073 SplitRoot = insertNode(Level,
NodeRef(
Node[Pos], NewSize[Pos]), Stop);
2076 P.setSize(Level, NewSize[Pos]);
2077 setNodeStop(Level, Stop);
2079 if (Pos + 1 == Nodes)
2086 while(Pos != NewOffset.first) {
2090 P.offset(Level) = NewOffset.second;
2110template <
typename MapA,
typename MapB>
2112 using KeyType =
typename MapA::KeyType;
2113 using Traits =
typename MapA::KeyTraits;
2115 typename MapA::const_iterator posA;
2116 typename MapB::const_iterator posB;
2125 if (Traits::stopLess(posA.stop(), posB.start())) {
2128 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2130 }
else if (Traits::stopLess(posB.stop(), posA.start())) {
2132 posB.advanceTo(posA.start());
2133 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2142 posA.advanceTo(posB.start());
2143 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2146 posB.advanceTo(posA.start());
2147 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2160 return posA.valid() && posB.valid();
2164 const typename MapA::const_iterator &
a()
const {
return posA; }
2167 const typename MapB::const_iterator &
b()
const {
return posB; }
2171 KeyType ak =
a().start();
2172 KeyType bk =
b().start();
2173 return Traits::startLess(ak, bk) ? bk : ak;
2178 KeyType ak =
a().stop();
2179 KeyType bk =
b().stop();
2180 return Traits::startLess(ak, bk) ? ak : bk;
2198 if (Traits::startLess(posB.stop(), posA.stop()))
2211 if (Traits::stopLess(posA.stop(), x))
2213 if (Traits::stopLess(posB.stop(), x))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Given that RA is a live value
This file defines the PointerIntPair class.
This file defines the SmallVector class.
const NodeRef & subtree(unsigned i) const
NodeRef & subtree(unsigned i)
unsigned safeFind(unsigned i, KeyT x) const
safeFind - Find a subtree that is known to exist.
const KeyT & stop(unsigned i) const
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
findFrom - Find the first subtree after i that may contain x.
NodeRef safeLookup(KeyT x) const
safeLookup - Get the subtree containing x, Assuming that x is in range.
void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop)
insert - Insert a new (subtree, stop) pair.
unsigned safeFind(unsigned i, KeyT x) const
safeFind - Find an interval that is known to exist.
const KeyT & stop(unsigned i) const
const ValT & value(unsigned i) const
ValT safeLookup(KeyT x, ValT NotFound) const
safeLookup - Lookup mapped value for a safe key.
unsigned insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y)
insertFrom - Add mapping of [a;b] to y if possible, coalescing as much as possible.
const KeyT & start(unsigned i) const
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
findFrom - Find the first interval after i that may contain x.
void erase(unsigned i, unsigned j, unsigned Size)
erase - Erase elements [i;j).
void moveLeft(unsigned i, unsigned j, unsigned Count)
moveLeft - Move elements to the left.
void transferToLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, unsigned Count)
transferToLeftSib - Transfer elements to a left sibling node.
void copy(const NodeBase< T1, T2, M > &Other, unsigned i, unsigned j, unsigned Count)
copy - Copy elements from another node.
static constexpr unsigned Capacity
int adjustFromLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, int Add)
adjustFromLeftSib - Adjust the number if elements in this node by moving elements to or from a left s...
void shift(unsigned i, unsigned Size)
shift - Shift elements [i;size) 1 position to the right.
void transferToRightSib(unsigned Size, NodeBase &Sib, unsigned SSize, unsigned Count)
transferToRightSib - Transfer elements to a right sibling node.
void erase(unsigned i, unsigned Size)
erase - Erase element at i.
void moveRight(unsigned i, unsigned j, unsigned Count)
moveRight - Move elements to the right.
unsigned size() const
size - Return the number of elements in the referenced node.
bool operator!=(const NodeRef &RHS) const
void setSize(unsigned n)
setSize - Update the node size.
bool operator==(const NodeRef &RHS) const
NodeT & get() const
get - Dereference as a NodeT reference.
NodeRef(NodeT *p, unsigned n)
NodeRef - Create a reference to the node p with n elements.
NodeRef & subtree(unsigned i) const
subtree - Access the i'th subtree reference in a branch node.
NodeRef()=default
NodeRef - Create a null ref.
LLVM_ABI void replaceRoot(void *Root, unsigned Size, IdxPair Offsets)
replaceRoot - Replace the current root node with two new entries after the tree height has increased.
unsigned & offset(unsigned Level)
bool valid() const
valid - Return true if path is at a valid node, not at end().
void reset(unsigned Level)
reset - Reset cached information about node(Level) from subtree(Level -1).
LLVM_ABI NodeRef getLeftSibling(unsigned Level) const
getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
void setRoot(void *Node, unsigned Size, unsigned Offset)
setRoot - Clear the path and set a new root node.
unsigned offset(unsigned Level) const
unsigned leafOffset() const
NodeT & node(unsigned Level) const
bool atLastEntry(unsigned Level) const
atLastEntry - Return true if the path is at the last entry of the node at Level.
unsigned leafSize() const
bool atBegin() const
atBegin - Return true if path is at begin().
unsigned height() const
height - Return the height of the tree corresponding to this path.
LLVM_ABI void moveRight(unsigned Level)
moveRight - Move path to the left sibling at Level.
void pop()
pop - Remove the last path entry.
void setSize(unsigned Level, unsigned Size)
setSize - Set the size of a node both in the path and in the tree.
LLVM_ABI NodeRef getRightSibling(unsigned Level) const
getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
void fillLeft(unsigned Height)
fillLeft - Grow path to Height by taking leftmost branches.
void legalizeForInsert(unsigned Level)
legalizeForInsert - Prepare the path for an insertion at Level.
unsigned size(unsigned Level) const
LLVM_ABI void moveLeft(unsigned Level)
moveLeft - Move path to the left sibling at Level.
void push(NodeRef Node, unsigned Offset)
push - Add entry to path.
NodeRef & subtree(unsigned Level) const
subtree - Get the subtree referenced from Level.
IntervalMapOverlaps - Iterate over the overlaps of mapped intervals in two IntervalMaps.
IntervalMapOverlaps & operator++()
Preincrement - Move to the next overlap.
void skipB()
skipB - Move to the next overlap that doesn't involve b().
void skipA()
skipA - Move to the next overlap that doesn't involve a().
IntervalMapOverlaps(const MapA &a, const MapB &b)
IntervalMapOverlaps - Create an iterator for the overlaps of a and b.
KeyType start() const
start - Beginning of the overlapping interval.
const MapA::const_iterator & a() const
a - access the left hand side in the overlap.
void advanceTo(KeyType x)
advanceTo - Move to the first overlapping interval with stopLess(x, stop()).
bool valid() const
valid - Return true if iterator is at an overlap.
const MapB::const_iterator & b() const
b - access the right hand side in the overlap.
KeyType stop() const
stop - End of the overlapping interval.
void setMap(const IntervalMap &m)
setMap - Change the map iterated over.
const_iterator(const IntervalMap &map)
const_iterator()=default
const_iterator - Create an iterator that isn't pointing anywhere.
void advanceTo(KeyT x)
advanceTo - Move to the first interval with stop >= x, or end().
void pathFillFind(KeyT x)
pathFillFind - Complete path by searching for x.
bool operator==(const const_iterator &RHS) const
bool operator!=(const const_iterator &RHS) const
void goToEnd()
goToEnd - Move beyond the last interval in map.
const KeyT & stop() const
stop - Return the end of the current interval.
KeyT & unsafeStop() const
unsafeStop - Writable access to stop() for iterator.
const_iterator & operator++()
preincrement - Move to the next interval.
bool valid() const
valid - Return true if the current position is valid, false for end().
const KeyT & start() const
start - Return the beginning of the current interval.
void treeAdvanceTo(KeyT x)
treeAdvanceTo - Find position after the current one.
ValT & unsafeValue() const
unsafeValue - Writable access to value() for iterator.
const ValT & operator*() const
std::bidirectional_iterator_tag iterator_category
const ValT & value() const
value - Return the mapped value at the current interval.
const_iterator operator--(int)
postdecrement - Don't do that!
IntervalMapImpl::Path path
void setRoot(unsigned Offset)
void treeFind(KeyT x)
treeFind - Find in a branched tree.
bool atBegin() const
atBegin - Return true if the current position is the first map entry.
std::ptrdiff_t difference_type
void find(KeyT x)
find - Move to the first interval with stop >= x, or end().
const_iterator & operator--()
predecrement - Move to the previous interval.
KeyT & unsafeStart() const
unsafeStart - Writable access to start() for iterator.
void goToBegin()
goToBegin - Move to the first interval in map.
const_iterator operator++(int)
postincrement - Don't do that!
void insert(KeyT a, KeyT b, ValT y)
insert - Insert mapping [a;b] -> y before the current position.
void setValueUnchecked(ValT x)
setValueUnchecked - Change the mapped value of the current interval without checking for coalescing.
iterator()=default
iterator - Create null iterator.
void setStart(KeyT a)
setStart - Move the start of the current interval.
void erase()
erase - Erase the current interval.
void setValue(ValT x)
setValue - Change the mapped value of the current interval.
void setStartUnchecked(KeyT a)
setStartUnchecked - Move the start of the current interval without checking for coalescing or overlap...
void setStop(KeyT b)
setStop - Move the end of the current interval.
void setStopUnchecked(KeyT b)
setStopUnchecked - Move the end of the current interval without checking for coalescing or overlaps.
const_iterator begin() const
void insert(KeyT a, KeyT b, ValT y)
insert - Add a mapping of [a;b] to y, coalesce with adjacent intervals.
ValT lookup(KeyT x, ValT NotFound=ValT()) const
lookup - Return the mapped value at x or NotFound.
KeyT stop() const
stop - Return the largest mapped key in a non-empty map.
IntervalMap & operator=(IntervalMap const &RHS)
typename Sizer::Allocator Allocator
IntervalMap & operator=(IntervalMap &&RHS)
IntervalMap(IntervalMap &&RHS)
const_iterator find(KeyT x) const
find - Return an iterator pointing to the first interval ending at or after x, or end().
RootBranchData branchData
IntervalMap(IntervalMap const &RHS)
bool overlaps(KeyT a, KeyT b) const
overlaps(a, b) - Return true if the intervals in this map overlap with the interval [a;b].
bool empty() const
empty - Return true when no intervals are mapped.
const_iterator end() const
KeyT start() const
start - Return the smallest mapped key in a non-empty map.
void clear()
clear - Remove all entries.
IntervalMap(Allocator &a)
PointerIntPair - This class implements a pair of a pointer and small integer.
void setInt(IntType IntVal) &
void * getOpaqueValue() const
PointerTy getPointer() const
RecyclingAllocator - This class wraps an Allocator, adding the functionality of recycling deleted obj...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
std::pair< unsigned, unsigned > IdxPair
void adjustSiblingSizes(NodeT *Node[], unsigned Nodes, unsigned CurSize[], const unsigned NewSize[])
IntervalMapImpl::adjustSiblingSizes - Move elements between sibling nodes.
LLVM_ABI IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity, const unsigned *CurSize, unsigned NewSize[], unsigned Position, bool Grow)
IntervalMapImpl::distribute - Compute a new distribution of node elements after an overflow or underf...
std::pair< NodeId, LaneBitmask > NodeRef
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
static bool startLess(const T &x, const T &a)
startLess - Return true if x is not in [a;b).
static bool adjacent(const T &a, const T &b)
adjacent - Return true when the intervals [x;a) and [b;y) can coalesce.
static bool stopLess(const T &b, const T &x)
stopLess - Return true if x is not in [a;b).
static bool nonEmpty(const T &a, const T &b)
nonEmpty - Return true if [a;b) is non-empty.
NodeBase< std::pair< KeyT, KeyT >, ValT, LeafSize > LeafBase
RecyclingAllocator< BumpPtrAllocator, char, AllocBytes, CacheLineBytes > Allocator
Allocator - The recycling allocator used for both branch and leaf nodes.
static bool startLess(const T &x, const T &a)
startLess - Return true if x is not in [a;b].
static bool adjacent(const T &a, const T &b)
adjacent - Return true when the intervals [x;a] and [b;y] can coalesce.
static bool nonEmpty(const T &a, const T &b)
nonEmpty - Return true if [a;b] is non-empty.
static bool stopLess(const T &b, const T &x)
stopLess - Return true if x is not in [a;b].