diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a76e0d713..ca1c47b50 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -27,6 +27,7 @@ #include #include +#include YOSYS_NAMESPACE_BEGIN @@ -2423,6 +2424,7 @@ RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *oth RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) { RTLIL::Cell *cell = new RTLIL::Cell; + // std::cout << "alloc " << (long long)cell << " called " << cell->name.c_str() << "\n"; cell->name = name; cell->type = type; add(cell); @@ -3441,7 +3443,6 @@ RTLIL::Wire::Wire() port_output = false; upto = false; is_signed = false; - #ifdef WITH_PYTHON RTLIL::Wire::get_all_wires()->insert(std::pair(hashidx_, this)); #endif @@ -3785,14 +3786,10 @@ bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const } RTLIL::SigSpec::SigSpec(std::initializer_list parts) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.list"); - width_ = 0; - hash_ = 0; - - packed_ = true; - (void)new (&this->chunks_) std::vector(); log_assert(parts.size() > 0); auto ie = parts.begin(); auto it = ie + parts.size() - 1; @@ -3801,149 +3798,114 @@ RTLIL::SigSpec::SigSpec(std::initializer_list parts) } RTLIL::SigSpec::SigSpec(const RTLIL::Const &value) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.const"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); if (GetSize(value) != 0) { chunks_.emplace_back(value); width_ = chunks_.back().width; - } else { - width_ = 0; } - hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(RTLIL::Const &&value) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.const.move"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); if (GetSize(value) != 0) { chunks_.emplace_back(std::move(value)); width_ = chunks_.back().width; - } else { - width_ = 0; } - hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.chunk"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); if (chunk.width != 0) { chunks_.emplace_back(chunk); width_ = chunks_.back().width; - } else { - width_ = 0; } - hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(RTLIL::SigChunk &&chunk) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.chunk.move"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); if (chunk.width != 0) { chunks_.emplace_back(std::move(chunk)); width_ = chunks_.back().width; - } else { - width_ = 0; } - hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.wire"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); if (wire->width != 0) { chunks_.emplace_back(wire); width_ = chunks_.back().width; - } else { - width_ = 0; } - hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.wire_part"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); if (width != 0) { chunks_.emplace_back(wire, offset, width); width_ = chunks_.back().width; - } else { - width_ = 0; } - hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(const std::string &str) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.str"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); if (str.size() != 0) { chunks_.emplace_back(str); width_ = chunks_.back().width; - } else { - width_ = 0; } - hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(int val, int width) +: width_(width), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.int"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); if (width != 0) chunks_.emplace_back(val, width); - width_ = width; - hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width) +: width_(width), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.state"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); if (width != 0) chunks_.emplace_back(bit, width); - width_ = width; - hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(const RTLIL::SigBit &bit, int width) +: width_(width), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.bit"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); if (width != 0) { if (bit.wire == NULL) chunks_.emplace_back(bit.data, width); @@ -3951,109 +3913,91 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigBit &bit, int width) for (int i = 0; i < width; i++) chunks_.push_back(bit); } - width_ = width; - hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(const std::vector &chunks) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.stdvec_chunks"); - packed_ = true; - (void)new (&this->chunks_) std::vector(); - width_ = 0; - hash_ = 0; for (const auto &c : chunks) append(c); check(); } RTLIL::SigSpec::SigSpec(const std::vector &bits) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.stdvec_bits"); - packed_ = false; - (void)new (&this->bits_) std::vector(); - width_ = 0; - hash_ = 0; + for (const auto &bit : bits) + append(bit); + check(); +} + +RTLIL::SigSpec::SigSpec(const chunk_vec_type &chunks) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) +{ + cover("kernel.rtlil.sigspec.init.mock_vec_chunks"); + + for (const auto &c : chunks) + append(c); + check(); +} + +RTLIL::SigSpec::SigSpec(const bit_vec_type &bits) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) +{ + cover("kernel.rtlil.sigspec.init.mock_vec_bits"); + for (const auto &bit : bits) append(bit); check(); } RTLIL::SigSpec::SigSpec(const pool &bits) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.pool_bits"); - packed_ = false; - (void)new (&this->bits_) std::vector(); - width_ = 0; - hash_ = 0; for (const auto &bit : bits) append(bit); check(); } RTLIL::SigSpec::SigSpec(const std::set &bits) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.stdset_bits"); - packed_ = false; - (void)new (&this->bits_) std::vector(); - width_ = 0; - hash_ = 0; for (const auto &bit : bits) append(bit); check(); } RTLIL::SigSpec::SigSpec(bool bit) +: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) { cover("kernel.rtlil.sigspec.init.bool"); - packed_ = false; - (void)new (&this->bits_) std::vector(); - width_ = 0; - hash_ = 0; append(SigBit(bit)); check(); } -void RTLIL::SigSpec::switch_to_packed() const -{ - // TODO change to debug asserts - // log_assert(!this->packed_); - // log_assert(bits_.size() == 0); - RTLIL::SigSpec *that = (RTLIL::SigSpec*)this; - that->bits_.~vector(); - that->packed_ = true; - (void)new (&that->chunks_) std::vector(); -} - -void RTLIL::SigSpec::switch_to_unpacked() const -{ - // TODO change to debug asserts - // log_assert(this->packed_); - // log_assert(chunks_.size() == 0); - RTLIL::SigSpec *that = (RTLIL::SigSpec*)this; - that->chunks_.~vector(); - that->packed_ = false; - (void)new (&that->bits_) std::vector(); -} - void RTLIL::SigSpec::pack() const { RTLIL::SigSpec *that = (RTLIL::SigSpec*)this; - if (packed_ || that->bits_.empty()) + if (that->bits_.empty()) return; cover("kernel.rtlil.sigspec.convert.pack"); + log_assert(that->chunks_.empty()); - std::vector old_bits; - std::vector new_chunks; - old_bits.swap(that->bits_); + HellVector old_bit_hell; + old_bit_hell.swap(that->hell_); + HellVector::mock_vector old_bits(old_bit_hell); RTLIL::SigChunk *last = NULL; int last_end_offset = 0; @@ -4070,14 +4014,11 @@ void RTLIL::SigSpec::pack() const continue; } } - new_chunks.push_back(bit); - last = &new_chunks.back(); + that->chunks_.push_back(bit); + last = &that->chunks_.back(); last_end_offset = bit.offset + 1; } - that->switch_to_packed(); - that->chunks_.swap(new_chunks); - check(); } @@ -4085,21 +4026,19 @@ void RTLIL::SigSpec::unpack() const { RTLIL::SigSpec *that = (RTLIL::SigSpec*)this; - if (!packed_ || that->chunks_.empty()) + if (that->chunks_.empty()) return; cover("kernel.rtlil.sigspec.convert.unpack"); + log_assert(that->bits_.empty()); - std::vector new_bits; - new_bits.reserve(that->width_); + that->bits_.reserve(that->width_); for (auto &c : that->chunks_) for (int i = 0; i < c.width; i++) - new_bits.emplace_back(c, i); + that->bits_.emplace_back(c, i); that->chunks_.clear(); that->hash_ = 0; - that->switch_to_unpacked(); - that->bits_.swap(new_bits); } void RTLIL::SigSpec::updhash() const @@ -4142,7 +4081,7 @@ void RTLIL::SigSpec::sort_and_unify() // A copy of the bits vector is used to prevent duplicating the logic from // SigSpec::SigSpec(std::vector). This incurrs an extra copy but // that isn't showing up as significant in profiles. - std::vector unique_bits = bits_; + bit_vec_type unique_bits = bits_; std::sort(unique_bits.begin(), unique_bits.end()); auto last = std::unique(unique_bits.begin(), unique_bits.end()); unique_bits.erase(last, unique_bits.end()); @@ -4383,11 +4322,11 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLI log_assert(other == NULL || width_ == other->width_); RTLIL::SigSpec ret; - std::vector bits_match = to_sigbit_vector(); + bit_vec_type bits_match = to_sigbit_vector(); for (auto& pattern_chunk : pattern.chunks()) { if (other) { - std::vector bits_other = other->to_sigbit_vector(); + bit_vec_type bits_other = other->to_sigbit_vector(); for (int i = 0; i < width_; i++) if (bits_match[i].wire && bits_match[i].wire == pattern_chunk.wire && @@ -4417,11 +4356,11 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(const pool &pattern, const log_assert(other == NULL || width_ == other->width_); - std::vector bits_match = to_sigbit_vector(); + bit_vec_type bits_match = to_sigbit_vector(); RTLIL::SigSpec ret; if (other) { - std::vector bits_other = other->to_sigbit_vector(); + bit_vec_type bits_other = other->to_sigbit_vector(); for (int i = 0; i < width_; i++) if (bits_match[i].wire && pattern.count(bits_match[i])) ret.append(bits_other[i]); @@ -4458,7 +4397,7 @@ void RTLIL::SigSpec::remove_const() { cover("kernel.rtlil.sigspec.remove_const.packed"); - std::vector new_chunks; + chunk_vec_type new_chunks(hell_); new_chunks.reserve(GetSize(chunks_)); width_ = 0; @@ -4480,7 +4419,7 @@ void RTLIL::SigSpec::remove_const() { cover("kernel.rtlil.sigspec.remove_const.unpacked"); - std::vector new_bits; + bit_vec_type new_bits(hell_); new_bits.reserve(width_); for (auto &bit : bits_) @@ -4679,6 +4618,7 @@ void RTLIL::SigSpec::check(Module *mod) const w += chunk.width; } log_assert(w == width_); + log_assert(bits_.empty()); } else { @@ -4689,7 +4629,9 @@ void RTLIL::SigSpec::check(Module *mod) const if (bits_[i].wire != nullptr) log_assert(bits_[i].wire->module == mod); } + log_assert(width_ == GetSize(bits_)); + log_assert(chunks_.empty()); } } #endif @@ -5022,7 +4964,7 @@ pool RTLIL::SigSpec::to_sigbit_pool() const return sigbits; } -std::vector RTLIL::SigSpec::to_sigbit_vector() const +RTLIL::SigSpec::bit_vec_type RTLIL::SigSpec::to_sigbit_vector() const { cover("kernel.rtlil.sigspec.to_sigbit_vector"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7062421c5..bfdf58b81 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -843,6 +843,7 @@ struct RTLIL::SigSpecConstIterator struct RTLIL::HellVector { private: + // TODO spend at least ten seconds thinking about alignment std::vector backing; void dump() { std::cout << "Dumping, size is " << backing.size() << std::endl; @@ -853,119 +854,243 @@ struct RTLIL::HellVector } } public: + // template + // using iterator = T*; + // template + // using const_iterator = T*; + template class mock_vector; template class iterator { + friend mock_vector; private: - HellVector *const parent; - int position; + char* position; public: - typedef std::bidirectional_iterator_tag iterator_category; + typedef std::random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; - iterator (HellVector* parent, int position) : parent(parent), position(position) {} - T& operator* () { - char* as_char = &parent->backing[position * sizeof(T)]; - return *(T*)as_char; + iterator (char* position) : position(position) {} + T& operator* () const { + return *(T*)position; + } + T* operator-> () const { + return (const T*)position; + } + iterator operator+(size_t i) { + return iterator((char*)((T*)position + i)); + } + size_t operator-(iterator other) { + return (size_t)(position - other.position) / sizeof(T); + } + iterator operator-(size_t i) { + return iterator(position - i * sizeof(T)); } iterator& operator++() { - position += 1; + position += sizeof(T); return *this; } iterator& operator--() { - position -= 1; + position -= sizeof(T); return *this; } + iterator& operator++(int) { + position += sizeof(T); + return *this; + } + iterator& operator--(int) { + position -= sizeof(T); + return *this; + } + bool operator<(const iterator& other) const { + return position < other.position; + } bool operator==(const iterator &other) const { return position == other.position; } bool operator!=(const iterator& other) const { - return !operator==(other); + return !operator==(other); } }; template class const_iterator { + friend mock_vector; private: - const HellVector *const parent; - int position; + char* position; public: typedef std::input_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; - const_iterator (const HellVector* parent, int position) : parent(parent), position(position) {} - const T& operator* () { - const char* as_char = &parent->backing[position * sizeof(T)]; - return *(const T*)as_char; + const_iterator (char* position) : position(position) {} + const T& operator* () const { + return *(const T*)position; + } + const T* operator-> () const { + return (const T*)position; + } + const_iterator operator+(size_t i) { + return const_iterator((char*)((T*)position + i)); + } + size_t operator-(const_iterator other) { + return (size_t)(position - other.position) / sizeof(T); + } + const_iterator operator-(size_t i) { + return const_iterator(position - i * sizeof(T)); } const_iterator& operator++() { - position += 1; + position += sizeof(T); return *this; } - const_iterator& operator-() { - position -= 1; + const_iterator& operator--() { + position -= sizeof(T); return *this; } + const_iterator& operator++(int) { + position += sizeof(T); + return *this; + } + const_iterator& operator--(int) { + position -= sizeof(T); + return *this; + } + bool operator<(const const_iterator& other) const { + return position < other.position; + } bool operator==(const const_iterator &other) const { return position == other.position; } bool operator!=(const const_iterator& other) const { - return !operator==(other); + return !operator==(other); } }; + template + using reverse_iterator = std::reverse_iterator>; + template + using const_reverse_iterator = std::reverse_iterator>; template class mock_vector { - const HellVector *const parent; + HellVector& parent; public: - mock_vector(HellVector* parent) {parent(parent)} - void clear() { - backing.clear(); + mock_vector(HellVector& p) : parent(p) {} + template + T& emplace_back(Args&&... args) { + // TODO optimize this + push_back(T(std::forward(args)...)); + return back(); } - bool empty() const { - return backing.empty(); + void reserve(size_t n) { + parent.backing.reserve(sizeof(T) * n); } - template iterator begin() { - return iterator(this, 0); + void push_back(T t) { + std::cout << "Pushing " << std::dec << sizeof(T) << " bytes" << std::endl; + auto size = parent.backing.size(); + parent.backing.resize(size + sizeof(T)); + memcpy((void*) &parent.backing[size], (void*) &t, sizeof(T)); + // dump(); + // parent.backing.push_back(t); } - template iterator end() { - return iterator(this, backing.size() / sizeof(T)); - } - template const_iterator begin() const { - return const_iterator(this, 0); - } - template const_iterator end() const { - return const_iterator(this, backing.size() / sizeof(T)); - } - template T& at(int i) { - char* as_char = &parent->backing[i * sizeof(T)]; + T& operator[](size_t i) { + char* as_char = &parent.backing[i * sizeof(T)]; return *(T*)as_char; } - template const T& at(int i) { - const char* as_char = &parent->backing[i * sizeof(T)]; - return *(const T*)as_char; + const T& operator[](size_t i) const { + const char* as_char = &parent.backing[i * sizeof(T)]; + return *(T*)as_char; + } + T& at(size_t i) { + if (i >= parent.backing.size() / sizeof(T)) + throw std::out_of_range("HellVector::mock_vector.at(size_t i)"); + return (*this)[i]; + } + const T& at(size_t i) const { + if (i >= parent.backing.size() / sizeof(T)) + throw std::out_of_range("HellVector::mock_vector.at(size_t i)"); + return (*this)[i]; + } + // Unlike with std::vector, this kind of signature doesn't provide a return value because I didn't feel like it + void erase(iterator it) { + size_t position = it - begin(); + (void)parent.backing.erase(parent.backing.begin() + position * sizeof(T), parent.backing.begin() + (position + 1) * sizeof(T)); + } + void erase(const_iterator it) { + size_t position = it - begin(); + (void)parent.backing.erase(parent.backing.begin() + position * sizeof(T), parent.backing.begin() + (position + 1) * sizeof(T)); + } + void erase(iterator first_it, iterator last_it) { + size_t first = first_it - begin(); + size_t last = last_it - begin(); + (void)parent.backing.erase(parent.backing.begin() + first * sizeof(T), parent.backing.begin() + last * sizeof(T)); + } + void erase(const_iterator first_it, const_iterator last_it) { + size_t first = first_it - begin(); + size_t last = last_it - begin(); + (void)parent.backing.erase(parent.backing.begin() + first * sizeof(T), parent.backing.begin() + last * sizeof(T)); + } + iterator insert(iterator pos_it, const T& value) { + size_t position = pos_it - begin(); + // vector allows us to use char* as iterators for the source range of the insert + auto backing_it = parent.backing.insert(parent.backing.begin() + (position * sizeof(T)), &value, &value + 1); + size_t ret_position = (backing_it - parent.backing.begin()) / sizeof(T); + return begin() + ret_position; + } + iterator insert(iterator pos_it, const_iterator first_it, const_iterator last_it) { + size_t backing_position = (pos_it - begin()) * sizeof(T); + // vector allows us to use char* as iterators for the source range of the insert + auto backing_it = parent.backing.insert(parent.backing.begin() + backing_position, first_it.position, last_it.position); + size_t ret_position = (backing_it - parent.backing.begin()) / sizeof(T); + return begin() + ret_position; + } + void swap(mock_vector& other) { + parent.backing.swap(other.parent.backing); + } + void clear() { + parent.backing.clear(); + } + size_t size() const { + return parent.backing.size() / sizeof(T); + } + bool empty() const { + return parent.backing.empty(); + } + iterator begin() { + return iterator(&parent.backing[0]); + } + iterator end() { + return iterator(&parent.backing[parent.backing.size()]); + } + const_iterator begin() const { + return const_iterator(&parent.backing[0]); + } + const_iterator end() const { + return const_iterator(&parent.backing[parent.backing.size()]); + } + reverse_iterator rbegin() { + return reverse_iterator(end()); + } + reverse_iterator rend() { + return reverse_iterator(begin()); + } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + T& front() { + return (*this)[0]; + } + T& back() { + return (*this)[parent.backing.size() / sizeof(T) - 1]; + } + const T& front() const { + return (*this)[0]; + } + const T& back() const { + return (*this)[parent.backing.size() / sizeof(T) - 1]; } }; - bool empty() const { - return backing.empty(); - } - template size_t size() const { - return backing.size() / sizeof(T); - } - template void push_back(T& thing) { - std::cout << "Pushing " << std::dec << sizeof(T) << " bytes" << std::endl; - auto size = backing.size(); - backing.resize(size + sizeof(T)); - memcpy((void*) &backing[size], (void*) &thing, sizeof(T)); - // dump(); - } - SigBit &bit(size_t position) const { - void* eee = (void*)(&backing[position * sizeof(SigBit)]); - return *(SigBit*) eee; - } - SigChunk &chunk(size_t position) const { - void* eee = (void*)(&backing[position * sizeof(SigChunk)]); - return *(SigChunk*) eee; - } - + void swap(HellVector& other) { + other.backing.swap(backing); + } }; struct RTLIL::SigSpec @@ -973,13 +1098,20 @@ struct RTLIL::SigSpec private: int width_; bool packed_; - unsigned long hash_; - HellVector hell_; + mutable unsigned long hash_; + mutable HellVector hell_; + + typedef HellVector::mock_vector bit_vec_type; + typedef HellVector::mock_vector chunk_vec_type; + + bit_vec_type bits_; + chunk_vec_type chunks_; + void pack() const; void unpack() const; - void switch_to_packed() const; - void switch_to_unpacked() const; + void switch_to_packed(); + void switch_to_unpacked(); void updhash() const; inline bool packed() const { @@ -987,7 +1119,7 @@ private: } inline void inline_unpack() const { - if (packed_ && !hell_.empty()) + if (packed_ && !chunks_.empty()) unpack(); } @@ -996,10 +1128,10 @@ private: friend struct RTLIL::Module; public: - SigSpec() : width_(0), packed_(true), hash_(0), hell_(), bits_(&hell_), chunks_(&hell_) {} + SigSpec() : width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) {} // ~SigSpec() { if (packed_) chunks_.~vector(); else bits_.~vector(); } SigSpec(std::initializer_list parts); - SigSpec(const Yosys::RTLIL::SigSpec &other) : width_(other.width_), packed_(other.packed_), hash_(other.hash_), hell_(other.hell_), bits_(&hell_), chunks_(&hell_) { check(); } + SigSpec(const Yosys::RTLIL::SigSpec &other) : width_(other.width_), packed_(other.packed_), hash_(other.hash_), hell_(other.hell_), bits_(hell_), chunks_(hell_) { check(); } SigSpec& operator=(const Yosys::RTLIL::SigSpec & other) { hell_ = other.hell_; @@ -1022,6 +1154,8 @@ public: SigSpec(const RTLIL::SigBit &bit, int width = 1); SigSpec(const std::vector &chunks); SigSpec(const std::vector &bits); + SigSpec(const chunk_vec_type &chunks); + SigSpec(const bit_vec_type &bits); SigSpec(const pool &bits); SigSpec(const std::set &bits); explicit SigSpec(bool bit); @@ -1031,19 +1165,19 @@ public: return hash_; } - HellVector::mock_vector bits_; - HellVector::mock_vector chunks_; + inline const auto &chunks() const { pack(); return chunks_; } + inline const auto &bits() const { inline_unpack(); return bits_; } inline int size() const { return width_; } inline bool empty() const { return width_ == 0; } - inline RTLIL::SigBit &operator[](int index) { inline_unpack(); return bits_.at(index); } - inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); return chunks_.at(index); } + inline RTLIL::SigBit &operator[](int index) { inline_unpack(); SigBit& bit = bits_.at(index); return bit; } + inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); const SigBit& bit = bits_.at(index); return bit; } - inline auto begin() { HellVector::iterator it(&hell_, 0); return it; } - inline auto end() { HellVector::iterator it(&hell_, hell_.size()); return it; } - inline auto begin() const { HellVector::const_iterator it(&hell_, 0); return it; } - inline auto end() const { HellVector::const_iterator it(&hell_, hell_.size()); return it; } + inline auto begin() { return bits_.begin(); } + inline auto end() { return bits_.end(); } + inline auto begin() const { return bits_.begin(); } + inline auto end() const { return bits_.end(); } // inline auto end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = width_; return it; } // inline RTLIL::SigSpecConstIterator begin() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = 0; return it; } @@ -1128,7 +1262,7 @@ public: std::set to_sigbit_set() const; pool to_sigbit_pool() const; - std::vector to_sigbit_vector() const; + bit_vec_type to_sigbit_vector() const; std::map to_sigbit_map(const RTLIL::SigSpec &other) const; dict to_sigbit_dict(const RTLIL::SigSpec &other) const; @@ -1864,7 +1998,7 @@ inline unsigned int RTLIL::SigBit::hash() const { inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { log_assert(sig.size() == 1); - *this = SigBit(*sig.chunks()); + *this = SigBit(sig.chunks().front()); } template