mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 04:38:24 +00:00
Move tree navigation to a new Path class that doesn't have to be a template.
The path also holds a reference to the root node, and that allows important iterator accessors like start() and stop() to have no conditional code. (When the compiler is clever enough to remove it.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120165 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -16,6 +16,107 @@
|
||||
namespace llvm {
|
||||
namespace IntervalMapImpl {
|
||||
|
||||
void Path::replaceRoot(void *Root, unsigned Size, IdxPair Offsets) {
|
||||
assert(!path.empty() && "Can't replace missing root");
|
||||
path.front() = Entry(Root, Size, Offsets.first);
|
||||
path.insert(path.begin() + 1, Entry(subtree(0), Offsets.second));
|
||||
}
|
||||
|
||||
NodeRef Path::getLeftSibling(unsigned Level) const {
|
||||
// The root has no siblings.
|
||||
if (Level == 0)
|
||||
return NodeRef();
|
||||
|
||||
// Go up the tree until we can go left.
|
||||
unsigned l = Level - 1;
|
||||
while (l && path[l].offset == 0)
|
||||
--l;
|
||||
|
||||
// We can't go left.
|
||||
if (path[l].offset == 0)
|
||||
return NodeRef();
|
||||
|
||||
// NR is the subtree containing our left sibling.
|
||||
NodeRef NR = path[l].subtree(path[l].offset - 1);
|
||||
|
||||
// Keep right all the way down.
|
||||
for (++l; l != Level; ++l)
|
||||
NR = NR.subtree(NR.size() - 1);
|
||||
return NR;
|
||||
}
|
||||
|
||||
void Path::moveLeft(unsigned Level) {
|
||||
assert(Level != 0 && "Cannot move the root node");
|
||||
|
||||
// Go up the tree until we can go left.
|
||||
unsigned l = 0;
|
||||
if (valid()) {
|
||||
l = Level - 1;
|
||||
while (path[l].offset == 0) {
|
||||
assert(l != 0 && "Cannot move beyond begin()");
|
||||
--l;
|
||||
}
|
||||
} else if (height() < Level)
|
||||
// end() may have created a height=0 path.
|
||||
path.resize(Level + 1, Entry(0, 0, 0));
|
||||
|
||||
// NR is the subtree containing our left sibling.
|
||||
--path[l].offset;
|
||||
NodeRef NR = subtree(l);
|
||||
|
||||
// Get the rightmost node in the subtree.
|
||||
for (++l; l != Level; ++l) {
|
||||
path[l] = Entry(NR, NR.size() - 1);
|
||||
NR = NR.subtree(NR.size() - 1);
|
||||
}
|
||||
path[l] = Entry(NR, NR.size() - 1);
|
||||
}
|
||||
|
||||
NodeRef Path::getRightSibling(unsigned Level) const {
|
||||
// The root has no siblings.
|
||||
if (Level == 0)
|
||||
return NodeRef();
|
||||
|
||||
// Go up the tree until we can go right.
|
||||
unsigned l = Level - 1;
|
||||
while (l && atLastBranch(l))
|
||||
--l;
|
||||
|
||||
// We can't go right.
|
||||
if (atLastBranch(l))
|
||||
return NodeRef();
|
||||
|
||||
// NR is the subtree containing our right sibling.
|
||||
NodeRef NR = path[l].subtree(path[l].offset + 1);
|
||||
|
||||
// Keep left all the way down.
|
||||
for (++l; l != Level; ++l)
|
||||
NR = NR.subtree(0);
|
||||
return NR;
|
||||
}
|
||||
|
||||
void Path::moveRight(unsigned Level) {
|
||||
assert(Level != 0 && "Cannot move the root node");
|
||||
|
||||
// Go up the tree until we can go right.
|
||||
unsigned l = Level - 1;
|
||||
while (l && atLastBranch(l))
|
||||
--l;
|
||||
|
||||
// NR is the subtree containing our right sibling. If we hit end(), we have
|
||||
// offset(0) == node(0).size().
|
||||
if (++path[l].offset == path[l].size)
|
||||
return;
|
||||
NodeRef NR = subtree(l);
|
||||
|
||||
for (++l; l != Level; ++l) {
|
||||
path[l] = Entry(NR, 0);
|
||||
NR = NR.subtree(0);
|
||||
}
|
||||
path[l] = Entry(NR, 0);
|
||||
}
|
||||
|
||||
|
||||
IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity,
|
||||
const unsigned *CurSize, unsigned NewSize[],
|
||||
unsigned Position, bool Grow) {
|
||||
@ -56,5 +157,5 @@ IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity,
|
||||
}
|
||||
|
||||
} // namespace IntervalMapImpl
|
||||
} // namespace llvm
|
||||
} // namespace llvm
|
||||
|
||||
|
Reference in New Issue
Block a user