Internals: Optimzie unlinking rest of list after head (tail) (#6643)

AstNode::unlinkFrBackWithNext is O(n) if the subject node is not the
head of the list. We sometimes want to unlink the rest of the list
starting at the node after the head (e.g.: in
V3Sched::util::splitCheck), this patch makes that O(1) as well.
This commit is contained in:
Geza Lore 2025-11-05 15:55:30 +00:00 committed by GitHub
parent a35d4a4b4b
commit cb5f038060
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 9 additions and 6 deletions

View File

@ -613,11 +613,14 @@ AstNode* AstNode::unlinkFrBackWithNext(VNRelinker* linkerp) {
backp->m_nextp = nullptr;
// Old list gets truncated
// New list becomes a list upon itself
// Most common case is unlinking a entire operand tree
// (else we'd probably call unlinkFrBack without next)
// We may be in the middle of a list; we have no way to find head or tail!
AstNode* oldtailp = oldp;
while (oldtailp->m_nextp) oldtailp = oldtailp->m_nextp;
// Most common case is unlinking a entire operand tree, or all but the
// head (else we'd probably call unlinkFrBack without next)
AstNode* oldtailp = backp->m_headtailp;
if (!oldtailp) {
// We are in the middle of a list; we have no way to find head or tail in O(1)
oldtailp = oldp;
while (oldtailp->m_nextp) oldtailp = oldtailp->m_nextp;
}
// Create new head/tail of old list
AstNode* const oldheadp = oldtailp->m_headtailp;
oldheadp->m_headtailp = oldp->m_backp;

View File

@ -427,7 +427,7 @@ class AstNode VL_NOT_FINAL {
#endif
AstNodeDType* m_dtypep = nullptr; // Data type of output or assignment (etc)
AstNode* m_headtailp; // When at begin/end of list, the opposite end of the list
AstNode* m_headtailp; // When at begin/end of list, the opposite end of the list, else nullptr
FileLine* m_fileline; // Where it was declared
#ifdef VL_DEBUG
// Only keep track of the edit count in the node in the debug build.