Merge pull request #261 from eder-matheus/master

This commit is contained in:
Vitor Bandeira 2025-01-31 13:14:56 -03:00 committed by GitHub
commit 218aa0dd30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 44 additions and 58 deletions

View File

@ -38,7 +38,7 @@ project(STA VERSION 2.6.0
option(CUDD_DIR "CUDD BDD package directory") option(CUDD_DIR "CUDD BDD package directory")
option(USE_TCL_READLINE "Use TCL readline package" ON) option(USE_TCL_READLINE "Use TCL readline package" ON)
option(USE_SANITIZE "Compile with santize address enabled") option(ENABLE_TSAN "Compile with thread santizer enabled" OFF)
# Turn on to debug compiler args. # Turn on to debug compiler args.
set(CMAKE_VERBOSE_MAKEFILE OFF) set(CMAKE_VERBOSE_MAKEFILE OFF)
@ -550,8 +550,8 @@ endif()
# common to gcc/clang # common to gcc/clang
set(CXX_FLAGS -Wall -Wextra -pedantic -Wcast-qual -Wredundant-decls -Wformat-security) set(CXX_FLAGS -Wall -Wextra -pedantic -Wcast-qual -Wredundant-decls -Wformat-security)
if(USE_SANITIZE) if(ENABLE_TSAN)
message(STATUS "Sanitize: ${USE_SANITIZE}") message(STATUS "Thread sanitizer: ${ENABLE_TSAN}")
set(CXX_FLAGS "${CXX_FLAGS};-fsanitize=thread") set(CXX_FLAGS "${CXX_FLAGS};-fsanitize=thread")
set(CMAKE_EXE_LINKER_FLAGS "-fsanitize=thread") set(CMAKE_EXE_LINKER_FLAGS "-fsanitize=thread")
endif() endif()

View File

@ -685,13 +685,15 @@ GraphDelayCalc::findDriverDelays(Vertex *drvr_vertex,
LoadPinIndexMap &load_pin_index_map) LoadPinIndexMap &load_pin_index_map)
{ {
MultiDrvrNet *multi_drvr = findMultiDrvrNet(drvr_vertex); MultiDrvrNet *multi_drvr = findMultiDrvrNet(drvr_vertex);
if (multi_drvr == nullptr if (multi_drvr == nullptr) {
|| (multi_drvr
&& (!multi_drvr->parallelGates(network_)
|| drvr_vertex == multi_drvr->dcalcDrvr()))) {
initLoadSlews(drvr_vertex); initLoadSlews(drvr_vertex);
findDriverDelays1(drvr_vertex, multi_drvr, arc_delay_calc, load_pin_index_map); findDriverDelays1(drvr_vertex, multi_drvr, arc_delay_calc, load_pin_index_map);
} }
else if (drvr_vertex == multi_drvr->dcalcDrvr()) {
initLoadSlews(drvr_vertex);
for (Vertex *drvr : multi_drvr->drvrs())
findDriverDelays1(drvr, multi_drvr, arc_delay_calc, load_pin_index_map);
}
arc_delay_calc_->finishDrvrPin(); arc_delay_calc_->finishDrvrPin();
} }
@ -825,16 +827,7 @@ GraphDelayCalc::findDriverDelays1(Vertex *drvr_vertex,
LoadPinIndexMap &load_pin_index_map) LoadPinIndexMap &load_pin_index_map)
{ {
initSlew(drvr_vertex); initSlew(drvr_vertex);
if (multi_drvr initWireDelays(drvr_vertex);
&& multi_drvr->parallelGates(network_)) {
// Only init on the trigger driver.
if (drvr_vertex == multi_drvr->dcalcDrvr()) {
for (auto vertex : multi_drvr->drvrs())
initWireDelays(vertex);
}
}
else
initWireDelays(drvr_vertex);
bool delay_changed = false; bool delay_changed = false;
array<bool, RiseFall::index_count> delay_exists = {false, false}; array<bool, RiseFall::index_count> delay_exists = {false, false};
VertexInEdgeIterator edge_iter(drvr_vertex, graph_); VertexInEdgeIterator edge_iter(drvr_vertex, graph_);

View File

@ -61,12 +61,20 @@ instead, write this:
fatal ("virtual memory exhausted"); fatal ("virtual memory exhausted");
Use braces around if/for bodies that are more than one line. Do not use braces around if/for that are one line.
IE,
if (pred) if (pred)
for (int i = 0; i < len; i++) { // this body should be in {}'s bar = 1;
else
bar = 3;
Use braces around if/for bodies that are more than one line.
if (pred) {
for (int i = 0; i < len; i++) {
... ...
} }
}
Add a default clause to all switches calling switchCaseNotHandled: Add a default clause to all switches calling switchCaseNotHandled:

View File

@ -26,6 +26,7 @@
#include <cstring> // memcpy #include <cstring> // memcpy
#include <vector> #include <vector>
#include <atomic>
#include "ObjectId.hh" #include "ObjectId.hh"
#include "Error.hh" #include "Error.hh"
@ -77,8 +78,7 @@ private:
// Don't use std::vector so growing blocks_ can be thread safe. // Don't use std::vector so growing blocks_ can be thread safe.
size_t blocks_size_; size_t blocks_size_;
size_t blocks_capacity_; size_t blocks_capacity_;
ArrayBlock<TYPE>* *blocks_; std::atomic<ArrayBlock<TYPE>**> blocks_;
ArrayBlock<TYPE>* *prev_blocks_;
// Linked list of free arrays indexed by array size. // Linked list of free arrays indexed by array size.
std::vector<ObjectId> free_list_; std::vector<ObjectId> free_list_;
static constexpr ObjectId idx_mask_ = block_size - 1; static constexpr ObjectId idx_mask_ = block_size - 1;
@ -91,8 +91,7 @@ ArrayTable<TYPE>::ArrayTable() :
free_idx_(object_idx_null), free_idx_(object_idx_null),
blocks_size_(0), blocks_size_(0),
blocks_capacity_(1024), blocks_capacity_(1024),
blocks_(new ArrayBlock<TYPE>*[blocks_capacity_]), blocks_(new ArrayBlock<TYPE>*[blocks_capacity_])
prev_blocks_(nullptr)
{ {
} }
@ -101,7 +100,6 @@ ArrayTable<TYPE>::~ArrayTable()
{ {
deleteBlocks(); deleteBlocks();
delete [] blocks_; delete [] blocks_;
delete [] prev_blocks_;
} }
template <class TYPE> template <class TYPE>
@ -173,10 +171,6 @@ ArrayTable<TYPE>::pushBlock(ArrayBlock<TYPE> *block)
size_t new_capacity = blocks_capacity_ * 1.5; size_t new_capacity = blocks_capacity_ * 1.5;
ArrayBlock<TYPE>** new_blocks = new ArrayBlock<TYPE>*[new_capacity]; ArrayBlock<TYPE>** new_blocks = new ArrayBlock<TYPE>*[new_capacity];
memcpy(new_blocks, blocks_, blocks_capacity_ * sizeof(ArrayBlock<TYPE>*)); memcpy(new_blocks, blocks_, blocks_capacity_ * sizeof(ArrayBlock<TYPE>*));
if (prev_blocks_)
delete [] prev_blocks_;
// Preserve block array for other threads to reference.
prev_blocks_ = blocks_;
blocks_ = new_blocks; blocks_ = new_blocks;
blocks_capacity_ = new_capacity; blocks_capacity_ = new_capacity;
} }

