Improvements in new RTLIL::IdString implementation
authorClifford Wolf <clifford@clifford.at>
Sat, 2 Aug 2014 13:44:10 +0000 (15:44 +0200)
committerClifford Wolf <clifford@clifford.at>
Sat, 2 Aug 2014 13:44:10 +0000 (15:44 +0200)
kernel/log.cc
kernel/log.h
kernel/rtlil.cc
kernel/rtlil.h
kernel/yosys.h

index 1595596ac9df7078181617f697be15c9591d27de..f67d64c25cb9fdf4651849d71c902ef0e77b7228 100644 (file)
@@ -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)
index 118ff69bab804b8fa0c6adfcb4d3facba7c17871..037a62a3bb0c07c40888163384043b99dcb2c833 100644 (file)
@@ -22,8 +22,6 @@
 #ifndef LOG_H
 #define LOG_H
 
-#include <stdio.h>
-#include <string.h>
 #include <time.h>
 #include <sys/time.h>
 #include <sys/resource.h>
index 80f63ce74e5d1323cc7d42412af934fd5642a7c7..9ee8123ffbb443c3a4dda7259b5734bf2d5658d9 100644 (file)
@@ -27,8 +27,8 @@
 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<char*> RTLIL::IdString::global_id_storage_;
+std::map<char*, int, RTLIL::IdString::char_ptr_cmp> RTLIL::IdString::global_id_index_;
 std::vector<int> RTLIL::IdString::global_free_idx_list_;
 
 RTLIL::Const::Const()
index d95cf11f2bdb0d81badb64ac96ccff381f3c598d..9430da311840f7d247ef8bb0c8098c0c11930b24 100644 (file)
@@ -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<int> global_refcount_storage_;
-               static std::vector<std::string> global_id_storage_;
-               static std::map<const std::string, int> global_id_index_;
+               static std::vector<char*> global_id_storage_;
+               static std::map<char*, int, char_ptr_cmp> global_id_index_;
                static std::vector<int> 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) {
index f9c1848ee83b6bb0e66809a6cc5160d3903c8cc4..34777c9a490eff7dbb1e138f15802f66555d33ce 100644 (file)
 #include <string>
 #include <algorithm>
 #include <initializer_list>
+
 #include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
 
 #define PRIVATE_NAMESPACE_BEGIN  namespace {
 #define PRIVATE_NAMESPACE_END    }