mirror of
https://github.com/The-OpenROAD-Project/OpenSTA.git
synced 2026-09-03 08:25:52 +02:00
thread safety
commit 98fa3639bd0e07f4e315578b50266972bbb7ac7d Author: James Cherry <[email protected]> Date: Sat Feb 8 14:17:29 2025 -0800 Edge::setArcDelayAnnotated Signed-off-by: James Cherry <[email protected]> commit d4628351d788c68ed948751374adee1bba6ca6ea Author: James Cherry <[email protected]> Date: Sat Feb 8 09:27:33 2025 -0800 leaks Signed-off-by: James Cherry <[email protected]> commit cee843b81df89c0f7bc51a76a34422009f49b046 Author: James Cherry <[email protected]> Date: Fri Feb 7 10:22:00 2025 -0800 arcDelayAnnotated Signed-off-by: James Cherry <[email protected]> commit 2a080cb4a3425e9b0a98d90315d23b87c755ebaa Author: James Cherry <[email protected]> Date: Fri Feb 7 09:34:16 2025 -0800 leak Signed-off-by: James Cherry <[email protected]> commit 6b85cebe290cb9f1c7fabe06fcec42dd7c060550 Author: James Cherry <[email protected]> Date: Thu Feb 6 16:12:42 2025 -0800 readme Signed-off-by: James Cherry <[email protected]> commit 01d4481280b08e98cc311dc37a3eeb1cfc928902 Author: James Cherry <[email protected]> Date: Thu Feb 6 16:12:33 2025 -0800 comment Signed-off-by: James Cherry <[email protected]> commit e7c62097f948450ed46c0ac577bd3636cf5be625 Author: James Cherry <[email protected]> Date: Thu Feb 6 16:12:19 2025 -0800 Search no virtuals Signed-off-by: James Cherry <[email protected]> commit 761212fc0a593d47422dc7716b7e28f593647a64 Author: James Cherry <[email protected]> Date: Thu Feb 6 15:13:36 2025 -0800 leak Signed-off-by: James Cherry <[email protected]> commit dd64f685c7fe2b3e85e3194008fae67a23650110 Author: James Cherry <[email protected]> Date: Thu Feb 6 12:31:38 2025 -0800 Graph::removeDelayAnnotated Signed-off-by: James Cherry <[email protected]> commit a1b79b09178ba8bdf0ec9486d84fcff68c2a1f2e Author: James Cherry <[email protected]> Date: Thu Feb 6 12:19:32 2025 -0800 Edge::arc_annotated_delays_ Signed-off-by: James Cherry <[email protected]> commit 6b8b44ebd1e3a483ccfaa08f08c5fa8b60c72f90 Author: James Cherry <[email protected]> Date: Thu Feb 6 08:48:49 2025 -0800 leak Signed-off-by: James Cherry <[email protected]> commit ee939bf4015fe3d78860b3e615ec7defa395b2bf Author: James Cherry <[email protected]> Date: Wed Feb 5 18:14:04 2025 -0800 pass fast regressions Signed-off-by: James Cherry <[email protected]> commit f25b505d8507046638dbb30772d721547b3f8941 Author: James Cherry <[email protected]> Date: Wed Feb 5 15:54:39 2025 -0800 pass all but 1 regression Signed-off-by: James Cherry <[email protected]> commit acd3abf0512f5ecbe83025eb5facfa5a594ca9fa Author: James Cherry <[email protected]> Date: Wed Feb 5 12:23:02 2025 -0800 rm ArrayTable compiles Signed-off-by: James Cherry <[email protected]> commit 1a65f9da1814b8664062fe7ecf684acc42ee6933 Author: James Cherry <[email protected]> Date: Tue Feb 4 16:26:34 2025 -0800 keep prev tag arrays until search is finsihed Signed-off-by: James Cherry <[email protected]> Signed-off-by: James Cherry <[email protected]>
This commit is contained in:
@@ -1,275 +0,0 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
// 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 <cstring> // memcpy
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
|
||||
#include "ObjectId.hh"
|
||||
#include "Error.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
template <class TYPE>
|
||||
class ArrayBlock;
|
||||
|
||||
// Array tables allocate arrays of objects in blocks and use 32 bit IDs to
|
||||
// reference the array. Paging performance is improved by allocating
|
||||
// blocks instead of individual arrays, and object sizes are reduced
|
||||
// by using 32 bit references instead of 64 bit pointers.
|
||||
// They are similar to ObjectTables but do not support delete/destroy or
|
||||
// reclaiming deleted arrays.
|
||||
|
||||
template <class TYPE>
|
||||
class ArrayTable
|
||||
{
|
||||
public:
|
||||
ArrayTable();
|
||||
~ArrayTable();
|
||||
void make(uint32_t count,
|
||||
TYPE *&array,
|
||||
ObjectId &id);
|
||||
void destroy(ObjectId id,
|
||||
uint32_t count);
|
||||
// Grow as necessary and return pointer for id.
|
||||
TYPE *ensureId(ObjectId id);
|
||||
TYPE *pointer(ObjectId id) const;
|
||||
TYPE &ref(ObjectId id) const;
|
||||
size_t size() const { return size_; }
|
||||
void clear();
|
||||
|
||||
static constexpr int idx_bits = 7;
|
||||
static constexpr int block_size = (1 << idx_bits);
|
||||
static constexpr int block_id_max = 1 << (object_id_bits - idx_bits);
|
||||
|
||||
private:
|
||||
ArrayBlock<TYPE> *makeBlock(uint32_t size);
|
||||
void pushBlock(ArrayBlock<TYPE> *block);
|
||||
void deleteBlocks();
|
||||
|
||||
size_t size_;
|
||||
// Block index of free block (blocks_[size - 1]).
|
||||
BlockIdx free_block_idx_;
|
||||
// Index of next free object in free_block_idx_.
|
||||
ObjectIdx free_idx_;
|
||||
// Don't use std::vector so growing blocks_ can be thread safe.
|
||||
size_t blocks_size_;
|
||||
size_t blocks_capacity_;
|
||||
std::atomic<ArrayBlock<TYPE>**> blocks_;
|
||||
// Linked list of free arrays indexed by array size.
|
||||
std::vector<ObjectId> free_list_;
|
||||
static constexpr ObjectId idx_mask_ = block_size - 1;
|
||||
};
|
||||
|
||||
template <class TYPE>
|
||||
ArrayTable<TYPE>::ArrayTable() :
|
||||
size_(0),
|
||||
free_block_idx_(block_idx_null),
|
||||
free_idx_(object_idx_null),
|
||||
blocks_size_(0),
|
||||
blocks_capacity_(1024),
|
||||
blocks_(new ArrayBlock<TYPE>*[blocks_capacity_])
|
||||
{
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
ArrayTable<TYPE>::~ArrayTable()
|
||||
{
|
||||
deleteBlocks();
|
||||
delete [] blocks_;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
void
|
||||
ArrayTable<TYPE>::deleteBlocks()
|
||||
{
|
||||
for (size_t i = 0; i < blocks_size_; i++)
|
||||
delete blocks_[i];
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
void
|
||||
ArrayTable<TYPE>::make(uint32_t count,
|
||||
TYPE *&array,
|
||||
ObjectId &id)
|
||||
{
|
||||
// Check the free list for a previously destroyed array with the right size.
|
||||
if (count < free_list_.size()
|
||||
&& free_list_[count] != object_id_null) {
|
||||
id = free_list_[count];
|
||||
array = pointer(id);
|
||||
|
||||
ObjectId *head = reinterpret_cast<ObjectId*>(array);
|
||||
free_list_[count] = *head;
|
||||
}
|
||||
else {
|
||||
ArrayBlock<TYPE> *block = blocks_size_ ? blocks_[free_block_idx_] : nullptr;
|
||||
if ((free_idx_ == object_idx_null
|
||||
&& free_block_idx_ == block_idx_null)
|
||||
|| free_idx_ + count >= block->size()) {
|
||||
uint32_t size = block_size;
|
||||
if (blocks_size_ == 0
|
||||
// First block starts at idx 1.
|
||||
&& count > block_size - 1)
|
||||
size = count + 1;
|
||||
else if (count > block_size)
|
||||
size = count;
|
||||
block = makeBlock(size);
|
||||
}
|
||||
// makeId(free_block_idx_, idx_bits)
|
||||
id = (free_block_idx_ << idx_bits) + free_idx_;
|
||||
array = block->pointer(free_idx_);
|
||||
free_idx_ += count;
|
||||
}
|
||||
size_ += count;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
ArrayBlock<TYPE> *
|
||||
ArrayTable<TYPE>::makeBlock(uint32_t size)
|
||||
{
|
||||
BlockIdx block_idx = blocks_size_;
|
||||
ArrayBlock<TYPE> *block = new ArrayBlock<TYPE>(size);
|
||||
pushBlock(block);
|
||||
free_block_idx_ = block_idx;
|
||||
// ObjectId zero is reserved for object_id_null.
|
||||
free_idx_ = (block_idx > 0) ? 0 : 1;
|
||||
return block;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
void
|
||||
ArrayTable<TYPE>::pushBlock(ArrayBlock<TYPE> *block)
|
||||
{
|
||||
blocks_[blocks_size_++] = block;
|
||||
if (blocks_size_ >= block_id_max)
|
||||
criticalError(223, "max array table block count exceeded.");
|
||||
if (blocks_size_ == blocks_capacity_) {
|
||||
size_t new_capacity = blocks_capacity_ * 1.5;
|
||||
ArrayBlock<TYPE>** new_blocks = new ArrayBlock<TYPE>*[new_capacity];
|
||||
memcpy(new_blocks, blocks_, blocks_capacity_ * sizeof(ArrayBlock<TYPE>*));
|
||||
blocks_ = new_blocks;
|
||||
blocks_capacity_ = new_capacity;
|
||||
}
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
void
|
||||
ArrayTable<TYPE>::destroy(ObjectId id,
|
||||
uint32_t count)
|
||||
{
|
||||
if (count >= free_list_.size())
|
||||
free_list_.resize(count + 1);
|
||||
TYPE *array = pointer(id);
|
||||
// Prepend id to the free list.
|
||||
ObjectId *head = reinterpret_cast<ObjectId*>(array);
|
||||
*head = free_list_[count];
|
||||
free_list_[count] = id;
|
||||
size_ -= count;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
TYPE *
|
||||
ArrayTable<TYPE>::pointer(ObjectId id) const
|
||||
{
|
||||
if (id == object_id_null)
|
||||
return nullptr;
|
||||
else {
|
||||
BlockIdx blk_idx = id >> idx_bits;
|
||||
ObjectIdx obj_idx = id & idx_mask_;
|
||||
return blocks_[blk_idx]->pointer(obj_idx);
|
||||
}
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
TYPE *
|
||||
ArrayTable<TYPE>::ensureId(ObjectId id)
|
||||
{
|
||||
BlockIdx blk_idx = id >> idx_bits;
|
||||
ObjectIdx obj_idx = id & idx_mask_;
|
||||
// Make enough blocks for blk_idx to be valid.
|
||||
for (BlockIdx i = blocks_size_; i <= blk_idx; i++) {
|
||||
ArrayBlock<TYPE> *block = new ArrayBlock<TYPE>(block_size);
|
||||
pushBlock(block);
|
||||
}
|
||||
return blocks_[blk_idx]->pointer(obj_idx);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
TYPE &
|
||||
ArrayTable<TYPE>::ref(ObjectId id) const
|
||||
{
|
||||
if (id == object_id_null)
|
||||
criticalError(222, "null ObjectId reference is undefined.");
|
||||
|
||||
BlockIdx blk_idx = id >> idx_bits;
|
||||
ObjectIdx obj_idx = id & idx_mask_;
|
||||
return blocks_[blk_idx]->ref(obj_idx);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
void
|
||||
ArrayTable<TYPE>::clear()
|
||||
{
|
||||
deleteBlocks();
|
||||
blocks_size_ = 0;
|
||||
size_ = 0;
|
||||
free_block_idx_ = block_idx_null;
|
||||
free_idx_ = object_idx_null;
|
||||
free_list_.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class TYPE>
|
||||
class ArrayBlock
|
||||
{
|
||||
public:
|
||||
ArrayBlock(uint32_t size);
|
||||
~ArrayBlock();
|
||||
uint32_t size() const { return size_; }
|
||||
TYPE &ref(ObjectIdx idx) { return objects_[idx]; }
|
||||
TYPE *pointer(ObjectIdx idx) { return &objects_[idx]; }
|
||||
|
||||
private:
|
||||
uint32_t size_;
|
||||
TYPE *objects_;
|
||||
};
|
||||
|
||||
template <class TYPE>
|
||||
ArrayBlock<TYPE>::ArrayBlock(uint32_t size) :
|
||||
size_(size),
|
||||
objects_(new TYPE[size])
|
||||
{
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
ArrayBlock<TYPE>::~ArrayBlock()
|
||||
{
|
||||
delete [] objects_;
|
||||
}
|
||||
|
||||
} // Namespace
|
||||
+96
-108
@@ -31,7 +31,6 @@
|
||||
#include "Map.hh"
|
||||
#include "Vector.hh"
|
||||
#include "ObjectTable.hh"
|
||||
#include "ArrayTable.hh"
|
||||
#include "LibertyClass.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "Delay.hh"
|
||||
@@ -47,25 +46,16 @@ class Sdc;
|
||||
|
||||
enum class LevelColor { white, gray, black };
|
||||
|
||||
typedef ArrayTable<Delay> DelayTable;
|
||||
typedef ObjectTable<Vertex> VertexTable;
|
||||
typedef ObjectTable<Edge> EdgeTable;
|
||||
typedef ArrayTable<Arrival> ArrivalsTable;
|
||||
typedef ArrayTable<Required> RequiredsTable;
|
||||
typedef ArrayTable<PathVertexRep> PrevPathsTable;
|
||||
typedef Map<const Pin*, Vertex*> PinVertexMap;
|
||||
typedef Iterator<Edge*> VertexEdgeIterator;
|
||||
typedef Map<const Pin*, float*, PinIdLess> PeriodCheckAnnotations;
|
||||
typedef Vector<DelayTable*> DelayTableSeq;
|
||||
typedef ObjectId EdgeId;
|
||||
typedef ObjectId ArrivalId;
|
||||
typedef ObjectId PrevPathId;
|
||||
|
||||
static constexpr EdgeId edge_id_null = object_id_null;
|
||||
static constexpr ObjectIdx edge_idx_null = object_id_null;
|
||||
static constexpr ObjectIdx vertex_idx_null = object_id_null;
|
||||
static constexpr ObjectIdx arrival_null = object_id_null;
|
||||
static constexpr ObjectIdx prev_path_null = object_id_null;
|
||||
|
||||
// The graph acts as a BUILDER for the graph vertices and edges.
|
||||
class Graph : public StaState
|
||||
@@ -78,17 +68,17 @@ public:
|
||||
// ap_count is the dcalc analysis point count.
|
||||
Graph(StaState *sta,
|
||||
int slew_rf_count,
|
||||
bool have_arc_delays,
|
||||
DcalcAPIndex ap_count);
|
||||
void makeGraph();
|
||||
virtual ~Graph();
|
||||
~Graph();
|
||||
|
||||
// Number of arc delays and slews from sdf or delay calculation.
|
||||
virtual void setDelayCount(DcalcAPIndex ap_count);
|
||||
void setDelayCount(DcalcAPIndex ap_count);
|
||||
size_t slewCount();
|
||||
|
||||
// Vertex functions.
|
||||
// Bidirect pins have two vertices.
|
||||
virtual Vertex *vertex(VertexId vertex_id) const;
|
||||
Vertex *vertex(VertexId vertex_id) const;
|
||||
VertexId id(const Vertex *vertex) const;
|
||||
void makePinVertices(Pin *pin);
|
||||
void makePinVertices(Pin *pin,
|
||||
@@ -103,56 +93,49 @@ public:
|
||||
Vertex *pinDrvrVertex(const Pin *pin) const;
|
||||
// Load vertex for bidirects.
|
||||
Vertex *pinLoadVertex(const Pin *pin) const;
|
||||
virtual void deleteVertex(Vertex *vertex);
|
||||
void deleteVertex(Vertex *vertex);
|
||||
bool hasFaninOne(Vertex *vertex) const;
|
||||
VertexId vertexCount() { return vertices_->size(); }
|
||||
Arrival *makeArrivals(Vertex *vertex,
|
||||
uint32_t count);
|
||||
Arrival *arrivals(Vertex *vertex);
|
||||
void deleteArrivals(Vertex *vertex,
|
||||
uint32_t count);
|
||||
Arrival *arrivals(const Vertex *vertex) const;
|
||||
void deleteArrivals(Vertex *vertex);
|
||||
Required *makeRequireds(Vertex *vertex,
|
||||
uint32_t count);
|
||||
Required *requireds(Vertex *vertex);
|
||||
void deleteRequireds(Vertex *vertex,
|
||||
uint32_t count);
|
||||
Required *requireds(const Vertex *vertex) const;
|
||||
void deleteRequireds(Vertex *vertex);
|
||||
PathVertexRep *makePrevPaths(Vertex *vertex,
|
||||
uint32_t count);
|
||||
PathVertexRep *prevPaths(Vertex *vertex) const;
|
||||
void deletePrevPaths(Vertex *vertex,
|
||||
uint32_t count);
|
||||
// Private to Search::deletePaths().
|
||||
void deletePaths();
|
||||
PathVertexRep *prevPaths(const Vertex *vertex) const;
|
||||
void deletePrevPaths(Vertex *vertex);
|
||||
// Private to Search::deletePaths(Vertex).
|
||||
void deletePaths(Vertex *vertex,
|
||||
uint32_t count);
|
||||
void deletePaths(Vertex *vertex);
|
||||
|
||||
// Reported slew are the same as those in the liberty tables.
|
||||
// reported_slews = measured_slews / slew_derate_from_library
|
||||
// Measured slews are between slew_lower_threshold and slew_upper_threshold.
|
||||
virtual const Slew &slew(const Vertex *vertex,
|
||||
const RiseFall *rf,
|
||||
DcalcAPIndex ap_index);
|
||||
virtual void setSlew(Vertex *vertex,
|
||||
const RiseFall *rf,
|
||||
DcalcAPIndex ap_index,
|
||||
const Slew &slew);
|
||||
SlewSeq slews(Vertex *vertex);
|
||||
const Slew &slew(const Vertex *vertex,
|
||||
const RiseFall *rf,
|
||||
DcalcAPIndex ap_index);
|
||||
void setSlew(Vertex *vertex,
|
||||
const RiseFall *rf,
|
||||
DcalcAPIndex ap_index,
|
||||
const Slew &slew);
|
||||
|
||||
// Edge functions.
|
||||
virtual Edge *edge(EdgeId edge_index) const;
|
||||
Edge *edge(EdgeId edge_index) const;
|
||||
EdgeId id(const Edge *edge) const;
|
||||
virtual Edge *makeEdge(Vertex *from,
|
||||
Vertex *to,
|
||||
TimingArcSet *arc_set);
|
||||
virtual void makeWireEdge(const Pin *from_pin,
|
||||
const Pin *to_pin);
|
||||
Edge *makeEdge(Vertex *from,
|
||||
Vertex *to,
|
||||
TimingArcSet *arc_set);
|
||||
void makeWireEdge(const Pin *from_pin,
|
||||
const Pin *to_pin);
|
||||
void makePinInstanceEdges(const Pin *pin);
|
||||
void makeInstanceEdges(const Instance *inst);
|
||||
void makeWireEdgesToPin(const Pin *to_pin);
|
||||
void makeWireEdgesThruPin(const Pin *hpin);
|
||||
virtual void makeWireEdgesFromPin(const Pin *drvr_pin);
|
||||
virtual void deleteEdge(Edge *edge);
|
||||
void makeWireEdgesFromPin(const Pin *drvr_pin);
|
||||
void deleteEdge(Edge *edge);
|
||||
// Find the edge and timing arc on a gate between in_pin and drvr_pin.
|
||||
void gateEdgeArc(const Pin *in_pin,
|
||||
const RiseFall *in_rf,
|
||||
@@ -162,21 +145,21 @@ public:
|
||||
Edge *&edge,
|
||||
const TimingArc *&arc) const;
|
||||
|
||||
virtual ArcDelay arcDelay(const Edge *edge,
|
||||
const TimingArc *arc,
|
||||
DcalcAPIndex ap_index) const;
|
||||
virtual void setArcDelay(Edge *edge,
|
||||
const TimingArc *arc,
|
||||
DcalcAPIndex ap_index,
|
||||
ArcDelay delay);
|
||||
ArcDelay arcDelay(const Edge *edge,
|
||||
const TimingArc *arc,
|
||||
DcalcAPIndex ap_index) const;
|
||||
void setArcDelay(Edge *edge,
|
||||
const TimingArc *arc,
|
||||
DcalcAPIndex ap_index,
|
||||
ArcDelay delay);
|
||||
// Alias for arcDelays using library wire arcs.
|
||||
virtual const ArcDelay &wireArcDelay(const Edge *edge,
|
||||
const RiseFall *rf,
|
||||
DcalcAPIndex ap_index);
|
||||
virtual void setWireArcDelay(Edge *edge,
|
||||
const RiseFall *rf,
|
||||
DcalcAPIndex ap_index,
|
||||
const ArcDelay &delay);
|
||||
const ArcDelay &wireArcDelay(const Edge *edge,
|
||||
const RiseFall *rf,
|
||||
DcalcAPIndex ap_index);
|
||||
void setWireArcDelay(Edge *edge,
|
||||
const RiseFall *rf,
|
||||
DcalcAPIndex ap_index,
|
||||
const ArcDelay &delay);
|
||||
// Is timing arc delay annotated.
|
||||
bool arcDelayAnnotated(const Edge *edge,
|
||||
const TimingArc *arc,
|
||||
@@ -185,7 +168,7 @@ public:
|
||||
const TimingArc *arc,
|
||||
DcalcAPIndex ap_index,
|
||||
bool annotated);
|
||||
bool wireDelayAnnotated(Edge *edge,
|
||||
bool wireDelayAnnotated(const Edge *edge,
|
||||
const RiseFall *rf,
|
||||
DcalcAPIndex ap_index) const;
|
||||
void setWireDelayAnnotated(Edge *edge,
|
||||
@@ -194,8 +177,6 @@ public:
|
||||
bool annotated);
|
||||
// True if any edge arc is annotated.
|
||||
bool delayAnnotated(Edge *edge);
|
||||
int edgeCount() { return edges_->size(); }
|
||||
virtual int arcCount() { return arc_count_; }
|
||||
|
||||
void minPulseWidthArc(Vertex *vertex,
|
||||
const RiseFall *hi_low,
|
||||
@@ -211,6 +192,7 @@ public:
|
||||
void setPeriodCheckAnnotation(const Pin *pin,
|
||||
DcalcAPIndex ap_index,
|
||||
float period);
|
||||
|
||||
// Remove all delay and slew annotations.
|
||||
void removeDelaySlewAnnotations();
|
||||
VertexSet *regClkVertices() { return reg_clk_vertices_; }
|
||||
@@ -223,29 +205,27 @@ protected:
|
||||
Vertex *makeVertex(Pin *pin,
|
||||
bool is_bidirect_drvr,
|
||||
bool is_reg_clk);
|
||||
virtual void makeEdgeArcDelays(Edge *edge);
|
||||
void makeEdgeArcDelays(Edge *edge);
|
||||
void makePinVertices(const Instance *inst);
|
||||
void makeWireEdgesFromPin(const Pin *drvr_pin,
|
||||
PinSet &visited_drvrs);
|
||||
bool isIsolatedNet(PinSeq &drvrs,
|
||||
PinSeq &loads) const;
|
||||
void makeWireEdges();
|
||||
virtual void makeInstDrvrWireEdges(const Instance *inst,
|
||||
PinSet &visited_drvrs);
|
||||
virtual void makePortInstanceEdges(const Instance *inst,
|
||||
LibertyCell *cell,
|
||||
LibertyPort *from_to_port);
|
||||
void makeInstDrvrWireEdges(const Instance *inst,
|
||||
PinSet &visited_drvrs);
|
||||
void makePortInstanceEdges(const Instance *inst,
|
||||
LibertyCell *cell,
|
||||
LibertyPort *from_to_port);
|
||||
void removePeriodCheckAnnotations();
|
||||
void makeSlewTables(DcalcAPIndex count);
|
||||
void deleteSlewTables();
|
||||
void makeVertexSlews(Vertex *vertex);
|
||||
void makeArcDelayTables(DcalcAPIndex ap_count);
|
||||
void deleteArcDelayTables();
|
||||
void deleteInEdge(Vertex *vertex,
|
||||
Edge *edge);
|
||||
void deleteOutEdge(Vertex *vertex,
|
||||
Edge *edge);
|
||||
void removeDelays();
|
||||
void initSlews();
|
||||
void initSlews(Vertex *vertex);
|
||||
void initArcDelays(Edge *edge);
|
||||
void removeDelayAnnotated(Edge *edge);
|
||||
|
||||
VertexTable *vertices_;
|
||||
@@ -255,20 +235,8 @@ protected:
|
||||
// driver/source (top level input, instance pin output) vertex
|
||||
// in pin_bidirect_drvr_vertex_map
|
||||
PinVertexMap pin_bidirect_drvr_vertex_map_;
|
||||
int arc_count_;
|
||||
ArrivalsTable arrivals_;
|
||||
std::mutex arrivals_lock_;
|
||||
RequiredsTable requireds_;
|
||||
std::mutex requireds_lock_;
|
||||
PrevPathsTable prev_paths_;
|
||||
std::mutex prev_paths_lock_;
|
||||
Vector<bool> arc_delay_annotated_;
|
||||
int slew_rf_count_;
|
||||
bool have_arc_delays_;
|
||||
DcalcAPIndex ap_count_;
|
||||
DelayTableSeq slew_tables_; // [ap_index][tr_index][vertex_id]
|
||||
VertexId slew_count_;
|
||||
DelayTableSeq arc_delays_; // [ap_index][edge_arc_index]
|
||||
// Sdf period check annotations.
|
||||
PeriodCheckAnnotations *period_check_annotations_;
|
||||
// Register/latch clock vertices to search from.
|
||||
@@ -286,6 +254,7 @@ class Vertex
|
||||
{
|
||||
public:
|
||||
Vertex();
|
||||
~Vertex();
|
||||
Pin *pin() const { return pin_; }
|
||||
// Pin path with load/driver suffix for bidirects.
|
||||
const char *name(const Network *network) const;
|
||||
@@ -298,11 +267,12 @@ public:
|
||||
bool hasFanout() const;
|
||||
LevelColor color() const { return static_cast<LevelColor>(color_); }
|
||||
void setColor(LevelColor color);
|
||||
ArrivalId arrivals() { return arrivals_; }
|
||||
ArrivalId requireds() { return requireds_; }
|
||||
bool hasRequireds() const { return requireds_ != arrival_null; }
|
||||
PrevPathId prevPaths() const { return prev_paths_; }
|
||||
void setPrevPaths(PrevPathId id);
|
||||
Slew *slews() { return slews_; }
|
||||
const Slew *slews() const { return slews_; }
|
||||
Arrival *arrivals() const { return arrivals_; }
|
||||
Arrival *requireds() const { return requireds_; }
|
||||
PathVertexRep *prevPaths() const { return prev_paths_; }
|
||||
void setPrevPaths(PathVertexRep *prev_paths);
|
||||
TagGroupIndex tagGroupIndex() const;
|
||||
void setTagGroupIndex(TagGroupIndex tag_index);
|
||||
// Slew is annotated by sdc set_annotated_transition cmd.
|
||||
@@ -341,6 +311,7 @@ public:
|
||||
bool isRegClk() const { return is_reg_clk_; }
|
||||
bool crprPathPruningDisabled() const { return crpr_path_pruning_disabled_;}
|
||||
void setCrprPathPruningDisabled(bool disabled);
|
||||
bool hasRequireds() const { return requireds_ != nullptr; }
|
||||
bool requiredsPruned() const { return requireds_pruned_; }
|
||||
void setRequiredsPruned(bool pruned);
|
||||
|
||||
@@ -354,22 +325,30 @@ protected:
|
||||
void init(Pin *pin,
|
||||
bool is_bidirect_drvr,
|
||||
bool is_reg_clk);
|
||||
void setArrivals(ArrivalId id);
|
||||
void setRequireds(ArrivalId id);
|
||||
void clear();
|
||||
void setArrivals(Arrival *arrivals);
|
||||
void setRequireds(Required *requireds);
|
||||
void setSlews(Slew *slews);
|
||||
|
||||
Pin *pin_;
|
||||
ArrivalId arrivals_;
|
||||
ArrivalId requireds_;
|
||||
PrevPathId prev_paths_;
|
||||
EdgeId in_edges_; // Edges to this vertex.
|
||||
EdgeId out_edges_; // Edges from this vertex.
|
||||
|
||||
// 28 bits
|
||||
unsigned int tag_group_index_:tag_group_index_bits; // 24
|
||||
unsigned int slew_annotated_:slew_annotated_bits; // 4
|
||||
// Delay calc
|
||||
Slew *slews_;
|
||||
// Search
|
||||
Arrival *arrivals_;
|
||||
Arrival *requireds_;
|
||||
PathVertexRep *prev_paths_;
|
||||
|
||||
// These fields are written by multiple threads, so they
|
||||
// cannot share the same word as the following bit fields.
|
||||
uint32_t tag_group_index_;
|
||||
// Each bit corresponds to a different BFS queue.
|
||||
std::atomic<uint8_t> bfs_in_queue_; // 4
|
||||
|
||||
// 32 bits
|
||||
unsigned int level_:Graph::vertex_level_bits; // 24
|
||||
unsigned int slew_annotated_:slew_annotated_bits; // 4
|
||||
// Levelization search state.
|
||||
// LevelColor gcc barfs if this is dcl'd.
|
||||
unsigned color_:2;
|
||||
@@ -379,11 +358,6 @@ protected:
|
||||
// This flag distinguishes the driver and load vertices.
|
||||
bool is_bidirect_drvr_:1;
|
||||
bool is_reg_clk_:1;
|
||||
|
||||
// Each bit corresponds to a different BFS queue.
|
||||
std::atomic<uint8_t> bfs_in_queue_; // 4
|
||||
|
||||
// 15 bits
|
||||
bool is_disabled_constraint_:1;
|
||||
bool is_gated_clk_enable_:1;
|
||||
// Constrained by timing check edge.
|
||||
@@ -409,6 +383,7 @@ class Edge
|
||||
{
|
||||
public:
|
||||
Edge();
|
||||
~Edge();
|
||||
Vertex *to(const Graph *graph) const { return graph->vertex(to_); }
|
||||
Vertex *from(const Graph *graph) const { return graph->vertex(from_); }
|
||||
TimingRole *role() const;
|
||||
@@ -416,9 +391,9 @@ public:
|
||||
TimingSense sense() const;
|
||||
TimingArcSet *timingArcSet() const { return arc_set_; }
|
||||
void setTimingArcSet(TimingArcSet *set);
|
||||
ArcId arcDelays() const { return arc_delays_; }
|
||||
void setArcDelays(ArcId arc_delays);
|
||||
bool delayAnnotationIsIncremental() const;
|
||||
ArcDelay *arcDelays() const { return arc_delays_; }
|
||||
void setArcDelays(ArcDelay *arc_delays);
|
||||
bool delay_Annotation_Is_Incremental() const {return delay_annotation_is_incremental_;};
|
||||
void setDelayAnnotationIsIncremental(bool is_incr);
|
||||
// Edge is disabled by set_disable_timing constraint.
|
||||
bool isDisabledConstraint() const;
|
||||
@@ -438,6 +413,7 @@ public:
|
||||
void setIsBidirectInstPath(bool is_bidir);
|
||||
bool isBidirectNetPath() const { return is_bidirect_net_path_; }
|
||||
void setIsBidirectNetPath(bool is_bidir);
|
||||
void removeDelayAnnotated();
|
||||
|
||||
// ObjectTable interface.
|
||||
ObjectIdx objectIdx() const { return object_idx_; }
|
||||
@@ -447,6 +423,14 @@ protected:
|
||||
void init(VertexId from,
|
||||
VertexId to,
|
||||
TimingArcSet *arc_set);
|
||||
void clear();
|
||||
bool arcDelayAnnotated(const TimingArc *arc,
|
||||
DcalcAPIndex ap_index,
|
||||
DcalcAPIndex ap_count) const;
|
||||
void setArcDelayAnnotated(const TimingArc *arc,
|
||||
DcalcAPIndex ap_index,
|
||||
DcalcAPIndex ap_count,
|
||||
bool annotated);
|
||||
|
||||
TimingArcSet *arc_set_;
|
||||
VertexId from_;
|
||||
@@ -454,8 +438,12 @@ protected:
|
||||
EdgeId vertex_in_link_; // Vertex in edges list.
|
||||
EdgeId vertex_out_next_; // Vertex out edges doubly linked list.
|
||||
EdgeId vertex_out_prev_;
|
||||
ArcId arc_delays_;
|
||||
// 16 bits
|
||||
ArcDelay *arc_delays_;
|
||||
union {
|
||||
uintptr_t bits_;
|
||||
vector<bool> *seq_;
|
||||
} arc_delay_annotated_;
|
||||
bool arc_delay_annotated_is_bits_:1;
|
||||
bool delay_annotation_is_incremental_:1;
|
||||
bool is_bidirect_inst_path_:1;
|
||||
bool is_bidirect_net_path_:1;
|
||||
|
||||
@@ -49,7 +49,6 @@ class VertexSet;
|
||||
|
||||
typedef ObjectId VertexId;
|
||||
typedef ObjectId EdgeId;
|
||||
typedef ObjectId ArcId;
|
||||
typedef Vector<Vertex*> VertexSeq;
|
||||
typedef Vector<Edge*> EdgeSeq;
|
||||
typedef Set<Edge*> EdgeSet;
|
||||
|
||||
@@ -173,7 +173,6 @@ void
|
||||
ObjectTable<TYPE>::destroy(TYPE *object)
|
||||
{
|
||||
ObjectId object_id = objectId(object);
|
||||
object->~TYPE();
|
||||
size_--;
|
||||
freePush(object, object_id);
|
||||
}
|
||||
|
||||
@@ -383,7 +383,8 @@ protected:
|
||||
bool report_max,
|
||||
DcalcAnalysisPt *dcalc_ap_min,
|
||||
DcalcAnalysisPt *dcalc_ap_max);
|
||||
virtual void deleteTags();
|
||||
void deleteTags();
|
||||
void deleteTagsPrev();
|
||||
void seedInvalidArrivals();
|
||||
void seedArrivals();
|
||||
void findClockVertices(VertexSet &vertices);
|
||||
@@ -593,12 +594,14 @@ protected:
|
||||
// Entries in tags_ may be missing where previous filter tags were deleted.
|
||||
TagIndex tag_capacity_;
|
||||
std::atomic<Tag **> tags_;
|
||||
vector<Tag **> tags_prev_;
|
||||
TagIndex tag_next_;
|
||||
// Holes in tags_ left by deleting filter tags.
|
||||
std::vector<TagIndex> tag_free_indices_;
|
||||
std::mutex tag_lock_;
|
||||
TagGroupSet *tag_group_set_;
|
||||
std::atomic<TagGroup **> tag_groups_;
|
||||
vector<TagGroup **> tag_groups_prev_;
|
||||
TagGroupIndex tag_group_next_;
|
||||
// Holes in tag_groups_ left by deleting filter tag groups.
|
||||
std::vector<TagIndex> tag_group_free_indices_;
|
||||
|
||||
Reference in New Issue
Block a user