3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-09-11 12:11:27 +00:00

Stop using mutable in Const.

Now that we only call `bitvectorize()` in non-const methods, we can move the casting-away-const to only happen
in `bitvectorize()`, which is deprecated so only some plugins (maybe) are using it.

This means `const` `Const` methods don't change the underlying data, which means
they'll be safe to use from multiple threads if/when we want to do that.
This commit is contained in:
Robert O'Callahan 2025-08-29 05:56:19 +00:00
parent a515055be4
commit cd370bf6d1
2 changed files with 34 additions and 20 deletions

View file

@ -204,12 +204,22 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
#define check(condition) log_assert(condition && "malformed Const union") #define check(condition) log_assert(condition && "malformed Const union")
Const::bitvectype& Const::get_bits() const { const Const::bitvectype& Const::get_bits() const {
check(is_bits()); check(is_bits());
return *get_if_bits(); return *get_if_bits();
} }
std::string& Const::get_str() const { const std::string& Const::get_str() const {
check(is_str());
return *get_if_str();
}
Const::bitvectype& Const::get_bits() {
check(is_bits());
return *get_if_bits();
}
std::string& Const::get_str() {
check(is_str()); check(is_str());
return *get_if_str(); return *get_if_str();
} }
@ -395,7 +405,7 @@ bool RTLIL::Const::as_bool() const
return false; return false;
} }
bitvectype& bv = get_bits(); const bitvectype& bv = get_bits();
for (size_t i = 0; i < bv.size(); i++) for (size_t i = 0; i < bv.size(); i++)
if (bv[i] == State::S1) if (bv[i] == State::S1)
return true; return true;
@ -542,7 +552,7 @@ std::string RTLIL::Const::decode_string() const
if (auto str = get_if_str()) if (auto str = get_if_str())
return *str; return *str;
bitvectype& bv = get_bits(); const bitvectype& bv = get_bits();
const int n = GetSize(bv); const int n = GetSize(bv);
const int n_over_8 = n / 8; const int n_over_8 = n / 8;
std::string s; std::string s;
@ -590,7 +600,7 @@ bool RTLIL::Const::empty() const {
} }
} }
void RTLIL::Const::bitvectorize_internal() const { void RTLIL::Const::bitvectorize_internal() {
if (tag == backing_tag::bits) if (tag == backing_tag::bits)
return; return;
@ -641,7 +651,7 @@ bool RTLIL::Const::is_fully_zero() const
return true; return true;
} }
bitvectype& bv = get_bits(); const bitvectype& bv = get_bits();
for (const auto &bit : bv) for (const auto &bit : bv)
if (bit != RTLIL::State::S0) if (bit != RTLIL::State::S0)
@ -661,7 +671,7 @@ bool RTLIL::Const::is_fully_ones() const
return true; return true;
} }
bitvectype& bv = get_bits(); const bitvectype& bv = get_bits();
for (const auto &bit : bv) for (const auto &bit : bv)
if (bit != RTLIL::State::S1) if (bit != RTLIL::State::S1)
return false; return false;
@ -676,7 +686,7 @@ bool RTLIL::Const::is_fully_def() const
if (is_str()) if (is_str())
return true; return true;
bitvectype& bv = get_bits(); const bitvectype& bv = get_bits();
for (const auto &bit : bv) for (const auto &bit : bv)
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1) if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
return false; return false;
@ -691,7 +701,7 @@ bool RTLIL::Const::is_fully_undef() const
if (auto str = get_if_str()) if (auto str = get_if_str())
return str->empty(); return str->empty();
bitvectype& bv = get_bits(); const bitvectype& bv = get_bits();
for (const auto &bit : bv) for (const auto &bit : bv)
if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz) if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz)
return false; return false;
@ -706,7 +716,7 @@ bool RTLIL::Const::is_fully_undef_x_only() const
if (auto str = get_if_str()) if (auto str = get_if_str())
return str->empty(); return str->empty();
bitvectype& bv = get_bits(); const bitvectype& bv = get_bits();
for (const auto &bit : bv) for (const auto &bit : bv)
if (bit != RTLIL::State::Sx) if (bit != RTLIL::State::Sx)
return false; return false;
@ -742,7 +752,7 @@ Hasher RTLIL::Const::hash_into(Hasher h) const
// If the bits are all 0/1, hash packed bits using the string hash. // If the bits are all 0/1, hash packed bits using the string hash.
// Otherwise hash the leading packed bits with the rest of the bits individually. // Otherwise hash the leading packed bits with the rest of the bits individually.
bitvectype &bv = get_bits(); const bitvectype &bv = get_bits();
int size = GetSize(bv); int size = GetSize(bv);
std::string packed; std::string packed;
int packed_size = (size + 7) >> 3; int packed_size = (size + 7) >> 3;

View file

@ -723,23 +723,27 @@ private:
using bitvectype = std::vector<RTLIL::State>; using bitvectype = std::vector<RTLIL::State>;
enum class backing_tag: bool { bits, string }; enum class backing_tag: bool { bits, string };
// Do not access the union or tag even in Const methods unless necessary // Do not access the union or tag even in Const methods unless necessary
mutable backing_tag tag; backing_tag tag;
union { union {
mutable bitvectype bits_; bitvectype bits_;
mutable std::string str_; std::string str_;
}; };
// Use these private utilities instead // Use these private utilities instead
bool is_bits() const { return tag == backing_tag::bits; } bool is_bits() const { return tag == backing_tag::bits; }
bool is_str() const { return tag == backing_tag::string; } bool is_str() const { return tag == backing_tag::string; }
bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; } bitvectype* get_if_bits() { return is_bits() ? &bits_ : NULL; }
std::string* get_if_str() const { return is_str() ? &str_ : NULL; } std::string* get_if_str() { return is_str() ? &str_ : NULL; }
const bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; }
const std::string* get_if_str() const { return is_str() ? &str_ : NULL; }
bitvectype& get_bits() const; bitvectype& get_bits();
std::string& get_str() const; std::string& get_str();
const bitvectype& get_bits() const;
const std::string& get_str() const;
std::vector<RTLIL::State>& bits_internal(); std::vector<RTLIL::State>& bits_internal();
void bitvectorize_internal() const; void bitvectorize_internal();
public: public:
Const() : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::vector<RTLIL::State>()) {} Const() : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::vector<RTLIL::State>()) {}
@ -772,7 +776,7 @@ public:
[[deprecated("Don't use direct access to the internal std::vector<State>, that's an implementation detail.")]] [[deprecated("Don't use direct access to the internal std::vector<State>, that's an implementation detail.")]]
std::vector<RTLIL::State>& bits() { return bits_internal(); } std::vector<RTLIL::State>& bits() { return bits_internal(); }
[[deprecated("Don't call bitvectorize() directly, it's an implementation detail.")]] [[deprecated("Don't call bitvectorize() directly, it's an implementation detail.")]]
void bitvectorize() const { bitvectorize_internal(); } void bitvectorize() const { const_cast<Const*>(this)->bitvectorize_internal(); }
bool as_bool() const; bool as_bool() const;