mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-15 21:38:45 +00:00
sigspec: decrease size with tagged union of bits and chunks
This commit is contained in:
parent
b08688f711
commit
36fe6d4c56
|
@ -3791,6 +3791,8 @@ RTLIL::SigSpec::SigSpec(std::initializer_list<RTLIL::SigSpec> parts)
|
|||
width_ = 0;
|
||||
hash_ = 0;
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
log_assert(parts.size() > 0);
|
||||
auto ie = parts.begin();
|
||||
auto it = ie + parts.size() - 1;
|
||||
|
@ -3802,6 +3804,8 @@ RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.const");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
if (GetSize(value) != 0) {
|
||||
chunks_.emplace_back(value);
|
||||
width_ = chunks_.back().width;
|
||||
|
@ -3816,6 +3820,8 @@ RTLIL::SigSpec::SigSpec(RTLIL::Const &&value)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.const.move");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
if (GetSize(value) != 0) {
|
||||
chunks_.emplace_back(std::move(value));
|
||||
width_ = chunks_.back().width;
|
||||
|
@ -3830,6 +3836,8 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.chunk");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
if (chunk.width != 0) {
|
||||
chunks_.emplace_back(chunk);
|
||||
width_ = chunks_.back().width;
|
||||
|
@ -3844,6 +3852,8 @@ RTLIL::SigSpec::SigSpec(RTLIL::SigChunk &&chunk)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.chunk.move");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
if (chunk.width != 0) {
|
||||
chunks_.emplace_back(std::move(chunk));
|
||||
width_ = chunks_.back().width;
|
||||
|
@ -3858,6 +3868,8 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.wire");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
if (wire->width != 0) {
|
||||
chunks_.emplace_back(wire);
|
||||
width_ = chunks_.back().width;
|
||||
|
@ -3872,6 +3884,8 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.wire_part");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
if (width != 0) {
|
||||
chunks_.emplace_back(wire, offset, width);
|
||||
width_ = chunks_.back().width;
|
||||
|
@ -3886,6 +3900,8 @@ RTLIL::SigSpec::SigSpec(const std::string &str)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.str");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
if (str.size() != 0) {
|
||||
chunks_.emplace_back(str);
|
||||
width_ = chunks_.back().width;
|
||||
|
@ -3900,6 +3916,8 @@ RTLIL::SigSpec::SigSpec(int val, int width)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.int");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
if (width != 0)
|
||||
chunks_.emplace_back(val, width);
|
||||
width_ = width;
|
||||
|
@ -3911,6 +3929,8 @@ RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.state");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
if (width != 0)
|
||||
chunks_.emplace_back(bit, width);
|
||||
width_ = width;
|
||||
|
@ -3922,6 +3942,8 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigBit &bit, int width)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.bit");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
if (width != 0) {
|
||||
if (bit.wire == NULL)
|
||||
chunks_.emplace_back(bit.data, width);
|
||||
|
@ -3938,6 +3960,8 @@ RTLIL::SigSpec::SigSpec(const std::vector<RTLIL::SigChunk> &chunks)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.stdvec_chunks");
|
||||
|
||||
packed_ = true;
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
width_ = 0;
|
||||
hash_ = 0;
|
||||
for (const auto &c : chunks)
|
||||
|
@ -3949,6 +3973,8 @@ RTLIL::SigSpec::SigSpec(const std::vector<RTLIL::SigBit> &bits)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.stdvec_bits");
|
||||
|
||||
packed_ = false;
|
||||
(void)new (&this->bits_) std::vector<SigBit>();
|
||||
width_ = 0;
|
||||
hash_ = 0;
|
||||
for (const auto &bit : bits)
|
||||
|
@ -3960,6 +3986,8 @@ RTLIL::SigSpec::SigSpec(const pool<RTLIL::SigBit> &bits)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.pool_bits");
|
||||
|
||||
packed_ = false;
|
||||
(void)new (&this->bits_) std::vector<SigBit>();
|
||||
width_ = 0;
|
||||
hash_ = 0;
|
||||
for (const auto &bit : bits)
|
||||
|
@ -3971,6 +3999,8 @@ RTLIL::SigSpec::SigSpec(const std::set<RTLIL::SigBit> &bits)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.stdset_bits");
|
||||
|
||||
packed_ = false;
|
||||
(void)new (&this->bits_) std::vector<SigBit>();
|
||||
width_ = 0;
|
||||
hash_ = 0;
|
||||
for (const auto &bit : bits)
|
||||
|
@ -3982,23 +4012,47 @@ RTLIL::SigSpec::SigSpec(bool bit)
|
|||
{
|
||||
cover("kernel.rtlil.sigspec.init.bool");
|
||||
|
||||
packed_ = false;
|
||||
(void)new (&this->bits_) std::vector<SigBit>();
|
||||
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<SigChunk>();
|
||||
}
|
||||
|
||||
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<SigBit>();
|
||||
}
|
||||
|
||||
void RTLIL::SigSpec::pack() const
|
||||
{
|
||||
RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
|
||||
|
||||
if (that->bits_.empty())
|
||||
if (packed_ || that->bits_.empty())
|
||||
return;
|
||||
|
||||
cover("kernel.rtlil.sigspec.convert.pack");
|
||||
log_assert(that->chunks_.empty());
|
||||
|
||||
std::vector<RTLIL::SigBit> old_bits;
|
||||
std::vector<RTLIL::SigChunk> new_chunks;
|
||||
old_bits.swap(that->bits_);
|
||||
|
||||
RTLIL::SigChunk *last = NULL;
|
||||
|
@ -4016,11 +4070,14 @@ void RTLIL::SigSpec::pack() const
|
|||
continue;
|
||||
}
|
||||
}
|
||||
that->chunks_.push_back(bit);
|
||||
last = &that->chunks_.back();
|
||||
new_chunks.push_back(bit);
|
||||
last = &new_chunks.back();
|
||||
last_end_offset = bit.offset + 1;
|
||||
}
|
||||
|
||||
that->switch_to_packed();
|
||||
that->chunks_.swap(new_chunks);
|
||||
|
||||
check();
|
||||
}
|
||||
|
||||
|
@ -4028,19 +4085,21 @@ void RTLIL::SigSpec::unpack() const
|
|||
{
|
||||
RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
|
||||
|
||||
if (that->chunks_.empty())
|
||||
if (!packed_ || that->chunks_.empty())
|
||||
return;
|
||||
|
||||
cover("kernel.rtlil.sigspec.convert.unpack");
|
||||
log_assert(that->bits_.empty());
|
||||
|
||||
that->bits_.reserve(that->width_);
|
||||
std::vector<RTLIL::SigBit> new_bits;
|
||||
new_bits.reserve(that->width_);
|
||||
for (auto &c : that->chunks_)
|
||||
for (int i = 0; i < c.width; i++)
|
||||
that->bits_.emplace_back(c, i);
|
||||
new_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
|
||||
|
@ -4620,7 +4679,6 @@ void RTLIL::SigSpec::check(Module *mod) const
|
|||
w += chunk.width;
|
||||
}
|
||||
log_assert(w == width_);
|
||||
log_assert(bits_.empty());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4631,9 +4689,7 @@ 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
|
||||
|
|
|
@ -842,20 +842,25 @@ struct RTLIL::SigSpec
|
|||
{
|
||||
private:
|
||||
int width_;
|
||||
bool packed_;
|
||||
unsigned long hash_;
|
||||
std::vector<RTLIL::SigChunk> chunks_; // LSB at index 0
|
||||
std::vector<RTLIL::SigBit> bits_; // LSB at index 0
|
||||
union {
|
||||
std::vector<RTLIL::SigChunk> chunks_; // LSB at index 0
|
||||
std::vector<RTLIL::SigBit> bits_; // LSB at index 0
|
||||
};
|
||||
|
||||
void pack() const;
|
||||
void unpack() const;
|
||||
void switch_to_packed() const;
|
||||
void switch_to_unpacked() const;
|
||||
void updhash() const;
|
||||
|
||||
inline bool packed() const {
|
||||
return bits_.empty();
|
||||
return packed_;
|
||||
}
|
||||
|
||||
inline void inline_unpack() const {
|
||||
if (!chunks_.empty())
|
||||
if (packed_ && !chunks_.empty())
|
||||
unpack();
|
||||
}
|
||||
|
||||
|
@ -864,8 +869,47 @@ private:
|
|||
friend struct RTLIL::Module;
|
||||
|
||||
public:
|
||||
SigSpec() : width_(0), hash_(0) {}
|
||||
SigSpec() : width_(0), packed_(true), hash_(0), chunks_() {}
|
||||
~SigSpec() { if (packed_) chunks_.~vector(); else bits_.~vector(); }
|
||||
SigSpec(std::initializer_list<RTLIL::SigSpec> parts);
|
||||
SigSpec(const Yosys::RTLIL::SigSpec &other)
|
||||
{
|
||||
packed_ = other.packed_;
|
||||
width_ = other.width_;
|
||||
hash_ = other.hash_;
|
||||
if (packed_) {
|
||||
(void)new (&this->chunks_) std::vector<SigChunk>();
|
||||
chunks_ = other.chunks_;
|
||||
} else {
|
||||
(void)new (&this->bits_) std::vector<SigBit>();
|
||||
bits_ = other.bits_;
|
||||
}
|
||||
check();
|
||||
}
|
||||
SigSpec& operator=(const Yosys::RTLIL::SigSpec & other)
|
||||
{
|
||||
if (packed_ != other.packed_) {
|
||||
if (packed_) {
|
||||
chunks_.clear();
|
||||
switch_to_unpacked();
|
||||
bits_ = other.bits_;
|
||||
} else {
|
||||
bits_.clear();
|
||||
switch_to_packed();
|
||||
chunks_ = other.chunks_;
|
||||
}
|
||||
} else {
|
||||
if (packed_)
|
||||
chunks_ = other.chunks_;
|
||||
else
|
||||
bits_ = other.bits_;
|
||||
}
|
||||
|
||||
width_ = other.width_;
|
||||
hash_ = other.hash_;
|
||||
check();
|
||||
return *this;
|
||||
}
|
||||
|
||||
SigSpec(const RTLIL::Const &value);
|
||||
SigSpec(RTLIL::Const &&value);
|
||||
|
|
Loading…
Reference in a new issue