Skip to content

Commit 45017e1

Browse files
committed
Make SigSpec::unpack() non-const
1 parent 9a2fd4c commit 45017e1

File tree

2 files changed

+71
-66
lines changed

2 files changed

+71
-66
lines changed

kernel/rtlil.cc

Lines changed: 50 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4667,23 +4667,21 @@ void RTLIL::SigSpec::Chunks::const_iterator::next_chunk_bits()
46674667
chunk.width = i - bit_index;
46684668
}
46694669

4670-
void RTLIL::SigSpec::unpack() const
4670+
void RTLIL::SigSpec::unpack()
46714671
{
46724672
if (rep_ == BITS)
46734673
return;
46744674

4675-
RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
4676-
46774675
cover("kernel.rtlil.sigspec.convert.unpack");
46784676

46794677
std::vector<RTLIL::SigBit> bits;
4680-
bits.reserve(that->chunk_.width);
4681-
for (int i = 0; i < that->chunk_.width; i++)
4682-
bits.emplace_back(that->chunk_, i);
4678+
bits.reserve(chunk_.width);
4679+
for (int i = 0; i < chunk_.width; i++)
4680+
bits.emplace_back(chunk_, i);
46834681

4684-
that->chunk_.~SigChunk();
4685-
that->rep_ = BITS;
4686-
new (&that->bits_) std::vector<RTLIL::SigBit>(std::move(bits));
4682+
chunk_.~SigChunk();
4683+
rep_ = BITS;
4684+
new (&bits_) std::vector<RTLIL::SigBit>(std::move(bits));
46874685
}
46884686

46894687
void RTLIL::SigSpec::updhash() const
@@ -4746,25 +4744,22 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec
47464744
log_assert(size() == other->size());
47474745
log_assert(pattern.size() == with.size());
47484746

