16#ifndef LLVM_ADT_INTERVALTREE_H
17#define LLVM_ADT_INTERVALTREE_H
244 std::is_pointer<T>::value>;
246template <
typename PointT,
typename ValueT,
250 "PointT must be a fundamental type");
252 "ValueT must be a fundamental or pointer type");
269 IntervalNode *
Left =
nullptr;
270 IntervalNode *
Right =
nullptr;
271 unsigned BucketIntervalsStart = 0;
272 unsigned BucketIntervalsSize = 0;
275 PointType middle()
const {
return MiddlePoint; }
276 unsigned start()
const {
return BucketIntervalsStart; }
277 unsigned size()
const {
return BucketIntervalsSize; }
279 IntervalNode(
PointType Point,
unsigned Start)
280 : MiddlePoint(Point), BucketIntervalsStart(Start) {}
286 IntervalNode *Root =
nullptr;
287 IntervalVector Intervals;
289 PointsVector EndPoints;
307 void deleteTree(IntervalNode *
Node) {
309 deleteTree(
Node->Left);
310 deleteTree(
Node->Right);
311 Node->~IntervalNode();
312 NodeAllocator.Deallocate(
Node);
318 unsigned Start,
unsigned Size,
bool HexFormat =
true) {
320 "Start + Size must be in bounds of the IntervalSet");
321 const char *
Format = HexFormat ?
"[0x%08x,0x%08x] " :
"[%2d,%2d] ";
323 for (
unsigned Position = Start; Position < Start +
Size; ++Position)
325 IntervalSet[Position]->right());
333 void printNode(raw_ostream &
OS,
unsigned Level, IntervalNode *
Node,
334 bool HexFormat =
true) {
335 const char *
Format = HexFormat ?
"MP:0x%08x " :
"MP:%2d ";
338 OS.indent(Level * 2);
340 printList(
OS, IntervalSet,
Node->start(),
Node->size(), HexFormat);
343 PrintNodeData(
"IR", IntervalsRight);
344 PrintNodeData(
"IL", IntervalsLeft);
348 void printTree(raw_ostream &
OS,
unsigned Level, IntervalNode *
Node,
349 bool HexFormat =
true) {
351 printNode(
OS, Level,
Node, HexFormat);
353 printTree(
OS, Level,
Node->Left, HexFormat);
354 printTree(
OS, Level,
Node->Right, HexFormat);
365 IntervalNode *createTree(
unsigned &IntervalsSize,
int PointsBeginIndex,
366 int PointsEndIndex,
int ReferencesBeginIndex,
367 int ReferencesSize) {
378 if (PointsBeginIndex > PointsEndIndex ||
379 ReferencesBeginIndex >= ReferencesSize)
382 int MiddleIndex = (PointsBeginIndex + PointsEndIndex) / 2;
383 PointType MiddlePoint = EndPoints[MiddleIndex];
385 unsigned NewBucketStart = IntervalsSize;
386 unsigned NewBucketSize = 0;
387 int ReferencesRightIndex = ReferencesSize;
390 new (NodeAllocator) IntervalNode(MiddlePoint, NewBucketStart);
395 for (
int Index = ReferencesBeginIndex;
Index < ReferencesRightIndex;) {
399 IntervalsLeft[IntervalsSize] = References[
Index];
400 IntervalsRight[IntervalsSize] = References[
Index];
402 Root->BucketIntervalsSize = ++NewBucketSize;
404 if (
Index < --ReferencesRightIndex)
406 if (ReferencesRightIndex < --ReferencesSize)
407 std::swap(References[ReferencesRightIndex],
408 References[ReferencesSize]);
412 if (References[
Index]->left() > MiddlePoint) {
413 if (
Index < --ReferencesRightIndex)
421 if (NewBucketSize > 1) {
423 std::stable_sort(IntervalsLeft.begin() + NewBucketStart,
424 IntervalsLeft.begin() + NewBucketStart + NewBucketSize,
426 return LHS->left() < RHS->left();
429 std::stable_sort(IntervalsRight.begin() + NewBucketStart,
430 IntervalsRight.begin() + NewBucketStart + NewBucketSize,
432 return LHS->right() > RHS->right();
436 if (PointsBeginIndex <= MiddleIndex - 1) {
437 Root->Left = createTree(IntervalsSize, PointsBeginIndex, MiddleIndex - 1,
438 ReferencesBeginIndex, ReferencesRightIndex);
441 if (MiddleIndex + 1 <= PointsEndIndex) {
442 Root->Right = createTree(IntervalsSize, MiddleIndex + 1, PointsEndIndex,
443 ReferencesRightIndex, ReferencesSize);
464 IntervalNode *
Node =
nullptr;
476 if (Point ==
Node->middle()) {
477 if (
Node->size() == 0) {
484 if (Point < Node->middle()) {
488 if (
Node->size() && (*AscendingBuckets)[
Node->start()]->left(Point)) {
494 (*DescendingBuckets)[
Node->start()]->right(Point)) {
506 void nextInterval() {
510 if (++Index < Node->
size()) {
511 if (
Node->middle() == Point)
513 if (Point < Node->middle()) {
515 if (!(*AscendingBuckets)[
Node->start() + Index]->left(Point)) {
523 if (!(*DescendingBuckets)[
Node->start() + Index]->right(Point)) {
532 if (Point ==
Node->middle()) {
543 find_iterator() =
default;
548 Point(Point),
Index(0) {
553 return (Point <= Node->middle())
554 ? (*AscendingBuckets)[
Node->start() +
Index]
555 : (*DescendingBuckets)[
Node->start() +
Index];
576 return (!
LHS.Node && !
RHS.Node && !
LHS.Index && !
RHS.Index) ||
592 : NodeAllocator(NodeAllocator) {}
596 bool empty()
const {
return Root ==
nullptr; }
603 IntervalsLeft.clear();
604 IntervalsRight.clear();
610 assert(
empty() &&
"Invalid insertion. Interval tree already constructed.");
617 assert(!
empty() &&
"Interval tree it is not constructed.");
628 std::stable_sort(IntervalSet.
begin(), IntervalSet.
end(),
630 return Sort == Sorting::Ascending
631 ? (LHS->right() - LHS->left()) >
632 (RHS->right() - RHS->left())
633 : (LHS->right() - LHS->left()) <
634 (RHS->right() - RHS->left());
642 printTree(
OS, 0, Root, HexFormat);
647 assert(
empty() &&
"Interval tree already constructed.");
654 References.push_back(std::addressof(
Data));
656 std::stable_sort(Points.
begin(), Points.
end());
660 EndPoints.assign(Points.
begin(), Points.
end());
662 IntervalsLeft.resize(Intervals.size());
663 IntervalsRight.resize(Intervals.size());
668 unsigned IntervalsSize = 0;
670 createTree(IntervalsSize, 0, EndPoints.size() - 1,
671 0, References.size());
683 :
find_iterator(&IntervalsLeft, &IntervalsRight, Root, Point);
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Allocate memory in an ever growing pool, as if by bump-pointer.
An interval data composed by a Left and Right points and an associated Value.
bool right(const PointType &Point) const
Return true if Point is inside the right bound of closed interval [Left;Right].
virtual ~IntervalData()=default
IntervalData(PointType Left, PointType Right, ValueType Value)
bool left(const PointType &Point) const
Return true if Point is inside the left bound of closed interval [Left;Right].
bool contains(const PointType &Point) const
Return true when Point is contained in interval [Left;Right].
find_iterator operator++(int)
std::forward_iterator_tag iterator_category
friend bool operator!=(const find_iterator &LHS, const find_iterator &RHS)
friend bool operator==(const find_iterator &LHS, const find_iterator &RHS)
Comparison operators.
find_iterator & operator++()
const DataType * operator->() const
Dereference operators.
const DataType & operator*() const
SmallVector< const DataType *, 4 > IntervalReferences
BumpPtrAllocator Allocator
void clear()
Remove all entries.
bool empty() const
Return true when no intervals are mapped.
void print(raw_ostream &OS, bool HexFormat=true)
Print the interval tree.
void insert(PointType Left, PointType Right, ValueType Value)
Add a mapping of [Left;Right] to Value.
IntervalTree(Allocator &NodeAllocator)
find_iterator find_end() const
Iterator to end find operation.
static void sortIntervals(IntervalReferences &IntervalSet, Sorting Sort)
Sort the given intervals using the following sort options: Ascending: return the intervals with the s...
void create()
Create the interval tree.
find_iterator find(PointType Point) const
Iterator to start a find operation; it returns find_end() if the tree has not been built.
IntervalReferences getContaining(PointType Point) const
Return all the intervals in their natural tree location, that contain the given point.
iterator erase(const_iterator CI)
void push_back(const T &Elt)
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
This is an optimization pass for GlobalISel generic memory operations.
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.
auto unique(Range &&R, Predicate P)
std::bool_constant< std::is_fundamental< T >::value||std::is_pointer< T >::value > ValueTypeIsValid
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
std::bool_constant< std::is_fundamental< T >::value > PointTypeIsValid
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.