View File

@ -25,6 +25,7 @@
#pragma once #pragma once
#include <mutex> #include <mutex>
#include <atomic>
#include "Iterator.hh" #include "Iterator.hh"
#include "Map.hh" #include "Map.hh"
@ -365,14 +366,12 @@ protected:
EdgeId in_edges_; // Edges to this vertex. EdgeId in_edges_; // Edges to this vertex.
EdgeId out_edges_; // Edges from this vertex. EdgeId out_edges_; // Edges from this vertex.
// 32 bits // 28 bits
unsigned int tag_group_index_:tag_group_index_bits; // 24 unsigned int tag_group_index_:tag_group_index_bits; // 24
// Each bit corresponds to a different BFS queue. unsigned int slew_annotated_:slew_annotated_bits; // 4
unsigned int bfs_in_queue_:int(BfsIndex::bits); // 4
unsigned int slew_annotated_:slew_annotated_bits;
// 32 bits // 32 bits
unsigned int level_:Graph::vertex_level_bits; unsigned int level_:Graph::vertex_level_bits; // 24
// Levelization search state. // Levelization search state.
// LevelColor gcc barfs if this is dcl'd. // LevelColor gcc barfs if this is dcl'd.
unsigned color_:2; unsigned color_:2;
@ -383,6 +382,9 @@ protected:
bool is_bidirect_drvr_:1; bool is_bidirect_drvr_:1;
bool is_reg_clk_:1; bool is_reg_clk_:1;
// Each bit corresponds to a different BFS queue.
std::atomic<uint8_t> bfs_in_queue_; // 4
// 15 bits // 15 bits
bool is_disabled_constraint_:1; bool is_disabled_constraint_:1;
bool is_gated_clk_enable_:1; bool is_gated_clk_enable_:1;
@ -394,7 +396,7 @@ protected:
bool has_downstream_clk_pin_:1; bool has_downstream_clk_pin_:1;
bool crpr_path_pruning_disabled_:1; bool crpr_path_pruning_disabled_:1;
bool requireds_pruned_:1; bool requireds_pruned_:1;
unsigned object_idx_:VertexTable::idx_bits; unsigned object_idx_:VertexTable::idx_bits; // 7
private: private:
friend class Graph; friend class Graph;

