From e590ffc84dac1cb1ea833c5e7a71e958b63f7352 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 15:44:10 +0200 Subject: Improvements in new RTLIL::IdString implementation --- kernel/log.cc | 10 ++++---- kernel/log.h | 2 -- kernel/rtlil.cc | 4 +-- kernel/rtlil.h | 78 +++++++++++++++++++++++++++++++++++++++------------------ kernel/yosys.h | 4 +++ 5 files changed, 65 insertions(+), 33 deletions(-) (limited to 'kernel') diff --git a/kernel/log.cc b/kernel/log.cc index 1595596a..f67d64c2 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -205,11 +205,11 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) const char *log_id(RTLIL::IdString str) { - if (str.size() > 1 && str[0] == '\\' && str[1] != '$') - string_buf.push_back(str.substr(1)); - else - string_buf.push_back(str.str()); - return string_buf.back().c_str(); + const char *p = str; + log_assert(RTLIL::IdString::global_refcount_storage_[str.index_] > 1); + if (p[0] == '\\' && p[1] != '$' && p[1] != 0) + return p+1; + return p; } void log_cell(RTLIL::Cell *cell, std::string indent) diff --git a/kernel/log.h b/kernel/log.h index 118ff69b..037a62a3 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -22,8 +22,6 @@ #ifndef LOG_H #define LOG_H -#include -#include #include #include #include diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 80f63ce7..9ee8123f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -27,8 +27,8 @@ 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_id_storage_; +std::map RTLIL::IdString::global_id_index_; std::vector RTLIL::IdString::global_free_idx_list_; RTLIL::Const::Const() diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d95cf11f..9430da31 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -76,9 +76,18 @@ namespace RTLIL { // the global string cache + struct char_ptr_cmp { + bool operator()(const char *a, const char *b) { + for (int i = 0; a[i] || b[i]; i++) + if (a[i] != b[i]) + return a[i] < b[i]; + return false; + } + }; + static std::vector global_refcount_storage_; - static std::vector global_id_storage_; - static std::map global_id_index_; + static std::vector global_id_storage_; + static std::map global_id_index_; static std::vector global_free_idx_list_; static inline int get_reference(int idx) @@ -87,14 +96,14 @@ namespace RTLIL return idx; } - static inline int get_reference(const std::string &str) + static inline int get_reference(const char *p) { - if (!str.empty()) { - log_assert(str.size() >= 2); - log_assert(str[0] == '$' || str[0] == '\\'); + if (p[0]) { + log_assert(p[1] != 0); + log_assert(p[0] == '$' || p[0] == '\\'); } - auto it = global_id_index_.find(str); + auto it = global_id_index_.find((char*)p); if (it != global_id_index_.end()) { global_refcount_storage_.at(it->second)++; return it->second; @@ -103,13 +112,13 @@ namespace RTLIL 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_id_storage_.push_back(nullptr); 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_storage_.at(idx) = strdup(p); global_id_index_[global_id_storage_.at(idx)] = idx; global_refcount_storage_.at(idx)++; return idx; @@ -121,7 +130,7 @@ namespace RTLIL return; global_id_index_.erase(global_id_storage_.at(idx)); - global_id_storage_.at(idx).clear(); + free(global_id_storage_.at(idx)); global_free_idx_list_.push_back(idx); } @@ -132,7 +141,7 @@ namespace RTLIL 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(const std::string &str) : index_(get_reference(str.c_str())) { } ~IdString() { put_reference(index_); } void operator=(const IdString &rhs) { @@ -150,21 +159,26 @@ namespace RTLIL *this = id; } - const std::string& str() const { + const char*c_str() const { + return global_id_storage_.at(index_); + } + + operator const char*() const { return global_id_storage_.at(index_); } + std::string str() const { + return std::string(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. + bool operator==(const IdString &rhs) const { return index_ == rhs.index_; } + bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; } - 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(); } + // The methods below are just convinience functions for better compatibility with std::string. bool operator==(const std::string &rhs) const { return str() == rhs; } bool operator!=(const std::string &rhs) const { return str() != rhs; } @@ -172,12 +186,28 @@ namespace RTLIL bool operator==(const char *rhs) const { return str() == rhs; } bool operator!=(const char *rhs) const { return str() != rhs; } - char at(size_t i) const { return str().at(i); } - const char*c_str() const { return str().c_str(); } - std::string substr(size_t pos = 0, size_t len = std::string::npos) const { return str().substr(pos, len); } - size_t size() const { return str().size(); } - bool empty() const { return str().empty(); } - void clear() { *this = IdString(); } + char at(size_t i) const { + return c_str()[i]; + } + + std::string substr(size_t pos = 0, size_t len = std::string::npos) const { + if (len == std::string::npos) + return std::string(c_str() + pos); + else + return std::string(c_str() + pos, len); + } + + size_t size() const { + return str().size(); + } + + bool empty() const { + return c_str()[0] == 0; + } + + void clear() { + *this = IdString(); + } }; static inline std::string escape_id(std::string str) { diff --git a/kernel/yosys.h b/kernel/yosys.h index f9c1848e..34777c9a 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -43,7 +43,11 @@ #include #include #include + #include +#include +#include +#include #define PRIVATE_NAMESPACE_BEGIN namespace { #define PRIVATE_NAMESPACE_END } -- cgit v1.2.3