diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 392e0e9..e47a6d5 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -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(self)); + case Type_Node3: + return getFirstChild(static_cast(self)); + case Type_Node16: + return getFirstChild(static_cast(self)); + case Type_Node48: + return getFirstChild(static_cast(self)); + case Type_Node256: + return getFirstChild(static_cast(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.