From: Clifford Wolf Date: Sat, 2 Aug 2014 13:11:35 +0000 (+0200) Subject: Implemented new reference counting RTLIL::IdString X-Git-Tag: yosys-0.4~329 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=60f3dc99237afc051560d18f38625337dc80ac80;p=yosys.git Implemented new reference counting RTLIL::IdString --- diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index af652a9d6..80f63ce74 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -26,6 +26,11 @@ YOSYS_NAMESPACE_BEGIN +std::vector RTLIL::IdString::global_refcount_storage_; +std::vector RTLIL::IdString::global_id_storage_; +std::map RTLIL::IdString::global_id_index_; +std::vector RTLIL::IdString::global_free_idx_list_; + RTLIL::Const::Const() { flags = RTLIL::CONST_FLAG_NONE; @@ -1998,8 +2003,7 @@ void RTLIL::SigSpec::hash() const for (auto &v : c.data.bits) DJB2(that->hash_, v); } else { - for (auto &v : c.wire->name.str()) - DJB2(that->hash_, v); + DJB2(that->hash_, c.wire->name.index_); DJB2(that->hash_, c.offset); DJB2(that->hash_, c.width); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index daf888b79..d95cf11f2 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -74,30 +74,101 @@ namespace RTLIL struct IdString { - private: - std::string str_; - - public: - IdString() : str_() { } - IdString(const char *str) : str_(str) { } - IdString(const IdString &str) : str_(str.str_) { } - IdString(const std::string &str) : str_(str) { } + // the global string cache - void operator=(const char *rhs) { str_ = rhs; } - void operator=(const IdString &rhs) { str_ = rhs.str_; } - void operator=(const std::string &rhs) { str_ = rhs; } + static std::vector global_refcount_storage_; + static std::vector global_id_storage_; + static std::map global_id_index_; + static std::vector global_free_idx_list_; - const std::string& str() const { return str_; } + static inline int get_reference(int idx) + { + global_refcount_storage_.at(idx)++; + return idx; + } + + static inline int get_reference(const std::string &str) + { + if (!str.empty()) { + log_assert(str.size() >= 2); + log_assert(str[0] == '$' || str[0] == '\\'); + } + + auto it = global_id_index_.find(str); + if (it != global_id_index_.end()) { + global_refcount_storage_.at(it->second)++; + return it->second; + } + + if (global_free_idx_list_.empty()) { + log_assert(global_id_storage_.size() < 0x40000000); + global_free_idx_list_.push_back(global_id_storage_.size()); + global_id_storage_.push_back(std::string()); + global_refcount_storage_.push_back(0); + } + + int idx = global_free_idx_list_.back(); + global_free_idx_list_.pop_back(); + global_id_storage_.at(idx) = str; + global_id_index_[global_id_storage_.at(idx)] = idx; + global_refcount_storage_.at(idx)++; + return idx; + } + + static inline void put_reference(int idx) + { + if (--global_refcount_storage_.at(idx) != 0) + return; + + global_id_index_.erase(global_id_storage_.at(idx)); + global_id_storage_.at(idx).clear(); + global_free_idx_list_.push_back(idx); + } + + // The actual IdString objects just is a single int + + int index_; + + IdString() : index_(get_reference("")) { } + IdString(const char *str) : index_(get_reference(str)) { } + IdString(const IdString &str) : index_(get_reference(str.index_)) { } + IdString(const std::string &str) : index_(get_reference(str)) { } + ~IdString() { put_reference(index_); } + + void operator=(const IdString &rhs) { + put_reference(index_); + index_ = get_reference(rhs.index_); + } + + void operator=(const char *rhs) { + IdString id(rhs); + *this = id; + } + + void operator=(const std::string &rhs) { + IdString id(rhs); + *this = id; + } + + const std::string& str() const { + return global_id_storage_.at(index_); + } + + bool operator<(const IdString &rhs) const { + return index_ < rhs.index_; + } // The methods below are just convinience functions for better compatibility // with std::string. Except clear() they all just deligate to std::string. operator const char*() const { return str().c_str(); } - bool operator<(const IdString &rhs) const { return str() < rhs.str(); } bool operator==(const IdString &rhs) const { return str() == rhs.str(); } bool operator!=(const IdString &rhs) const { return str() != rhs.str(); } + bool operator==(const std::string &rhs) const { return str() == rhs; } + bool operator!=(const std::string &rhs) const { return str() != rhs; } + bool operator==(const char *rhs) const { return str() == rhs; } bool operator!=(const char *rhs) const { return str() != rhs; }