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:
parent
a35d4a4b4b
commit
cb5f038060
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue