Improve next{Physical,Logical} codegen more

This commit is contained in:
2024-10-17 09:52:03 -07:00
parent fd39065498
commit 707b220fbc

View File

@@ -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
Node *getFirstChildExists(Node3 *self) {
assert(self->numChildren > 0);
@@ -1559,36 +1594,45 @@ TaggedNodePointer &getOrCreateChild(TaggedNodePointer &self,
}
Node *nextPhysical(Node *node) {
int index = -1;
for (;;) {
auto nextChild = getChildGeq(node, index + 1);
auto nextChild = getFirstChild(node);
if (nextChild != nullptr) {
return nextChild;
}
index = node->parentsIndex;
for (;;) {
int index = node->parentsIndex;
node = node->parent;
if (node == nullptr) {
return nullptr;
}
auto nextChild = getChildGeq(node, index + 1);
if (nextChild != nullptr) {
return nextChild;
}
}
}
Node *nextLogical(Node *node) {
int index = -1;
for (;;) {
auto nextChild = getChildGeq(node, index + 1);
auto nextChild = getFirstChild(node);
if (nextChild != nullptr) {
for (node = nextChild; !node->entryPresent;
node = getFirstChildExists(node)) {
node = nextChild;
goto downLeftSpine;
}
return node;
}
index = node->parentsIndex;
for (;;) {
int index = node->parentsIndex;
node = node->parent;
if (node == 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.