From 4b3df0a4260a77922739b4bd27d381ffee05d81d Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Thu, 1 Aug 2024 10:46:08 -0700 Subject: [PATCH] Avoid dispatching on node type twice in nextPhysical --- ConflictSet.cpp | 117 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 94 insertions(+), 23 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 51780e6..0c20680 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -844,28 +844,41 @@ template int getNodeIndex(NodeT *self, uint8_t index) { #endif } +// Precondition - an entry for index must exist in the node +Node *&getChildExists(Node3 *self, uint8_t index) { + return self->children[getNodeIndex(self, index)]; +} +// Precondition - an entry for index must exist in the node +Node *&getChildExists(Node16 *self, uint8_t index) { + return self->children[getNodeIndex(self, index)]; +} +// Precondition - an entry for index must exist in the node +Node *&getChildExists(Node48 *self, uint8_t index) { + assert(self->bitSet.test(index)); + return self->children[self->index[index]]; +} +// Precondition - an entry for index must exist in the node +Node *&getChildExists(Node256 *self, uint8_t index) { + assert(self->bitSet.test(index)); + return self->children[index]; +} + // Precondition - an entry for index must exist in the node Node *&getChildExists(Node *self, uint8_t index) { switch (self->getType()) { case Type_Node0: // GCOVR_EXCL_LINE __builtin_unreachable(); // GCOVR_EXCL_LINE case Type_Node3: { - auto *self3 = static_cast(self); - return self3->children[getNodeIndex(self3, index)]; + return getChildExists(static_cast(self), index); } case Type_Node16: { - auto *self16 = static_cast(self); - return self16->children[getNodeIndex(self16, index)]; + return getChildExists(static_cast(self), index); } case Type_Node48: { - auto *self48 = static_cast(self); - assert(self48->bitSet.test(index)); - return self48->children[self48->index[index]]; + return getChildExists(static_cast(self), index); } case Type_Node256: { - auto *self256 = static_cast(self); - assert(self256->bitSet.test(index)); - return self256->children[index]; + return getChildExists(static_cast(self), index); } default: // GCOVR_EXCL_LINE __builtin_unreachable(); // GCOVR_EXCL_LINE @@ -979,24 +992,47 @@ template int getChildGeqSimd(NodeT *self, int child) { #endif } -int getChildGeq(Node *self, int child) { +int getChildGeq(Node0 *, int child) { if (child > 255) { return -1; } + return -1; +} +int getChildGeq(Node3 *self, int child) { + if (child > 255) { + return -1; + } + return getChildGeqSimd(self, child); +} +int getChildGeq(Node16 *self, int child) { + if (child > 255) { + return -1; + } + return getChildGeqSimd(self, child); +} +int getChildGeq(Node48 *self, int child) { + if (child > 255) { + return -1; + } + return self->bitSet.firstSetGeq(child); +} +int getChildGeq(Node256 *self, int child) { + static_assert(offsetof(Node48, bitSet) == offsetof(Node256, bitSet)); + return getChildGeq(reinterpret_cast(self), child); +} + +int getChildGeq(Node *self, int child) { switch (self->getType()) { case Type_Node0: - return -1; + return getChildGeq(static_cast(self), child); case Type_Node3: - return getChildGeqSimd(static_cast(self), child); + return getChildGeq(static_cast(self), child); case Type_Node16: - return getChildGeqSimd(static_cast(self), child); + return getChildGeq(static_cast(self), child); case Type_Node48: - [[fallthrough]]; - case Type_Node256: { - static_assert(offsetof(Node48, bitSet) == offsetof(Node256, bitSet)); - auto *self48 = static_cast(self); - return self48->bitSet.firstSetGeq(child); - } + return getChildGeq(static_cast(self), child); + case Type_Node256: + return getChildGeq(static_cast(self), child); default: // GCOVR_EXCL_LINE __builtin_unreachable(); // GCOVR_EXCL_LINE } @@ -1201,9 +1237,44 @@ Node *&getOrCreateChild(Node *&self, uint8_t index, WriteContext *tls) { Node *nextPhysical(Node *node) { int index = -1; for (;;) { - auto nextChild = getChildGeq(node, index + 1); - if (nextChild >= 0) { - return getChildExists(node, nextChild); + switch (node->getType()) { + case Type_Node0: { + auto *n = static_cast(node); + auto nextChild = getChildGeq(n, index + 1); + if (nextChild >= 0) { + return getChildExists(n, nextChild); + } + } break; + case Type_Node3: { + auto *n = static_cast(node); + auto nextChild = getChildGeq(n, index + 1); + if (nextChild >= 0) { + return getChildExists(n, nextChild); + } + } break; + case Type_Node16: { + auto *n = static_cast(node); + auto nextChild = getChildGeq(n, index + 1); + if (nextChild >= 0) { + return getChildExists(n, nextChild); + } + } break; + case Type_Node48: { + auto *n = static_cast(node); + auto nextChild = getChildGeq(n, index + 1); + if (nextChild >= 0) { + return getChildExists(n, nextChild); + } + } break; + case Type_Node256: { + auto *n = static_cast(node); + auto nextChild = getChildGeq(n, index + 1); + if (nextChild >= 0) { + return getChildExists(n, nextChild); + } + } break; + default: // GCOVR_EXCL_LINE + __builtin_unreachable(); // GCOVR_EXCL_LINE } index = node->parentsIndex; node = node->parent;