View File

@ -25,6 +25,7 @@
#pragma once #pragma once
#include <mutex> #include <mutex>
#include <atomic>
#include "MinMax.hh" #include "MinMax.hh"
#include "RiseFallMinMax.hh" #include "RiseFallMinMax.hh"
@ -644,7 +645,7 @@ protected:
bool leakage_power_exists_; bool leakage_power_exists_;
LibertyPgPortMap pg_port_map_; LibertyPgPortMap pg_port_map_;
bool has_internal_ports_; bool has_internal_ports_;
bool have_voltage_waveforms_; std::atomic<bool> have_voltage_waveforms_;
std::mutex waveform_lock_; std::mutex waveform_lock_;
const char *footprint_; const char *footprint_;
const char *user_function_class_; const char *user_function_class_;

View File

@ -25,6 +25,7 @@
#pragma once #pragma once
#include <mutex> #include <mutex>
#include <atomic>
#include "MinMax.hh" #include "MinMax.hh"
#include "UnorderedSet.hh" #include "UnorderedSet.hh"
@ -591,15 +592,13 @@ protected:
TagSet *tag_set_; TagSet *tag_set_;
// Entries in tags_ may be missing where previous filter tags were deleted. // Entries in tags_ may be missing where previous filter tags were deleted.
TagIndex tag_capacity_; TagIndex tag_capacity_;
Tag **tags_; std::atomic<Tag **> tags_;
Tag **tags_prev_;
TagIndex tag_next_; TagIndex tag_next_;
// Holes in tags_ left by deleting filter tags. // Holes in tags_ left by deleting filter tags.
std::vector<TagIndex> tag_free_indices_; std::vector<TagIndex> tag_free_indices_;
std::mutex tag_lock_; std::mutex tag_lock_;
TagGroupSet *tag_group_set_; TagGroupSet *tag_group_set_;
TagGroup **tag_groups_; std::atomic<TagGroup **> tag_groups_;
TagGroup **tag_groups_prev_;
TagGroupIndex tag_group_next_; TagGroupIndex tag_group_next_;
// Holes in tag_groups_ left by deleting filter tag groups. // Holes in tag_groups_ left by deleting filter tag groups.
std::vector<TagIndex> tag_group_free_indices_; std::vector<TagIndex> tag_group_free_indices_;

View File

