Improve next{Physical,Logical} codegen more
This commit is contained in:
@@ -1281,6 +1281,41 @@ Node *getChildGeq(Node *self, int child) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node *getFirstChild(Node0 *) { return nullptr; }
|
||||||
|
Node *getFirstChild(Node3 *self) {
|
||||||
|
return self->numChildren == 0 ? nullptr : self->children[0];
|
||||||
|
}
|
||||||
|
Node *getFirstChild(Node16 *self) {
|
||||||
|
return self->numChildren == 0 ? nullptr : self->children[0];
|
||||||
|
}
|
||||||
|
Node *getFirstChild(Node48 *self) {
|
||||||
|
int index = self->index[self->bitSet.firstSetGeq(0)];
|
||||||
|
return index < 0 ? nullptr : self->children[index];
|
||||||
|
}
|
||||||
|
Node *getFirstChild(Node256 *self) {
|
||||||
|
return self->children[self->bitSet.firstSetGeq(0)];
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *getFirstChild(Node *self) {
|
||||||
|
// Only require that the node-specific overloads are covered
|
||||||
|
// GCOVR_EXCL_START
|
||||||
|
switch (self->getType()) {
|
||||||
|
case Type_Node0:
|
||||||
|
return getFirstChild(static_cast<Node0 *>(self));
|
||||||
|
case Type_Node3:
|
||||||
|
return getFirstChild(static_cast<Node3 *>(self));
|
||||||
|
case Type_Node16:
|
||||||
|
return getFirstChild(static_cast<Node16 *>(self));
|
||||||
|
case Type_Node48:
|
||||||
|
return getFirstChild(static_cast<Node48 *>(self));
|
||||||
|
case Type_Node256:
|
||||||
|
return getFirstChild(static_cast<Node256 *>(self));
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
// GCOVR_EXCL_STOP
|
||||||
|
}
|
||||||
|
|
||||||
// Precondition: self has a child
|
// Precondition: self has a child
|
||||||
Node *getFirstChildExists(Node3 *self) {
|
Node *getFirstChildExists(Node3 *self) {
|
||||||
assert(self->numChildren > 0);
|
assert(self->numChildren > 0);
|
||||||
@@ -1559,36 +1594,45 @@ TaggedNodePointer &getOrCreateChild(TaggedNodePointer &self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Node *nextPhysical(Node *node) {
|
Node *nextPhysical(Node *node) {
|
||||||
int index = -1;
|
auto nextChild = getFirstChild(node);
|
||||||
|
if (nextChild != nullptr) {
|
||||||
|
return nextChild;
|
||||||
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto nextChild = getChildGeq(node, index + 1);
|
int index = node->parentsIndex;
|
||||||
if (nextChild != nullptr) {
|
|
||||||
return nextChild;
|
|
||||||
}
|
|
||||||
index = node->parentsIndex;
|
|
||||||
node = node->parent;
|
node = node->parent;
|
||||||
if (node == nullptr) {
|
if (node == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
auto nextChild = getChildGeq(node, index + 1);
|
||||||
|
if (nextChild != nullptr) {
|
||||||
|
return nextChild;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *nextLogical(Node *node) {
|
Node *nextLogical(Node *node) {
|
||||||
int index = -1;
|
auto nextChild = getFirstChild(node);
|
||||||
|
if (nextChild != nullptr) {
|
||||||
|
node = nextChild;
|
||||||
|
goto downLeftSpine;
|
||||||
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto nextChild = getChildGeq(node, index + 1);
|
int index = node->parentsIndex;
|
||||||
if (nextChild != nullptr) {
|
|
||||||
for (node = nextChild; !node->entryPresent;
|
|
||||||
node = getFirstChildExists(node)) {
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
index = node->parentsIndex;
|
|
||||||
node = node->parent;
|
node = node->parent;
|
||||||
if (node == nullptr) {
|
if (node == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
auto nextChild = getChildGeq(node, index + 1);
|
||||||
|
if (nextChild != nullptr) {
|
||||||
|
node = nextChild;
|
||||||
|
goto downLeftSpine;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
downLeftSpine:
|
||||||
|
for (; !node->entryPresent; node = getFirstChildExists(node)) {
|
||||||
|
}
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invalidates `self`, replacing it with a node of at least capacity.
|
// Invalidates `self`, replacing it with a node of at least capacity.
|
||||||
|
Reference in New Issue
Block a user