// OpenSTA, Static Timing Analyzer // Copyright (c) 2026, Parallax Software, Inc. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // The origin of this software must not be misrepresented; you must not // claim that you wrote the original software. // // Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // // This notice may not be removed or altered from any source distribution. #pragma once #include #include #include "Iterator.hh" #include "GraphClass.hh" #include "VertexVisitor.hh" #include "StaState.hh" namespace sta { class SearchPred; class BfsFwdIterator; class BfsBkwdIterator; // LevelQueue is a vector of vertex vectors indexed by logic level. using LevelQueue = std::vector; // Abstract base class for forward and backward breadth first search iterators. // Visit all of the vertices at a level before moving to the next. // Use enqueue to seed the search. // Use enqueueAdjacentVertices as a vertex is visited to queue the // fanout vertices filtered by the search predicate. // // Vertices are marked as being in the queue by using a flag on // the vertex indexed by bfs_index. A unique flag is only needed // if the BFS in in use when other BFS's are simultaneously in use. class BfsIterator : public StaState, Iterator { public: virtual ~BfsIterator(); // Make sure that the BFS queue is deep enough for the max logic level. void ensureSize(); // Reset to virgin state. void clear(); [[nodiscard]] bool empty() const; // Enqueue a vertex to search from. void enqueue(Vertex *vertex); // Enqueue vertices adjacent to a vertex. void enqueueAdjacentVertices(Vertex *vertex); virtual void enqueueAdjacentVertices(Vertex *vertex, const Mode *mode); virtual void enqueueAdjacentVertices(Vertex *vertex, SearchPred *search_pred, const Mode *mode) = 0; virtual void enqueueAdjacentVertices(Vertex *vertex, SearchPred *search_pred) = 0; [[nodiscard]] bool inQueue(Vertex *vertex); void checkInQueue(Vertex *vertex); // Notify iterator that vertex will be deleted. void deleteVertexBefore(Vertex *vertex); void remove(Vertex *vertex); void reportEntries() const; bool hasNext() override; bool hasNext(Level to_level); Vertex *next() override; // Apply visitor to all vertices in the queue in level order. // Returns the number of vertices that are visited. virtual int visit(Level to_level, VertexVisitor *visitor); // Apply visitor to all vertices in the queue in level order, // using threads to parallelize the visits. visitor must be thread safe. // Returns the number of vertices that are visited. int visitParallel(Level to_level, VertexVisitor *visitor); protected: BfsIterator(BfsIndex bfs_index, Level level_min, Level level_max, SearchPred *search_pred, StaState *sta); void init(); void deleteEntries(Level level); virtual bool levelLess(Level level1, Level level2) const = 0; virtual bool levelLessOrEqual(Level level1, Level level2) const = 0; virtual void incrLevel(Level &level) const = 0; void findNext(Level to_level); void deleteEntries(); void checkLevel(Vertex *vertex, Level level); BfsIndex bfs_index_; Level level_min_; Level level_max_; SearchPred *search_pred_; LevelQueue queue_; std::mutex queue_lock_; // Min (max) level of queued vertices. Level first_level_; // Max (min) level of queued vertices. Level last_level_; friend class BfsFwdIterator; friend class BfsBkwdIterator; }; class BfsFwdIterator : public BfsIterator { public: BfsFwdIterator(BfsIndex bfs_index, SearchPred *search_pred, StaState *sta); virtual ~BfsFwdIterator(); void enqueueAdjacentVertices(Vertex *vertex, SearchPred *search_pred) override; void enqueueAdjacentVertices(Vertex *vertex, SearchPred *search_pred, const Mode *mode) override; using BfsIterator::enqueueAdjacentVertices; protected: bool levelLessOrEqual(Level level1, Level level2) const override; bool levelLess(Level level1, Level level2) const override; void incrLevel(Level &level) const override; }; class BfsBkwdIterator : public BfsIterator { public: BfsBkwdIterator(BfsIndex bfs_index, SearchPred *search_pred, StaState *sta); virtual ~BfsBkwdIterator(); void enqueueAdjacentVertices(Vertex *vertex, SearchPred *search_pred) override; void enqueueAdjacentVertices(Vertex *vertex, SearchPred *search_pred, const Mode *mode) override; using BfsIterator::enqueueAdjacentVertices; protected: bool levelLessOrEqual(Level level1, Level level2) const override; bool levelLess(Level level1, Level level2) const override; void incrLevel(Level &level) const override; }; } // namespace