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