diff --git a/examples/cmake_tracing_c/CMakeLists.txt b/examples/cmake_tracing_c/CMakeLists.txt index 6d605b93b2b..725e5614e0b 100644 --- a/examples/cmake_tracing_c/CMakeLists.txt +++ b/examples/cmake_tracing_c/CMakeLists.txt @@ -35,5 +35,5 @@ target_compile_features(example PUBLIC cxx_std_14) # Add the Verilated circuit to the target verilate(example COVERAGE TRACE INCLUDE_DIRS "../make_tracing_c" - VERILATOR_ARGS -f ../make_tracing_c/input.vc -x-assign fast + VERILATOR_ARGS -f ../make_tracing_c/input.vc -x-assign fast --debug --debugi 9 SOURCES ../make_tracing_c/top.v) diff --git a/examples/cmake_tracing_c/Makefile b/examples/cmake_tracing_c/Makefile index a4f052a9872..54e32303878 100644 --- a/examples/cmake_tracing_c/Makefile +++ b/examples/cmake_tracing_c/Makefile @@ -54,7 +54,7 @@ run: @echo @echo "-- BUILD -------------------" - cmake --build build -j + cmake --build build -j -v @echo @echo "-- RUN ---------------------" diff --git a/src/V3Graph.cpp b/src/V3Graph.cpp index 968e4c2610c..2444a59bd00 100644 --- a/src/V3Graph.cpp +++ b/src/V3Graph.cpp @@ -41,15 +41,19 @@ V3GraphVertex::V3GraphVertex(V3Graph* graphp, const V3GraphVertex& old) , m_color{old.m_color} , m_rank{old.m_rank} { m_userp = nullptr; + UINFO(0, "A" << std::endl); graphp->vertices().linkBack(this); + UINFO(0, "B" << std::endl); } V3GraphVertex::V3GraphVertex(V3Graph* graphp) : m_fanout{0} , m_color{0} , m_rank{0} { + UINFO(0, "C" << std::endl); m_userp = nullptr; graphp->vertices().linkBack(this); + UINFO(0, "D" << std::endl); } void V3GraphVertex::unlinkEdges(V3Graph*) { @@ -147,8 +151,11 @@ void V3GraphEdge::init(V3Graph* /*graphp*/, V3GraphVertex* fromp, V3GraphVertex* m_cutable = cutable; m_userp = nullptr; // Link vertices to this edge + UINFO(0, "E" << std::endl); m_fromp->outEdges().linkBack(this); + UINFO(0, "F" << std::endl); m_top->inEdges().linkBack(this); + UINFO(0, "G" << std::endl); } void V3GraphEdge::relinkFromp(V3GraphVertex* newFromp) { diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 8bf4e41ee7d..e3828332d99 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -165,6 +165,7 @@ class LinkCellsVisitor final : public VNVisitor { m_graph.removeRedundantEdgesMax(&V3GraphEdge::followAlwaysTrue); if (dumpGraphLevel()) m_graph.dumpDotFilePrefixed("linkcells"); m_graph.rank(); + UINFO(0, "EEEEEEEEEEEEE??????????????????????" << std::endl); for (V3GraphVertex& vtx : m_graph.vertices()) { if (const LinkCellsVertex* const vvertexp = vtx.cast()) { // +1 so we leave level 1 for the new wrapper we'll make in a moment @@ -172,6 +173,7 @@ class LinkCellsVisitor final : public VNVisitor { modp->level(vvertexp->rank() + 1); } } + UINFO(0, "!!!!!!!!!!!!!!!EEEEEEEEEEEEE??????????????????????" << std::endl); if (v3Global.opt.topModule() != "" && !m_topVertexp) { v3error("Specified --top-module '" << v3Global.opt.topModule() << "' was not found in design."); diff --git a/src/V3List.h b/src/V3List.h index e77b3d89bc7..c50d2650029 100644 --- a/src/V3List.h +++ b/src/V3List.h @@ -42,6 +42,8 @@ class V3ListLinks final { public: V3ListLinks() = default; ~V3ListLinks() { + std::cout << "func " << __FUNCTION__ << std::endl; + #ifdef VL_DEBUG m_nextp = reinterpret_cast(1); m_prevp = reinterpret_cast(1); @@ -73,11 +75,13 @@ class V3List final { // Given the T_Element, return the Links. The links are always mutable, even in const elements. VL_ATTR_ALWINLINE static V3ListLinks& toLinks(const T_Base* elementp) { + std::cout << "func " << __FUNCTION__ << std::endl; return const_cast(elementp)->*LinksPointer; } VL_ATTR_ALWINLINE static void prefetch(T_Base* elementp, T_Base* fallbackp) { + std::cout << "func " << __FUNCTION__ << std::endl; UDEBUGONLY(UASSERT(fallbackp, "Prefetch fallback pointer must be non nullptr");); // This compiles to a branchless prefetch with cmove, with the address always valid VL_PREFETCH_RW(elementp ? elementp : fallbackp); @@ -101,10 +105,13 @@ class V3List final { VL_ATTR_ALWINLINE SimpleItertatorImpl(T_Base* elementp) - : m_currp{elementp} {} + : m_currp{elementp} { + std::cout << "func " << __FUNCTION__ << std::endl; + } VL_ATTR_ALWINLINE static T_Base* step(T_Base* currp) { + std::cout << "func " << __FUNCTION__ << std::endl; if VL_CONSTEXPR_CXX17 (T_Reverse) { return toLinks(currp).m_prevp; } else { @@ -116,32 +123,46 @@ class V3List final { // Dereference VL_ATTR_ALWINLINE T_IteratorElement& operator*() const { + std::cout << "enter " << __FUNCTION__ << std::endl; UDEBUGONLY(UASSERT(m_currp, "Dereferencing end of list iterator");); prefetch(step(m_currp), m_currp); + std::cout << "exit " << __FUNCTION__ << std::endl; return *static_cast(m_currp); } // Pre increment VL_ATTR_ALWINLINE IteratorType& operator++() { + std::cout << "enter " << __FUNCTION__ << std::endl; UDEBUGONLY(UASSERT(m_currp, "Pre-incrementing end of list iterator");); m_currp = step(m_currp); + std::cout << "exit " << __FUNCTION__ << std::endl; return *this; } // Post increment VL_ATTR_ALWINLINE IteratorType operator++(int) { + std::cout << "enter " << __FUNCTION__ << std::endl; UDEBUGONLY(UASSERT(m_currp, "Post-incrementing end of list iterator");); T_Base* const elementp = m_currp; m_currp = step(m_currp); + std::cout << "exit " << __FUNCTION__ << std::endl; return IteratorType{elementp}; } VL_ATTR_ALWINLINE - bool operator==(const IteratorType& other) const { return m_currp == other.m_currp; } + bool operator==(const IteratorType& other) const { + std::cout << "func " << __FUNCTION__ << std::endl; + return m_currp == other.m_currp; + } VL_ATTR_ALWINLINE - bool operator!=(const IteratorType& other) const { return m_currp != other.m_currp; } + bool operator!=(const IteratorType& other) const { + std::cout << "func " << __FUNCTION__ << std::endl; + return m_currp != other.m_currp; + } // Convert to const iterator VL_ATTR_ALWINLINE operator SimpleItertatorImpl() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return SimpleItertatorImpl{m_currp}; } }; @@ -177,43 +198,62 @@ class V3List final { VL_ATTR_ALWINLINE UnlinkableItertatorImpl(T_Base* elementp) : m_currp{elementp} - , m_nextp{toLinks(m_currp).m_nextp} {} + , m_nextp{toLinks(m_currp).m_nextp} { + std::cout << "func " << __FUNCTION__ << std::endl; + } VL_ATTR_ALWINLINE UnlinkableItertatorImpl(std::nullptr_t) : m_currp{nullptr} - , m_nextp{nullptr} {} + , m_nextp{nullptr} { + std::cout << "func " << __FUNCTION__ << std::endl; + } public: // Dereference - Note this returns a pointer. VL_ATTR_ALWINLINE T_IteratorElement* operator*() const { + std::cout << "enter " << __FUNCTION__ << std::endl; UDEBUGONLY(UASSERT(m_currp, "Dereferencing end of list iterator");); prefetch(m_nextp, m_currp); + std::cout << "exit " << __FUNCTION__ << std::endl; return static_cast(m_currp); } // Pre increment - Keeps hold of current next pointer. VL_ATTR_ALWINLINE IteratorType& operator++() { + std::cout << "enter " << __FUNCTION__ << std::endl; UDEBUGONLY(UASSERT(m_currp, "Pre-incrementing end of list iterator");); m_currp = m_nextp; m_nextp = m_currp ? toLinks(m_currp).m_nextp : nullptr; + std::cout << "exit " << __FUNCTION__ << std::endl; return *this; } VL_ATTR_ALWINLINE - bool operator!=(const IteratorType& other) const { return m_currp != other.m_currp; } + bool operator!=(const IteratorType& other) const { + std::cout << "func " << __FUNCTION__ << std::endl; + return m_currp != other.m_currp; + } }; public: using iterator = UnlinkableItertatorImpl; using const_iterator = UnlinkableItertatorImpl; iterator begin() { // + std::cout << "func " << __FUNCTION__ << std::endl; return m_list.m_headp ? iterator{m_list.m_headp} : end(); } const_iterator begin() const { + std::cout << "func " << __FUNCTION__ << std::endl; return m_list.m_headp ? const_iterator{m_list.m_headp} : end(); } - iterator end() { return iterator{nullptr}; } - const_iterator end() const { return const_iterator{nullptr}; } + iterator end() { + std::cout << "func " << __FUNCTION__ << std::endl; + return iterator{nullptr}; + } + const_iterator end() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return const_iterator{nullptr}; + } }; public: @@ -234,55 +274,108 @@ class V3List final { VL_UNMOVABLE(V3List); // METHDOS - bool empty() const { return !m_headp; } - bool hasSingleElement() const { return m_headp && m_headp == m_lastp; } - bool hasMultipleElements() const { return m_headp && m_headp != m_lastp; } + bool empty() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return !m_headp; + } + bool hasSingleElement() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return m_headp && m_headp == m_lastp; + } + bool hasMultipleElements() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return m_headp && m_headp != m_lastp; + } // These return pointers, as we often want to unlink/delete them, and can also signal empty - T_Element* frontp() { return static_cast(m_headp); } - const T_Element* frontp() const { return static_cast(m_headp); } - T_Element* backp() { return static_cast(m_lastp); } - const T_Element* backp() const { return static_cast(m_lastp); } + T_Element* frontp() { + std::cout << "func " << __FUNCTION__ << std::endl; + return static_cast(m_headp); + } + const T_Element* frontp() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return static_cast(m_headp); + } + T_Element* backp() { + std::cout << "func " << __FUNCTION__ << std::endl; + return static_cast(m_lastp); + } + const T_Element* backp() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return static_cast(m_lastp); + } // Standard iterators. The iterator is only invalidated if the element it points to is // unlinked. Other list operations do not invalidate the itartor. If you want to be able to // unlink the currently iterated element, use 'unlinkable()' below. - iterator begin() { return iterator{m_headp}; } - const_iterator begin() const { return const_iterator{m_headp}; } - iterator end() { return iterator{nullptr}; } - const_iterator end() const { return const_iterator{nullptr}; } - reverse_iterator rbegin() { return reverse_iterator{m_lastp}; } - const_reverse_iterator rbegin() const { return const_reverse_iterator{m_lastp}; } - reverse_iterator rend() { return reverse_iterator{nullptr}; } - const_reverse_iterator rend() const { return const_reverse_iterator{nullptr}; } + iterator begin() { + std::cout << "func " << __FUNCTION__ << std::endl; + return iterator{m_headp}; + } + const_iterator begin() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return const_iterator{m_headp}; + } + iterator end() { + std::cout << "func " << __FUNCTION__ << std::endl; + return iterator{nullptr}; + } + const_iterator end() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return const_iterator{nullptr}; + } + reverse_iterator rbegin() { + std::cout << "func " << __FUNCTION__ << std::endl; + return reverse_iterator{m_lastp}; + } + const_reverse_iterator rbegin() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return const_reverse_iterator{m_lastp}; + } + reverse_iterator rend() { + std::cout << "func " << __FUNCTION__ << std::endl; + return reverse_iterator{nullptr}; + } + const_reverse_iterator rend() const { + std::cout << "func " << __FUNCTION__ << std::endl; + return const_reverse_iterator{nullptr}; + } // Handle to create unlinkable iterators, which allows unlinking the currently iterated // element without invalidating the iterator. However, every other operation that mutates // the list invalidates the unlinkable iterator! - UnlinkableProxy unlinkable() { return UnlinkableProxy{*this}; } + UnlinkableProxy unlinkable() { + std::cout << "func " << __FUNCTION__ << std::endl; + return UnlinkableProxy{*this}; + } // Link (insert) existing element at front void linkFront(const T_Element* elementp) { + std::cout << "enter " << __FUNCTION__ << std::endl; auto& links = toLinks(elementp); links.m_nextp = m_headp; links.m_prevp = nullptr; if (m_headp) toLinks(m_headp).m_prevp = const_cast(elementp); m_headp = const_cast(elementp); if (!m_lastp) m_lastp = m_headp; + std::cout << "exit " << __FUNCTION__ << std::endl; } // Link (insert) existing element at back void linkBack(const T_Element* elementp) { + std::cout << "enter " << __FUNCTION__ << std::endl; auto& links = toLinks(elementp); links.m_nextp = nullptr; links.m_prevp = m_lastp; if (m_lastp) toLinks(m_lastp).m_nextp = const_cast(elementp); m_lastp = const_cast(elementp); if (!m_headp) m_headp = m_lastp; + std::cout << "exit " << __FUNCTION__ << std::endl; } // Unlink (remove) and return element at the front. Returns 'nullptr' if the list is empty. T_Element* unlinkFront() { + std::cout << "enter " << __FUNCTION__ << std::endl; T_Element* const headp = m_headp; if (headp) { m_headp = static_cast(toLinks(m_headp).m_nextp); @@ -292,11 +385,13 @@ class V3List final { m_lastp = nullptr; } } + std::cout << "exit " << __FUNCTION__ << std::endl; return headp; } // Unlink (remove) and return element at the back. Returns 'nullptr' if the list is empty. T_Element* unlinkBack() { + std::cout << "enter " << __FUNCTION__ << std::endl; T_Element* const lastp = m_lastp; if (lastp) { m_lastp = toLinks(m_lastp).m_prevp; @@ -306,11 +401,13 @@ class V3List final { m_headp = nullptr; } } + std::cout << "exit " << __FUNCTION__ << std::endl; return lastp; } // Unlink (remove) the given element. void unlink(const T_Element* elementp) { + std::cout << "enter " << __FUNCTION__ << std::endl; auto& links = toLinks(elementp); if (links.m_nextp) toLinks(links.m_nextp).m_prevp = links.m_prevp; if (links.m_prevp) toLinks(links.m_prevp).m_nextp = links.m_nextp; @@ -318,19 +415,24 @@ class V3List final { if (m_lastp == elementp) m_lastp = links.m_prevp; links.m_prevp = nullptr; links.m_nextp = nullptr; + std::cout << "exit " << __FUNCTION__ << std::endl; } // Swap elements of 2 lists void swap(ListType& other) { + std::cout << "enter " << __FUNCTION__ << std::endl; std::swap(m_headp, other.m_headp); std::swap(m_lastp, other.m_lastp); + std::cout << "exit " << __FUNCTION__ << std::endl; } // Take elements from 'other' and link (insert) them all before the given position. void splice(const_iterator pos, ListType& other) { + std::cout << "enter " << __FUNCTION__ << std::endl; if (empty()) { swap(other); } else if (other.empty()) { + std::cout << "exit " << __FUNCTION__ << std::endl; return; } else { UASSERT(pos == end(), "Sorry, only splicing at the end is implemented at the moment"); @@ -340,12 +442,15 @@ class V3List final { other.m_headp = nullptr; other.m_lastp = nullptr; } + std::cout << "exit " << __FUNCTION__ << std::endl; } // This is O(n)! size_t size() const { + std::cout << "enter " << __FUNCTION__ << std::endl; size_t result = 0; for (auto it = begin(); it != end(); ++it) ++result; + std::cout << "exit " << __FUNCTION__ << std::endl; return result; } };