3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-11-05 05:49:15 +00:00

Store IdString lengths and use them

This commit is contained in:
Robert O'Callahan 2025-08-20 03:47:03 +00:00
parent ae219cb8f9
commit d70924ace2
3 changed files with 38 additions and 28 deletions

View file

@ -587,7 +587,7 @@ void format_emit_idstring(std::string &result, std::string_view spec, int *dynam
{ {
if (spec == "%s") { if (spec == "%s") {
// Format checking will have guaranteed num_dynamic_ints == 0. // Format checking will have guaranteed num_dynamic_ints == 0.
result += arg.c_str(); result += arg.str_view();
return; return;
} }
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg.c_str()); format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg.c_str());

View file

@ -35,7 +35,7 @@ YOSYS_NAMESPACE_BEGIN
bool RTLIL::IdString::destruct_guard_ok = false; bool RTLIL::IdString::destruct_guard_ok = false;
RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard;
std::vector<char*> RTLIL::IdString::global_id_storage_; std::vector<RTLIL::IdString::Storage> RTLIL::IdString::global_id_storage_;
std::unordered_map<std::string_view, int> RTLIL::IdString::global_id_index_; std::unordered_map<std::string_view, int> RTLIL::IdString::global_id_index_;
#ifndef YOSYS_NO_IDS_REFCNT #ifndef YOSYS_NO_IDS_REFCNT
std::vector<uint32_t> RTLIL::IdString::global_refcount_storage_; std::vector<uint32_t> RTLIL::IdString::global_refcount_storage_;
@ -57,14 +57,14 @@ static void populate(std::string_view name)
name = name.substr(1); name = name.substr(1);
} }
RTLIL::IdString::global_id_index_.insert({name, GetSize(RTLIL::IdString::global_id_storage_)}); RTLIL::IdString::global_id_index_.insert({name, GetSize(RTLIL::IdString::global_id_storage_)});
RTLIL::IdString::global_id_storage_.push_back(const_cast<char*>(name.data())); RTLIL::IdString::global_id_storage_.push_back({const_cast<char*>(name.data()), GetSize(name)});
} }
void RTLIL::IdString::prepopulate() void RTLIL::IdString::prepopulate()
{ {
int size = static_cast<short>(RTLIL::StaticId::STATIC_ID_END); int size = static_cast<short>(RTLIL::StaticId::STATIC_ID_END);
global_id_storage_.reserve(size); global_id_storage_.reserve(size);
RTLIL::IdString::global_id_storage_.push_back(const_cast<char*>("")); RTLIL::IdString::global_id_storage_.push_back({const_cast<char*>(""), 0});
global_id_index_.reserve(size); global_id_index_.reserve(size);
global_refcount_storage_.resize(size, 1); global_refcount_storage_.resize(size, 1);
#define X(N) populate("\\" #N); #define X(N) populate("\\" #N);

View file

@ -137,6 +137,11 @@ namespace RTLIL
struct RTLIL::IdString struct RTLIL::IdString
{ {
struct Storage {
char *buf;
int size;
};
#undef YOSYS_XTRACE_GET_PUT #undef YOSYS_XTRACE_GET_PUT
#undef YOSYS_SORT_ID_FREE_LIST #undef YOSYS_SORT_ID_FREE_LIST
#undef YOSYS_USE_STICKY_IDS #undef YOSYS_USE_STICKY_IDS
@ -150,7 +155,7 @@ struct RTLIL::IdString
~destruct_guard_t() { destruct_guard_ok = false; } ~destruct_guard_t() { destruct_guard_ok = false; }
} destruct_guard; } destruct_guard;
static std::vector<char*> global_id_storage_; static std::vector<Storage> global_id_storage_;
static std::unordered_map<std::string_view, int> global_id_index_; static std::unordered_map<std::string_view, int> global_id_index_;
#ifndef YOSYS_NO_IDS_REFCNT #ifndef YOSYS_NO_IDS_REFCNT
// For prepopulated IdStrings, the refcount is meaningless since they // For prepopulated IdStrings, the refcount is meaningless since they
@ -173,10 +178,10 @@ struct RTLIL::IdString
#ifdef YOSYS_XTRACE_GET_PUT #ifdef YOSYS_XTRACE_GET_PUT
for (int idx = 0; idx < GetSize(global_id_storage_); idx++) for (int idx = 0; idx < GetSize(global_id_storage_); idx++)
{ {
if (global_id_storage_.at(idx) == nullptr) if (global_id_storage_.at(idx).buf == nullptr)
log("#X# DB-DUMP index %d: FREE\n", idx); log("#X# DB-DUMP index %d: FREE\n", idx);
else else
log("#X# DB-DUMP index %d: '%s' (ref %u)\n", idx, global_id_storage_.at(idx), global_refcount_storage_.at(idx)); log("#X# DB-DUMP index %d: '%s' (ref %u)\n", idx, global_id_storage_.at(idx).buf, global_refcount_storage_.at(idx));
} }
#endif #endif
} }
@ -203,7 +208,7 @@ struct RTLIL::IdString
#endif #endif
#ifdef YOSYS_XTRACE_GET_PUT #ifdef YOSYS_XTRACE_GET_PUT
if (yosys_xtrace && idx >= static_cast<short>(StaticId::STATIC_ID_END)) if (yosys_xtrace && idx >= static_cast<short>(StaticId::STATIC_ID_END))
log("#X# GET-BY-INDEX '%s' (index %d, refcount %u)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); log("#X# GET-BY-INDEX '%s' (index %d, refcount %u)\n", global_id_storage_.at(idx).buf, idx, global_refcount_storage_.at(idx));
#endif #endif
return idx; return idx;
} }
@ -224,7 +229,7 @@ struct RTLIL::IdString
#endif #endif
#ifdef YOSYS_XTRACE_GET_PUT #ifdef YOSYS_XTRACE_GET_PUT
if (yosys_xtrace) if (yosys_xtrace)
log("#X# GET-BY-NAME '%s' (index %d, refcount %u)\n", global_id_storage_.at(it->second), it->second, global_refcount_storage_.at(it->second)); log("#X# GET-BY-NAME '%s' (index %d, refcount %u)\n", global_id_storage_.at(it->second).buf, it->second, global_refcount_storage_.at(it->second));
#endif #endif
return it->second; return it->second;
} }
@ -243,32 +248,31 @@ struct RTLIL::IdString
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(nullptr); global_id_storage_.push_back({nullptr, 0});
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();
char* buf = static_cast<char*>(malloc(p.size() + 1));
memcpy(buf, p.data(), p.size());
buf[p.size()] = 0;
global_id_storage_.at(idx) = buf;
global_id_index_.insert(it, {std::string_view(buf, p.size()), idx});
global_refcount_storage_.at(idx)++; global_refcount_storage_.at(idx)++;
#else #else
int idx = global_id_storage_.size(); int idx = global_id_storage_.size();
global_id_storage_.push_back(strdup(p)); global_id_storage_.push_back({nullptr, 0});
global_id_index_[global_id_storage_.back()] = idx;
#endif #endif
char* buf = static_cast<char*>(malloc(p.size() + 1));
memcpy(buf, p.data(), p.size());
buf[p.size()] = 0;
global_id_storage_.at(idx) = {buf, GetSize(p)};
global_id_index_.insert(it, {std::string_view(buf, p.size()), idx});
if (yosys_xtrace) { if (yosys_xtrace) {
log("#X# New IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx); log("#X# New IdString '%s' with index %d.\n", global_id_storage_.at(idx).buf, idx);
log_backtrace("-X- ", yosys_xtrace-1); log_backtrace("-X- ", yosys_xtrace-1);
} }
#ifdef YOSYS_XTRACE_GET_PUT #ifdef YOSYS_XTRACE_GET_PUT
if (yosys_xtrace) if (yosys_xtrace)
log("#X# GET-BY-NAME '%s' (index %d, refcount %u)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); log("#X# GET-BY-NAME '%s' (index %d, refcount %u)\n", global_id_storage_.at(idx).buf, idx, global_refcount_storage_.at(idx));
#endif #endif
#ifdef YOSYS_USE_STICKY_IDS #ifdef YOSYS_USE_STICKY_IDS
@ -293,7 +297,7 @@ struct RTLIL::IdString
#ifdef YOSYS_XTRACE_GET_PUT #ifdef YOSYS_XTRACE_GET_PUT
if (yosys_xtrace) { if (yosys_xtrace) {
log("#X# PUT '%s' (index %d, refcount %u)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); log("#X# PUT '%s' (index %d, refcount %u)\n", global_id_storage_.at(idx).buf, idx, global_refcount_storage_.at(idx));
} }
#endif #endif
@ -307,14 +311,14 @@ struct RTLIL::IdString
static inline void free_reference(int idx) static inline void free_reference(int idx)
{ {
if (yosys_xtrace) { if (yosys_xtrace) {
log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx); log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx).buf, idx);
log_backtrace("-X- ", yosys_xtrace-1); log_backtrace("-X- ", yosys_xtrace-1);
} }
log_assert(idx >= static_cast<short>(StaticId::STATIC_ID_END)); log_assert(idx >= static_cast<short>(StaticId::STATIC_ID_END));
global_id_index_.erase(global_id_storage_.at(idx)); global_id_index_.erase(global_id_storage_.at(idx).buf);
free(global_id_storage_.at(idx)); free(global_id_storage_.at(idx).buf);
global_id_storage_.at(idx) = nullptr; global_id_storage_.at(idx) = {nullptr, 0};
global_free_idx_list_.push_back(idx); global_free_idx_list_.push_back(idx);
} }
#else #else
@ -358,11 +362,17 @@ struct RTLIL::IdString
constexpr inline const IdString &id_string() const { return *this; } constexpr inline const IdString &id_string() const { return *this; }
inline const char *c_str() const { inline const char *c_str() const {
return global_id_storage_.at(index_); return global_id_storage_.at(index_).buf;
} }
inline std::string str() const { inline std::string str() const {
return std::string(global_id_storage_.at(index_)); const Storage &storage = global_id_storage_.at(index_);
return std::string(storage.buf, storage.size);
}
inline std::string_view str_view() const {
const Storage &storage = global_id_storage_.at(index_);
return std::string_view(storage.buf, storage.size);
} }
inline bool operator<(const IdString &rhs) const { inline bool operator<(const IdString &rhs) const {
@ -394,7 +404,7 @@ struct RTLIL::IdString
} }
std::string substr(size_t pos = 0, size_t len = std::string::npos) const { std::string substr(size_t pos = 0, size_t len = std::string::npos) const {
if (len == std::string::npos || len >= strlen(c_str() + pos)) if (len == std::string::npos || len + pos >= size())
return std::string(c_str() + pos); return std::string(c_str() + pos);
else else
return std::string(c_str() + pos, len); return std::string(c_str() + pos, len);
@ -420,7 +430,7 @@ struct RTLIL::IdString
} }
size_t size() const { size_t size() const {
return strlen(c_str()); return global_id_storage_.at(index_).size;
} }
bool empty() const { bool empty() const {