Implemented new reference counting RTLIL::IdString

This commit is contained in:
Clifford Wolf 2014-08-02 15:11:35 +02:00
parent 97ad0623df
commit 60f3dc9923
2 changed files with 90 additions and 15 deletions

View File

@ -26,6 +26,11 @@
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
std::vector<int> RTLIL::IdString::global_refcount_storage_;
std::vector<std::string> RTLIL::IdString::global_id_storage_;
std::map<const std::string, int> RTLIL::IdString::global_id_index_;
std::vector<int> RTLIL::IdString::global_free_idx_list_;
RTLIL::Const::Const() RTLIL::Const::Const()
{ {
flags = RTLIL::CONST_FLAG_NONE; flags = RTLIL::CONST_FLAG_NONE;
@ -1998,8 +2003,7 @@ void RTLIL::SigSpec::hash() const
for (auto &v : c.data.bits) for (auto &v : c.data.bits)
DJB2(that->hash_, v); DJB2(that->hash_, v);
} else { } else {
for (auto &v : c.wire->name.str()) DJB2(that->hash_, c.wire->name.index_);
DJB2(that->hash_, v);
DJB2(that->hash_, c.offset); DJB2(that->hash_, c.offset);
DJB2(that->hash_, c.width); DJB2(that->hash_, c.width);
} }

View File

@ -74,30 +74,101 @@ namespace RTLIL
struct IdString struct IdString
{ {
private: // the global string cache
std::string str_;
public: static std::vector<int> global_refcount_storage_;
IdString() : str_() { } static std::vector<std::string> global_id_storage_;
IdString(const char *str) : str_(str) { } static std::map<const std::string, int> global_id_index_;
IdString(const IdString &str) : str_(str.str_) { } static std::vector<int> global_free_idx_list_;
IdString(const std::string &str) : str_(str) { }
void operator=(const char *rhs) { str_ = rhs; } static inline int get_reference(int idx)
void operator=(const IdString &rhs) { str_ = rhs.str_; } {
void operator=(const std::string &rhs) { str_ = rhs; } global_refcount_storage_.at(idx)++;
return idx;
}
const std::string& str() const { return str_; } 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 // The methods below are just convinience functions for better compatibility
// with std::string. Except clear() they all just deligate to std::string. // with std::string. Except clear() they all just deligate to std::string.
operator const char*() const { return str().c_str(); } 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 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; }
bool operator!=(const char *rhs) const { return str() != rhs; } bool operator!=(const char *rhs) const { return str() != rhs; }