From d70924ace2ff4f5bee5f8a32991cc7d33b3853ef Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 20 Aug 2025 03:47:03 +0000 Subject: [PATCH] Store IdString lengths and use them --- kernel/io.cc | 2 +- kernel/rtlil.cc | 6 ++--- kernel/rtlil.h | 58 +++++++++++++++++++++++++++++-------------------- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/kernel/io.cc b/kernel/io.cc index 9e9eb9fb0..028ac388d 100644 --- a/kernel/io.cc +++ b/kernel/io.cc @@ -587,7 +587,7 @@ void format_emit_idstring(std::string &result, std::string_view spec, int *dynam { if (spec == "%s") { // Format checking will have guaranteed num_dynamic_ints == 0. - result += arg.c_str(); + result += arg.str_view(); return; } format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg.c_str()); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index aa4743a87..4a7bf79b2 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -35,7 +35,7 @@ YOSYS_NAMESPACE_BEGIN bool RTLIL::IdString::destruct_guard_ok = false; RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; -std::vector RTLIL::IdString::global_id_storage_; +std::vector RTLIL::IdString::global_id_storage_; std::unordered_map RTLIL::IdString::global_id_index_; #ifndef YOSYS_NO_IDS_REFCNT std::vector RTLIL::IdString::global_refcount_storage_; @@ -57,14 +57,14 @@ static void populate(std::string_view name) name = name.substr(1); } RTLIL::IdString::global_id_index_.insert({name, GetSize(RTLIL::IdString::global_id_storage_)}); - RTLIL::IdString::global_id_storage_.push_back(const_cast(name.data())); + RTLIL::IdString::global_id_storage_.push_back({const_cast(name.data()), GetSize(name)}); } void RTLIL::IdString::prepopulate() { int size = static_cast(RTLIL::StaticId::STATIC_ID_END); global_id_storage_.reserve(size); - RTLIL::IdString::global_id_storage_.push_back(const_cast("")); + RTLIL::IdString::global_id_storage_.push_back({const_cast(""), 0}); global_id_index_.reserve(size); global_refcount_storage_.resize(size, 1); #define X(N) populate("\\" #N); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index b65b9b6eb..d570e39a3 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -137,6 +137,11 @@ namespace RTLIL struct RTLIL::IdString { + struct Storage { + char *buf; + int size; + }; + #undef YOSYS_XTRACE_GET_PUT #undef YOSYS_SORT_ID_FREE_LIST #undef YOSYS_USE_STICKY_IDS @@ -150,7 +155,7 @@ struct RTLIL::IdString ~destruct_guard_t() { destruct_guard_ok = false; } } destruct_guard; - static std::vector global_id_storage_; + static std::vector global_id_storage_; static std::unordered_map global_id_index_; #ifndef YOSYS_NO_IDS_REFCNT // For prepopulated IdStrings, the refcount is meaningless since they @@ -173,10 +178,10 @@ struct RTLIL::IdString #ifdef YOSYS_XTRACE_GET_PUT 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); 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 } @@ -203,7 +208,7 @@ struct RTLIL::IdString #endif #ifdef YOSYS_XTRACE_GET_PUT if (yosys_xtrace && idx >= static_cast(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 return idx; } @@ -224,7 +229,7 @@ struct RTLIL::IdString #endif #ifdef YOSYS_XTRACE_GET_PUT 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 return it->second; } @@ -243,32 +248,31 @@ struct RTLIL::IdString 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(nullptr); + global_id_storage_.push_back({nullptr, 0}); global_refcount_storage_.push_back(0); } int idx = global_free_idx_list_.back(); global_free_idx_list_.pop_back(); - char* buf = static_cast(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)++; #else int idx = global_id_storage_.size(); - global_id_storage_.push_back(strdup(p)); - global_id_index_[global_id_storage_.back()] = idx; + global_id_storage_.push_back({nullptr, 0}); #endif + char* buf = static_cast(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) { - 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); } #ifdef YOSYS_XTRACE_GET_PUT 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 #ifdef YOSYS_USE_STICKY_IDS @@ -293,7 +297,7 @@ struct RTLIL::IdString #ifdef YOSYS_XTRACE_GET_PUT 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 @@ -307,14 +311,14 @@ struct RTLIL::IdString static inline void free_reference(int idx) { 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_assert(idx >= static_cast(StaticId::STATIC_ID_END)); - global_id_index_.erase(global_id_storage_.at(idx)); - free(global_id_storage_.at(idx)); - global_id_storage_.at(idx) = nullptr; + global_id_index_.erase(global_id_storage_.at(idx).buf); + free(global_id_storage_.at(idx).buf); + global_id_storage_.at(idx) = {nullptr, 0}; global_free_idx_list_.push_back(idx); } #else @@ -358,11 +362,17 @@ struct RTLIL::IdString constexpr inline const IdString &id_string() const { return *this; } inline const char *c_str() const { - return global_id_storage_.at(index_); + return global_id_storage_.at(index_).buf; } 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 { @@ -394,7 +404,7 @@ struct RTLIL::IdString } 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); else return std::string(c_str() + pos, len); @@ -420,7 +430,7 @@ struct RTLIL::IdString } size_t size() const { - return strlen(c_str()); + return global_id_storage_.at(index_).size; } bool empty() const {