4749-
pattern.unpack();
4750-
with.unpack();
4751-
unpack();
4752-
other->unpack();
4753-
47544747
dict<RTLIL::SigBit, int> pattern_to_with;
4755-
for (int i = 0; i < GetSize(pattern.bits_); i++) {
4756-
if (pattern.bits_[i].wire != NULL) {
4757-
pattern_to_with.emplace(pattern.bits_[i], i);
4748+
int pattern_size = pattern.size();
4749+
for (int i = 0; i < pattern_size; i++) {
4750+
SigBit pattern_bit = pattern[i];
4751+
if (pattern_bit.wire != NULL) {
4752+
pattern_to_with.emplace(pattern_bit, i);
47584753
}
47594754
}
47604755

4761-
for (int j = 0; j < GetSize(bits_); j++) {
4762-
auto it = pattern_to_with.find(bits_[j]);
4756+
int this_size = size();
4757+
for (int j = 0; j < this_size; j++) {
4758+
auto it = pattern_to_with.find((*this)[j]);
47634759
if (it != pattern_to_with.end()) {
4764-
other->bits_[j] = with.bits_[it->second];
4760+
(*other)[j] = with[it->second];
47654761
}
47664762
}
4767-
other->hash_ = 0;
47684763

47694764
other->check();
47704765
}
@@ -4782,15 +4777,13 @@ void RTLIL::SigSpec::replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules, RT
47824777
log_assert(size() == other->size());
47834778

47844779
if (rules.empty()) return;
4785-
unpack();
4786-
other->unpack();
47874780

4788-
for (int i = 0; i < GetSize(bits_); i++) {
4789-
auto it = rules.find(bits_[i]);
4781+
int this_size = size();
4782+
for (int i = 0; i < this_size; i++) {
4783+
auto it = rules.find((*this)[i]);
47904784
if (it != rules.end())
4791-
other->bits_[i] = it->second;
4785+
(*other)[i] = it->second;
47924786
}
4793-
other->hash_ = 0;
47944787

47954788
other->check();
47964789
}
@@ -4808,15 +4801,13 @@ void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules
48084801
log_assert(size() == other->size());
48094802

48104803
if (rules.empty()) return;
4811-
unpack();
4812-
other->unpack();
48134804

4814-
for (int i = 0; i < GetSize(bits_); i++) {
4815-
auto it = rules.find(bits_[i]);
4805+
int this_size = size();
4806+
for (int i = 0; i < this_size; i++) {
4807+
auto it = rules.find((*this)[i]);
48164808
if (it != rules.end())
4817-
other->bits_[i] = it->second;
4809+
(*other)[i] = it->second;
48184810
}
4819-
other->hash_ = 0;
48204811

48214812
other->check();
48224813
}
@@ -5570,23 +5561,25 @@ bool RTLIL::SigSpec::match(const char* pattern) const
55705561
{
55715562
cover("kernel.rtlil.sigspec.match");
55725563

5573-
unpack();
5574-
log_assert(int(strlen(pattern)) == GetSize(bits_));
5564+
int pattern_len = strlen(pattern);
5565+
log_assert(pattern_len == size());
55755566

5576-
for (auto it = bits_.rbegin(); it != bits_.rend(); it++, pattern++) {
5577-
if (*pattern == ' ')
5567+
for (int i = 0; i < pattern_len; ++i) {
5568+
char ch = pattern[i];
5569+
if (ch == ' ')
55785570
continue;
5579-
if (*pattern == '*') {
5580-
if (*it != State::Sz && *it != State::Sx)
5571+
RTLIL::SigBit bit = (*this)[pattern_len - 1 - i];
5572+
if (ch == '*') {
5573+
if (bit != State::Sz && bit != State::Sx)
55815574
return false;
55825575
continue;
55835576
}
5584-
if (*pattern == '0') {
5585-
if (*it != State::S0)
5577+
if (ch == '0') {
5578+
if (bit != State::S0)
55865579
return false;
55875580
} else
5588-
if (*pattern == '1') {
5589-
if (*it != State::S1)
5581+
if (ch == '1') {
5582+
if (bit != State::S1)
55905583
return false;
55915584
} else
55925585
log_abort();
@@ -5622,22 +5615,23 @@ std::vector<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_vector() const
56225615
{
56235616
cover("kernel.rtlil.sigspec.to_sigbit_vector");
56245617

5625-
unpack();
5626-
return bits_;
5618+
std::vector<RTLIL::SigBit> result;
5619+
result.reserve(size());
5620+
for (SigBit bit : *this)
5621+
result.push_back(bit);
5622+
return result;
56275623
}
56285624

56295625
std::map<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_map(const RTLIL::SigSpec &other) const
56305626
{
56315627
cover("kernel.rtlil.sigspec.to_sigbit_map");
56325628

5633-
unpack();
5634-
other.unpack();
5635-
5636-
log_assert(size() == other.size());
5629+
int this_size = size();
5630+
log_assert(this_size == other.size());
56375631

56385632
std::map<RTLIL::SigBit, RTLIL::SigBit> new_map;
5639-
for (int i = 0; i < GetSize(bits_); i++)
5640-
new_map[bits_[i]] = other.bits_[i];
5633+
for (int i = 0; i < this_size; i++)
5634+
new_map[(*this)[i]] = other[i];
56415635

56425636
return new_map;
56435637
}
@@ -5646,15 +5640,13 @@ dict<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_dict(const RTLIL::S
56465640
{
56475641
cover("kernel.rtlil.sigspec.to_sigbit_dict");
56485642

5649-
unpack();
5650-
other.unpack();
5651-
5652-
log_assert(size() == other.size());
5643+
int this_size = size();
5644+
log_assert(this_size == other.size());
56535645

56545646
dict<RTLIL::SigBit, RTLIL::SigBit> new_map;
5655-
new_map.reserve(size());
5656-
for (int i = 0; i < GetSize(bits_); i++)
5657-
new_map[bits_[i]] = other.bits_[i];
5647+
new_map.reserve(this_size);
5648+
for (int i = 0; i < this_size; i++)
5649+
new_map[(*this)[i]] = other[i];
56585650

56595651
return new_map;
56605652
}

kernel/rtlil.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,9 +1222,10 @@ struct RTLIL::SigSpecConstIterator
12221222
typedef RTLIL::SigBit& reference;
12231223

12241224
const RTLIL::SigSpec *sig_p;
1225+
RTLIL::SigBit bit;
12251226
int index;
12261227

1227-
inline const RTLIL::SigBit &operator*() const;
1228+
inline const RTLIL::SigBit &operator*();
12281229
inline bool operator!=(const RTLIL::SigSpecConstIterator &other) const { return index != other.index; }
12291230
inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; }
12301231
inline void operator++() { index++; }
@@ -1250,8 +1251,8 @@ struct RTLIL::SigSpec
12501251
new (&bits_) std::vector<RTLIL::SigBit>;
12511252
}
12521253

1253-
void unpack() const;
1254-
inline void inline_unpack() const {
1254+
void unpack();
1255+
inline void inline_unpack() {
12551256
if (rep_ == CHUNK)
12561257
unpack();
12571258
}
@@ -1402,13 +1403,22 @@ struct RTLIL::SigSpec
14021403
friend struct Chunks::const_iterator;
14031404

14041405
inline Chunks chunks() const { return {*this}; }
1405-
inline const std::vector<RTLIL::SigBit> &bits() const { inline_unpack(); return bits_; }
1406+
inline const SigSpec &bits() const { return *this; }
14061407

14071408
inline int size() const { return rep_ == CHUNK ? chunk_.width : GetSize(bits_); }
14081409
inline bool empty() const { return size() == 0; }
14091410

14101411
inline RTLIL::SigBit &operator[](int index) { inline_unpack(); hash_ = 0; return bits_.at(index); }
1411-
inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); return bits_.at(index); }
1412+
inline RTLIL::SigBit operator[](int index) const {
1413+
if (rep_ == CHUNK) {
1414+
if (index < 0 || index >= chunk_.width)
1415+
throw std::out_of_range("SigSpec::operator[]");
1416+
if (chunk_.wire)
1417+
return RTLIL::SigBit(chunk_.wire, chunk_.offset + index);
1418+
return RTLIL::SigBit(chunk_.data[index]);
1419+
}
1420+
return bits_.at(index);
1421+
}
14121422

14131423
inline RTLIL::SigSpecIterator begin() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = 0; return it; }
14141424
inline RTLIL::SigSpecIterator end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = size(); return it; }
@@ -1452,6 +1462,8 @@ struct RTLIL::SigSpec
14521462

14531463
RTLIL::SigBit lsb() const { log_assert(size()); return (*this)[0]; };
14541464
RTLIL::SigBit msb() const { log_assert(size()); return (*this)[size() - 1]; };
1465+
RTLIL::SigBit front() const { return (*this)[0]; }
1466+
RTLIL::SigBit back() const { return (*this)[size() - 1]; }
14551467

14561468
void append(const RTLIL::SigSpec &signal);
14571469
inline void append(Wire *wire) { append(RTLIL::SigSpec(wire)); }
@@ -1532,7 +1544,7 @@ struct RTLIL::SigSpec
15321544
static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
15331545

15341546
operator std::vector<RTLIL::SigChunk>() const;
1535-
operator std::vector<RTLIL::SigBit>() const { return bits(); }
1547+
operator std::vector<RTLIL::SigBit>() const { return to_sigbit_vector(); }
15361548
const RTLIL::SigBit &at(int offset, const RTLIL::SigBit &defval) { return offset < size() ? (*this)[offset] : defval; }
15371549

15381550
[[nodiscard]] Hasher hash_into(Hasher h) const { if (!hash_) updhash(); h.eat(hash_); return h; }
@@ -2439,8 +2451,9 @@ inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const {
24392451
return (*sig_p)[index];
24402452
}
24412453

2442-
inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() const {
2443-
return (*sig_p)[index];
2454+
inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() {
2455+
bit = (*sig_p)[index];
2456+
return bit;
24442457
}
24452458

24462459
inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) {

0 commit comments

Comments
 (0)