@ -240,15 +240,13 @@ Search::init(StaState *sta)
worst_slacks_ = nullptr; worst_slacks_ = nullptr;
arrival_iter_ = new BfsFwdIterator(BfsIndex::arrival, nullptr, sta); arrival_iter_ = new BfsFwdIterator(BfsIndex::arrival, nullptr, sta);
required_iter_ = new BfsBkwdIterator(BfsIndex::required, search_adj_, sta); required_iter_ = new BfsBkwdIterator(BfsIndex::required, search_adj_, sta);
tag_capacity_ = 127; tag_capacity_ = 128;
tag_set_ = new TagSet(tag_capacity_); tag_set_ = new TagSet(tag_capacity_);
clk_info_set_ = new ClkInfoSet(ClkInfoLess(sta)); clk_info_set_ = new ClkInfoSet(ClkInfoLess(sta));
tag_next_ = 0; tag_next_ = 0;
tags_ = new Tag*[tag_capacity_]; tags_ = new Tag*[tag_capacity_];
tags_prev_ = nullptr; tag_group_capacity_ = tag_capacity_;
tag_group_capacity_ = 127;
tag_groups_ = new TagGroup*[tag_group_capacity_]; tag_groups_ = new TagGroup*[tag_group_capacity_];
tag_groups_prev_ = nullptr;
tag_group_next_ = 0; tag_group_next_ = 0;
tag_group_set_ = new TagGroupSet(tag_group_capacity_); tag_group_set_ = new TagGroupSet(tag_group_capacity_);
pending_latch_outputs_ = new VertexSet(graph_); pending_latch_outputs_ = new VertexSet(graph_);
@ -280,9 +278,7 @@ Search::~Search()
delete tag_set_; delete tag_set_;
delete clk_info_set_; delete clk_info_set_;
delete [] tags_; delete [] tags_;
delete [] tags_prev_;
delete [] tag_groups_; delete [] tag_groups_;
delete [] tag_groups_prev_;
delete tag_group_set_; delete tag_group_set_;
delete search_adj_; delete search_adj_;
delete eval_pred_; delete eval_pred_;
@ -589,13 +585,14 @@ Search::deleteFilterTags()
void void
Search::deleteFilterClkInfos() Search::deleteFilterClkInfos()
{ {
ClkInfoSet::Iterator clk_info_iter(clk_info_set_); for (auto itr = clk_info_set_->cbegin(); itr != clk_info_set_->cend(); ) {
while (clk_info_iter.hasNext()) { ClkInfo *clk_info = *itr;
ClkInfo *clk_info = clk_info_iter.next();
if (clk_info->refsFilter(this)) { if (clk_info->refsFilter(this)) {
clk_info_set_->erase(clk_info); itr = clk_info_set_->erase(itr);
delete clk_info; delete clk_info;
} }
else
itr++;
} }
} }
@ -2669,15 +2666,11 @@ Search::findTagGroup(TagGroupBldr *tag_bldr)
// If tag_groups_ needs to grow make the new array and copy the // If tag_groups_ needs to grow make the new array and copy the
// contents into it before updating tags_groups_ so that other threads // contents into it before updating tags_groups_ so that other threads
// can use Search::tagGroup(TagGroupIndex) without returning gubbish. // can use Search::tagGroup(TagGroupIndex) without returning gubbish.
// std::vector doesn't seem to follow this protocol so multi-thread
// search fails occasionally if a vector is used for tag_groups_.
if (tag_group_next_ == tag_group_capacity_) { if (tag_group_next_ == tag_group_capacity_) {
TagGroupIndex tag_capacity = tag_group_capacity_ * 2; TagGroupIndex tag_capacity = tag_group_capacity_ * 2;
TagGroup **tag_groups = new TagGroup*[tag_capacity]; TagGroup **tag_groups = new TagGroup*[tag_capacity];
memcpy(tag_groups, tag_groups_, memcpy(tag_groups, tag_groups_,
tag_group_capacity_ * sizeof(TagGroup*)); tag_group_capacity_ * sizeof(TagGroup*));
delete [] tag_groups_prev_;
tag_groups_prev_ = tag_groups_;
tag_groups_ = tag_groups; tag_groups_ = tag_groups;
tag_group_capacity_ = tag_capacity; tag_group_capacity_ = tag_capacity;
tag_group_set_->reserve(tag_capacity); tag_group_set_->reserve(tag_capacity);
@ -2910,14 +2903,10 @@ Search::findTag(const RiseFall *rf,
// If tags_ needs to grow make the new array and copy the // If tags_ needs to grow make the new array and copy the
// contents into it before updating tags_ so that other threads // contents into it before updating tags_ so that other threads
// can use Search::tag(TagIndex) without returning gubbish. // can use Search::tag(TagIndex) without returning gubbish.
// std::vector doesn't seem to follow this protocol so multi-thread
// search fails occasionally if a vector is used for tags_.
if (tag_next_ == tag_capacity_) { if (tag_next_ == tag_capacity_) {
TagIndex tag_capacity = tag_capacity_ * 2; TagIndex tag_capacity = tag_capacity_ * 2;
Tag **tags = new Tag*[tag_capacity]; Tag **tags = new Tag*[tag_capacity];
memcpy(tags, tags_, tag_capacity_ * sizeof(Tag*)); memcpy(tags, tags_, tag_capacity_ * sizeof(Tag*));
delete [] tags_prev_;
tags_prev_ = tags_;
tags_ = tags; tags_ = tags;
tag_capacity_ = tag_capacity; tag_capacity_ = tag_capacity;
tag_set_->reserve(tag_capacity); tag_set_->reserve(tag_capacity);