mirror of
https://github.com/YosysHQ/yosys
synced 2025-11-13 17:41:17 +00:00
Repack SigSpecs when possible
This commit is contained in:
parent
38d1d071a5
commit
1cf3497d15
2 changed files with 122 additions and 18 deletions
137
kernel/rtlil.cc
137
kernel/rtlil.cc
|
|
@ -4692,6 +4692,39 @@ void RTLIL::SigSpec::unpack()
|
||||||
new (&bits_) std::vector<RTLIL::SigBit>(std::move(bits));
|
new (&bits_) std::vector<RTLIL::SigBit>(std::move(bits));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RTLIL::SigSpec::try_repack()
|
||||||
|
{
|
||||||
|
if (rep_ != BITS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cover("kernel.rtlil.sigspec.convert.try_repack");
|
||||||
|
|
||||||
|
int bits_size = GetSize(bits_);
|
||||||
|
if (bits_size == 0)
|
||||||
|
return;
|
||||||
|
if (bits_[0].is_wire()) {
|
||||||
|
for (int i = 1; i < bits_size; i++)
|
||||||
|
if (bits_[0].wire != bits_[i].wire || bits_[0].offset + i != bits_[i].offset)
|
||||||
|
return;
|
||||||
|
SigChunk chunk(bits_[0].wire, bits_[0].offset, bits_size);
|
||||||
|
bits_.~vector();
|
||||||
|
rep_ = CHUNK;
|
||||||
|
new (&chunk_) SigChunk(std::move(chunk));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<RTLIL::State> bits;
|
||||||
|
bits.reserve(bits_size);
|
||||||
|
bits.push_back(bits_[0].data);
|
||||||
|
for (int i = 1; i < bits_size; i++) {
|
||||||
|
if (bits_[i].is_wire())
|
||||||
|
return;
|
||||||
|
bits.push_back(bits_[i].data);
|
||||||
|
}
|
||||||
|
bits_.~vector();
|
||||||
|
rep_ = CHUNK;
|
||||||
|
new (&chunk_) SigChunk(std::move(bits));
|
||||||
|
}
|
||||||
|
|
||||||
Hasher::hash_t RTLIL::SigSpec::updhash() const
|
Hasher::hash_t RTLIL::SigSpec::updhash() const
|
||||||
{
|
{
|
||||||
cover("kernel.rtlil.sigspec.hash");
|
cover("kernel.rtlil.sigspec.hash");
|
||||||
|
|
@ -4719,6 +4752,7 @@ void RTLIL::SigSpec::sort()
|
||||||
cover("kernel.rtlil.sigspec.sort");
|
cover("kernel.rtlil.sigspec.sort");
|
||||||
std::sort(bits_.begin(), bits_.end());
|
std::sort(bits_.begin(), bits_.end());
|
||||||
hash_.clear();
|
hash_.clear();
|
||||||
|
try_repack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::sort_and_unify()
|
void RTLIL::SigSpec::sort_and_unify()
|
||||||
|
|
@ -4736,6 +4770,7 @@ void RTLIL::SigSpec::sort_and_unify()
|
||||||
|
|
||||||
*this = unique_bits;
|
*this = unique_bits;
|
||||||
hash_.clear();
|
hash_.clear();
|
||||||
|
try_repack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
|
void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
|
||||||
|
|
@ -4759,13 +4794,17 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec
|
||||||
}
|
}
|
||||||
|
|
||||||
int this_size = size();
|
int this_size = size();
|
||||||
|
bool other_modified = false;
|
||||||
for (int j = 0; j < this_size; j++) {
|
for (int j = 0; j < this_size; j++) {
|
||||||
auto it = pattern_to_with.find((*this)[j]);
|
auto it = pattern_to_with.find((*this)[j]);
|
||||||
if (it != pattern_to_with.end()) {
|
if (it != pattern_to_with.end()) {
|
||||||
|
other_modified = true;
|
||||||
(*other)[j] = with[it->second];
|
(*other)[j] = with[it->second];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (other_modified)
|
||||||
|
other->try_repack();
|
||||||
other->check();
|
other->check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4784,12 +4823,17 @@ void RTLIL::SigSpec::replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules, RT
|
||||||
if (rules.empty()) return;
|
if (rules.empty()) return;
|
||||||
|
|
||||||
int this_size = size();
|
int this_size = size();
|
||||||
|
bool other_modified = false;
|
||||||
for (int i = 0; i < this_size; i++) {
|
for (int i = 0; i < this_size; i++) {
|
||||||
auto it = rules.find((*this)[i]);
|
auto it = rules.find((*this)[i]);
|
||||||
if (it != rules.end())
|
if (it != rules.end()) {
|
||||||
|
other_modified = true;
|
||||||
(*other)[i] = it->second;
|
(*other)[i] = it->second;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other_modified)
|
||||||
|
other->try_repack();
|
||||||
other->check();
|
other->check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4808,12 +4852,17 @@ void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules
|
||||||
if (rules.empty()) return;
|
if (rules.empty()) return;
|
||||||
|
|
||||||
int this_size = size();
|
int this_size = size();
|
||||||
|
bool other_modified = false;
|
||||||
for (int i = 0; i < this_size; i++) {
|
for (int i = 0; i < this_size; i++) {
|
||||||
auto it = rules.find((*this)[i]);
|
auto it = rules.find((*this)[i]);
|
||||||
if (it != rules.end())
|
if (it != rules.end()) {
|
||||||
|
other_modified = true;
|
||||||
(*other)[i] = it->second;
|
(*other)[i] = it->second;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other_modified)
|
||||||
|
other->try_repack();
|
||||||
other->check();
|
other->check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4839,9 +4888,10 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe
|
||||||
if (other != NULL) {
|
if (other != NULL) {
|
||||||
log_assert(size() == other->size());
|
log_assert(size() == other->size());
|
||||||
other->unpack();
|
other->unpack();
|
||||||
other->hash_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool modified = false;
|
||||||
|
bool other_modified = false;
|
||||||
for (int i = GetSize(bits_) - 1; i >= 0; i--)
|
for (int i = GetSize(bits_) - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (bits_[i].wire == NULL) continue;
|
if (bits_[i].wire == NULL) continue;
|
||||||
|
|
@ -4850,14 +4900,24 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe
|
||||||
if (bits_[i].wire == pattern_chunk.wire &&
|
if (bits_[i].wire == pattern_chunk.wire &&
|
||||||
bits_[i].offset >= pattern_chunk.offset &&
|
bits_[i].offset >= pattern_chunk.offset &&
|
||||||
bits_[i].offset < pattern_chunk.offset + pattern_chunk.width) {
|
bits_[i].offset < pattern_chunk.offset + pattern_chunk.width) {
|
||||||
|
modified = true;
|
||||||
bits_.erase(bits_.begin() + i);
|
bits_.erase(bits_.begin() + i);
|
||||||
if (other != NULL)
|
if (other != NULL) {
|
||||||
|
other_modified = true;
|
||||||
other->bits_.erase(other->bits_.begin() + i);
|
other->bits_.erase(other->bits_.begin() + i);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hash_.clear();
|
|
||||||
|
|
||||||
|
if (modified) {
|
||||||
|
hash_.clear();
|
||||||
|
try_repack();
|
||||||
|
}
|
||||||
|
if (other_modified) {
|
||||||
|
other->hash_.clear();
|
||||||
|
other->try_repack();
|
||||||
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4884,18 +4944,29 @@ void RTLIL::SigSpec::remove2(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec
|
||||||
if (other != NULL) {
|
if (other != NULL) {
|
||||||
log_assert(size() == other->size());
|
log_assert(size() == other->size());
|
||||||
other->unpack();
|
other->unpack();
|
||||||
other->hash_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool modified = false;
|
||||||
|
bool other_modified = false;
|
||||||
for (int i = GetSize(bits_) - 1; i >= 0; i--) {
|
for (int i = GetSize(bits_) - 1; i >= 0; i--) {
|
||||||
if (bits_[i].wire != NULL && pattern.count(bits_[i])) {
|
if (bits_[i].wire != NULL && pattern.count(bits_[i])) {
|
||||||
|
modified = true;
|
||||||
bits_.erase(bits_.begin() + i);
|
bits_.erase(bits_.begin() + i);
|
||||||
if (other != NULL)
|
if (other != NULL) {
|
||||||
|
other_modified = true;
|
||||||
other->bits_.erase(other->bits_.begin() + i);
|
other->bits_.erase(other->bits_.begin() + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hash_.clear();
|
}
|
||||||
|
|
||||||
|
if (modified) {
|
||||||
|
hash_.clear();
|
||||||
|
try_repack();
|
||||||
|
}
|
||||||
|
if (other_modified) {
|
||||||
|
other->hash_.clear();
|
||||||
|
other->try_repack();
|
||||||
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4911,18 +4982,29 @@ void RTLIL::SigSpec::remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigS
|
||||||
if (other != NULL) {
|
if (other != NULL) {
|
||||||
log_assert(size() == other->size());
|
log_assert(size() == other->size());
|
||||||
other->unpack();
|
other->unpack();
|
||||||
other->hash_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool modified = false;
|
||||||
|
bool other_modified = false;
|
||||||
for (int i = GetSize(bits_) - 1; i >= 0; i--) {
|
for (int i = GetSize(bits_) - 1; i >= 0; i--) {
|
||||||
if (bits_[i].wire != NULL && pattern.count(bits_[i])) {
|
if (bits_[i].wire != NULL && pattern.count(bits_[i])) {
|
||||||
|
modified = true;
|
||||||
bits_.erase(bits_.begin() + i);
|
bits_.erase(bits_.begin() + i);
|
||||||
if (other != NULL)
|
if (other != NULL) {
|
||||||
|
other_modified = true;
|
||||||
other->bits_.erase(other->bits_.begin() + i);
|
other->bits_.erase(other->bits_.begin() + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hash_.clear();
|
}
|
||||||
|
|
||||||
|
if (modified) {
|
||||||
|
hash_.clear();
|
||||||
|
try_repack();
|
||||||
|
}
|
||||||
|
if (other_modified) {
|
||||||
|
other->hash_.clear();
|
||||||
|
other->try_repack();
|
||||||
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4938,18 +5020,29 @@ void RTLIL::SigSpec::remove2(const pool<RTLIL::Wire*> &pattern, RTLIL::SigSpec *
|
||||||
if (other != NULL) {
|
if (other != NULL) {
|
||||||
log_assert(size() == other->size());
|
log_assert(size() == other->size());
|
||||||
other->unpack();
|
other->unpack();
|
||||||
other->hash_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool modified = false;
|
||||||
|
bool other_modified = false;
|
||||||
for (int i = GetSize(bits_) - 1; i >= 0; i--) {
|
for (int i = GetSize(bits_) - 1; i >= 0; i--) {
|
||||||
if (bits_[i].wire != NULL && pattern.count(bits_[i].wire)) {
|
if (bits_[i].wire != NULL && pattern.count(bits_[i].wire)) {
|
||||||
|
modified = true;
|
||||||
bits_.erase(bits_.begin() + i);
|
bits_.erase(bits_.begin() + i);
|
||||||
if (other != NULL)
|
if (other != NULL) {
|
||||||
|
other_modified = true;
|
||||||
other->bits_.erase(other->bits_.begin() + i);
|
other->bits_.erase(other->bits_.begin() + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hash_.clear();
|
}
|
||||||
|
|
||||||
|
if (modified) {
|
||||||
|
hash_.clear();
|
||||||
|
try_repack();
|
||||||
|
}
|
||||||
|
if (other_modified) {
|
||||||
|
other->hash_.clear();
|
||||||
|
other->try_repack();
|
||||||
|
}
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5025,6 +5118,9 @@ void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with)
|
||||||
{
|
{
|
||||||
cover("kernel.rtlil.sigspec.replace_pos");
|
cover("kernel.rtlil.sigspec.replace_pos");
|
||||||
|
|
||||||
|
if (with.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
unpack();
|
unpack();
|
||||||
|
|
||||||
log_assert(offset >= 0);
|
log_assert(offset >= 0);
|
||||||
|
|
@ -5037,6 +5133,7 @@ void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with)
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
hash_.clear();
|
hash_.clear();
|
||||||
|
try_repack();
|
||||||
|
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
@ -5050,6 +5147,7 @@ void RTLIL::SigSpec::remove_const()
|
||||||
if (chunk_.wire == NULL) {
|
if (chunk_.wire == NULL) {
|
||||||
chunk_.~SigChunk();
|
chunk_.~SigChunk();
|
||||||
init_empty_bits();
|
init_empty_bits();
|
||||||
|
hash_.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -5058,15 +5156,16 @@ void RTLIL::SigSpec::remove_const()
|
||||||
|
|
||||||
std::vector<RTLIL::SigBit> new_bits;
|
std::vector<RTLIL::SigBit> new_bits;
|
||||||
new_bits.reserve(bits_.size());
|
new_bits.reserve(bits_.size());
|
||||||
|
|
||||||
for (auto &bit : bits_)
|
for (auto &bit : bits_)
|
||||||
if (bit.wire != NULL)
|
if (bit.wire != NULL)
|
||||||
new_bits.push_back(bit);
|
new_bits.push_back(bit);
|
||||||
|
if (GetSize(new_bits) != GetSize(bits_)) {
|
||||||
bits_.swap(new_bits);
|
bits_.swap(new_bits);
|
||||||
|
hash_.clear();
|
||||||
|
try_repack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_.clear();
|
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5074,6 +5173,9 @@ void RTLIL::SigSpec::remove(int offset, int length)
|
||||||
{
|
{
|
||||||
cover("kernel.rtlil.sigspec.remove_pos");
|
cover("kernel.rtlil.sigspec.remove_pos");
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
unpack();
|
unpack();
|
||||||
|
|
||||||
log_assert(offset >= 0);
|
log_assert(offset >= 0);
|
||||||
|
|
@ -5083,6 +5185,7 @@ void RTLIL::SigSpec::remove(int offset, int length)
|
||||||
bits_.erase(bits_.begin() + offset, bits_.begin() + offset + length);
|
bits_.erase(bits_.begin() + offset, bits_.begin() + offset + length);
|
||||||
|
|
||||||
hash_.clear();
|
hash_.clear();
|
||||||
|
try_repack();
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1287,6 +1287,7 @@ private:
|
||||||
if (rep_ == CHUNK)
|
if (rep_ == CHUNK)
|
||||||
unpack();
|
unpack();
|
||||||
}
|
}
|
||||||
|
void try_repack();
|
||||||
|
|
||||||
Hasher::hash_t updhash() const;
|
Hasher::hash_t updhash() const;
|
||||||
void destroy() {
|
void destroy() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue