Improvements in new RTLIL::IdString implementation

This commit is contained in:
Clifford Wolf 2014-08-02 15:44:10 +02:00
parent 8fd1c269ac
commit e590ffc84d
5 changed files with 65 additions and 33 deletions

View File

@ -205,11 +205,11 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint)
const char *log_id(RTLIL::IdString str) const char *log_id(RTLIL::IdString str)
{ {
if (str.size() > 1 && str[0] == '\\' && str[1] != '$') const char *p = str;
string_buf.push_back(str.substr(1)); log_assert(RTLIL::IdString::global_refcount_storage_[str.index_] > 1);
else if (p[0] == '\\' && p[1] != '$' && p[1] != 0)
string_buf.push_back(str.str()); return p+1;
return string_buf.back().c_str(); return p;
} }
void log_cell(RTLIL::Cell *cell, std::string indent) void log_cell(RTLIL::Cell *cell, std::string indent)

View File

@ -22,8 +22,6 @@
#ifndef LOG_H #ifndef LOG_H
#define LOG_H #define LOG_H
#include <stdio.h>
#include <string.h>
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>

View File

@ -27,8 +27,8 @@
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
std::vector<int> RTLIL::IdString::global_refcount_storage_; std::vector<int> RTLIL::IdString::global_refcount_storage_;
std::vector<std::string> RTLIL::IdString::global_id_storage_; std::vector<char*> RTLIL::IdString::global_id_storage_;
std::map<const std::string, int> RTLIL::IdString::global_id_index_; std::map<char*, int, RTLIL::IdString::char_ptr_cmp> RTLIL::IdString::global_id_index_;
std::vector<int> RTLIL::IdString::global_free_idx_list_; std::vector<int> RTLIL::IdString::global_free_idx_list_;
RTLIL::Const::Const() RTLIL::Const::Const()

View File

@ -76,9 +76,18 @@ namespace RTLIL
{ {
// the global string cache // 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<int> global_refcount_storage_; static std::vector<int> global_refcount_storage_;
static std::vector<std::string> global_id_storage_; static std::vector<char*> global_id_storage_;
static std::map<const std::string, int> global_id_index_; static std::map<char*, int, char_ptr_cmp> global_id_index_;
static std::vector<int> global_free_idx_list_; static std::vector<int> global_free_idx_list_;
static inline int get_reference(int idx) static inline int get_reference(int idx)
@ -87,14 +96,14 @@ namespace RTLIL
return idx; return idx;
} }
static inline int get_reference(const std::string &str) static inline int get_reference(const char *p)
{ {
if (!str.empty()) { if (p[0]) {
log_assert(str.size() >= 2); log_assert(p[1] != 0);
log_assert(str[0] == '$' || str[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()) { if (it != global_id_index_.end()) {
global_refcount_storage_.at(it->second)++; global_refcount_storage_.at(it->second)++;
return it->second; return it->second;
@ -103,13 +112,13 @@ namespace RTLIL
if (global_free_idx_list_.empty()) { if (global_free_idx_list_.empty()) {
log_assert(global_id_storage_.size() < 0x40000000); log_assert(global_id_storage_.size() < 0x40000000);
global_free_idx_list_.push_back(global_id_storage_.size()); 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); global_refcount_storage_.push_back(0);
} }
int idx = global_free_idx_list_.back(); int idx = global_free_idx_list_.back();
global_free_idx_list_.pop_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_id_index_[global_id_storage_.at(idx)] = idx;
global_refcount_storage_.at(idx)++; global_refcount_storage_.at(idx)++;
return idx; return idx;
@ -121,7 +130,7 @@ namespace RTLIL
return; return;
global_id_index_.erase(global_id_storage_.at(idx)); 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); global_free_idx_list_.push_back(idx);
} }
@ -132,7 +141,7 @@ namespace RTLIL
IdString() : index_(get_reference("")) { } IdString() : index_(get_reference("")) { }
IdString(const char *str) : index_(get_reference(str)) { } IdString(const char *str) : index_(get_reference(str)) { }
IdString(const IdString &str) : index_(get_reference(str.index_)) { } 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_); } ~IdString() { put_reference(index_); }
void operator=(const IdString &rhs) { void operator=(const IdString &rhs) {
@ -150,21 +159,26 @@ namespace RTLIL
*this = id; *this = id;
} }
const std::string& str() const { const char*c_str() const {
return global_id_storage_.at(index_); 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 { bool operator<(const IdString &rhs) const {
return index_ < rhs.index_; return index_ < rhs.index_;
} }
// The methods below are just convinience functions for better compatibility bool operator==(const IdString &rhs) const { return index_ == rhs.index_; }
// with std::string. Except clear() they all just deligate to std::string. bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; }
operator const char*() const { return str().c_str(); } // The methods below are just convinience functions for better compatibility with std::string.
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 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; }
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); } char at(size_t i) const {
const char*c_str() const { return str().c_str(); } return c_str()[i];
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(); } std::string substr(size_t pos = 0, size_t len = std::string::npos) const {
void clear() { *this = IdString(); } 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) { static inline std::string escape_id(std::string str) {

View File

@ -43,7 +43,11 @@
#include <string> #include <string>
#include <algorithm> #include <algorithm>
#include <initializer_list> #include <initializer_list>
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define PRIVATE_NAMESPACE_BEGIN namespace { #define PRIVATE_NAMESPACE_BEGIN namespace {
#define PRIVATE_NAMESPACE_END } #define PRIVATE_NAMESPACE_END }