Fix levelize crash when vertices enqueued in arrival/required iterators
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
3e6bbf46d5
commit
b32eed9a84
|
|
@ -359,6 +359,7 @@ public:
|
|||
void reportArrivals(Vertex *vertex) const;
|
||||
Slack wnsSlack(Vertex *vertex,
|
||||
PathAPIndex path_ap_index);
|
||||
void levelsChangedBefore();
|
||||
void levelChangedBefore(Vertex *vertex);
|
||||
void seedInputArrival(const Pin *pin,
|
||||
Vertex *vertex,
|
||||
|
|
|
|||
|
|
@ -122,6 +122,8 @@ Levelize::levelize()
|
|||
Stats stats(debug_, report_);
|
||||
debugPrint(debug_, "levelize", 1, "levelize");
|
||||
clear();
|
||||
if (observer_)
|
||||
observer_->levelsChangedBefore();
|
||||
|
||||
VertexIterator vertex_iter(graph_);
|
||||
while (vertex_iter.hasNext()) {
|
||||
|
|
@ -545,6 +547,19 @@ Levelize::ensureLatchLevels()
|
|||
latch_d_to_q_edges_.clear();
|
||||
}
|
||||
|
||||
void
|
||||
Levelize::setLevel(Vertex *vertex,
|
||||
Level level)
|
||||
{
|
||||
debugPrint(debug_, "levelize", 2, "set level %s %d",
|
||||
vertex->to_string(this).c_str(),
|
||||
level);
|
||||
vertex->setLevel(level);
|
||||
max_level_ = max(level, max_level_);
|
||||
if (level >= Graph::vertex_level_max)
|
||||
criticalError(616, "maximum logic level exceeded");
|
||||
}
|
||||
|
||||
void
|
||||
Levelize::invalid()
|
||||
{
|
||||
|
|
@ -597,6 +612,8 @@ Levelize::deleteEdgeBefore(Edge *edge)
|
|||
{
|
||||
if (levelized_
|
||||
&& loop_edges_.hasKey(edge)) {
|
||||
debugPrint(debug_, "levelize", 2, "delete loop edge %s",
|
||||
edge->to_string(this).c_str());
|
||||
disabled_loop_edges_.erase(edge);
|
||||
// Relevelize if a loop edge is removed. Incremental levelization
|
||||
// fails because the DFS path will be missing.
|
||||
|
|
@ -621,7 +638,7 @@ Levelize::relevelize()
|
|||
vertex->to_string(this).c_str());
|
||||
if (search_pred_.searchFrom(vertex)) {
|
||||
if (isRoot(vertex)) {
|
||||
setLevel(vertex, 0);
|
||||
setLevelIncr(vertex, 0);
|
||||
roots_->insert(vertex);
|
||||
}
|
||||
VertexSet visited(graph_);
|
||||
|
|
@ -645,7 +662,7 @@ Levelize::visit(Vertex *vertex,
|
|||
EdgeSeq &path)
|
||||
{
|
||||
Pin *from_pin = vertex->pin();
|
||||
setLevel(vertex, level);
|
||||
setLevelIncr(vertex, level);
|
||||
level += level_space;
|
||||
visited.insert(vertex);
|
||||
path_vertices.insert(vertex);
|
||||
|
|
@ -691,8 +708,8 @@ Levelize::isDisabledLoop(Edge *edge) const
|
|||
}
|
||||
|
||||
void
|
||||
Levelize::setLevel(Vertex *vertex,
|
||||
Level level)
|
||||
Levelize::setLevelIncr(Vertex *vertex,
|
||||
Level level)
|
||||
{
|
||||
debugPrint(debug_, "levelize", 2, "set level %s %d",
|
||||
vertex->to_string(this).c_str(),
|
||||
|
|
@ -704,7 +721,7 @@ Levelize::setLevel(Vertex *vertex,
|
|||
}
|
||||
max_level_ = max(level, max_level_);
|
||||
if (level >= Graph::vertex_level_max)
|
||||
criticalError(616, "maximum logic level exceeded");
|
||||
criticalError(617, "maximum logic level exceeded");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ protected:
|
|||
EdgeSeq &path);
|
||||
void setLevel(Vertex *vertex,
|
||||
Level level);
|
||||
void setLevelIncr(Vertex *vertex,
|
||||
Level level);
|
||||
void clearLoopEdges();
|
||||
void deleteLoops();
|
||||
void reportPath(EdgeSeq &path) const;
|
||||
|
|
@ -135,6 +137,7 @@ class LevelizeObserver
|
|||
public:
|
||||
LevelizeObserver() {}
|
||||
virtual ~LevelizeObserver() {}
|
||||
virtual void levelsChangedBefore() = 0;
|
||||
virtual void levelChangedBefore(Vertex *vertex) = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -795,14 +795,30 @@ Search::arrivalInvalid(Vertex *vertex)
|
|||
}
|
||||
}
|
||||
|
||||
// Move any pending arrival/requireds to invalid before relevelization.
|
||||
void
|
||||
Search::levelsChangedBefore()
|
||||
{
|
||||
if (arrivals_exist_) {
|
||||
while (arrival_iter_->hasNext()) {
|
||||
Vertex *vertex = arrival_iter_->next();
|
||||
arrivalInvalid(vertex);
|
||||
}
|
||||
while (required_iter_->hasNext()) {
|
||||
Vertex *vertex = required_iter_->next();
|
||||
requiredInvalid(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Search::levelChangedBefore(Vertex *vertex)
|
||||
{
|
||||
if (arrivals_exist_) {
|
||||
arrival_iter_->remove(vertex);
|
||||
required_iter_->remove(vertex);
|
||||
search_->arrivalInvalid(vertex);
|
||||
search_->requiredInvalid(vertex);
|
||||
arrivalInvalid(vertex);
|
||||
requiredInvalid(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -210,7 +210,8 @@ class StaLevelizeObserver : public LevelizeObserver
|
|||
{
|
||||
public:
|
||||
StaLevelizeObserver(Search *search);
|
||||
virtual void levelChangedBefore(Vertex *vertex);
|
||||
void levelsChangedBefore() override;
|
||||
void levelChangedBefore(Vertex *vertex) override;
|
||||
|
||||
private:
|
||||
Search *search_;
|
||||
|
|
@ -221,6 +222,12 @@ StaLevelizeObserver::StaLevelizeObserver(Search *search) :
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
StaLevelizeObserver::levelsChangedBefore()
|
||||
{
|
||||
search_->levelsChangedBefore();
|
||||
}
|
||||
|
||||
void
|
||||
StaLevelizeObserver::levelChangedBefore(Vertex *vertex)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue