// OpenSTA, Static Timing Analyzer // Copyright (c) 2025, 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 "Iterator.hh" #include "Set.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. typedef Vector LevelQueue; // 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(); bool empty() const; // Enqueue a vertex to search from. void enqueue(Vertex *vertex); // Enqueue vertices adjacent to a vertex. void enqueueAdjacentVertices(Vertex *vertex); void enqueueAdjacentVertices(Vertex *vertex, SearchPred *search_pred); void enqueueAdjacentVertices(Vertex *vertex, Level to_level); virtual void enqueueAdjacentVertices(Vertex *vertex, SearchPred *search_pred, Level to_level) = 0; 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; virtual bool hasNext(); bool hasNext(Level to_level); virtual Vertex *next(); // 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(); 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(); virtual void enqueueAdjacentVertices(Vertex *vertex, SearchPred *search_pred, Level to_level); using BfsIterator::enqueueAdjacentVertices; protected: virtual bool levelLessOrEqual(Level level1, Level level2) const; virtual bool levelLess(Level level1, Level level2) const; virtual void incrLevel(Level &level) const; }; class BfsBkwdIterator : public BfsIterator { public: BfsBkwdIterator(BfsIndex bfs_index, SearchPred *search_pred, StaState *sta); virtual ~BfsBkwdIterator(); virtual void enqueueAdjacentVertices(Vertex *vertex, SearchPred *search_pred, Level to_level); using BfsIterator::enqueueAdjacentVertices; protected: virtual bool levelLessOrEqual(Level level1, Level level2) const; virtual bool levelLess(Level level1, Level level2) const; virtual void incrLevel(Level &level) const; }; } // namespace