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:
James Cherry
2025-02-10 17:31:45 -07:00
parent 6a27390dd5
commit 0dfea7dfad
12 changed files with 373 additions and 705 deletions
-275
View File
@@ -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
View File
@@ -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;
-1
View File
@@ -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;
-1
View File
@@ -173,7 +173,6 @@ void
ObjectTable<TYPE>::destroy(TYPE *object)
{
ObjectId object_id = objectId(object);
object->~TYPE();
size_--;
freePush(object, object_id);
}
+4 -1
View File
@@ -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_;