mirror of https://github.com/YosysHQ/yosys.git
Speed up stringf / vstringf by 1.8x.
The main speedup is accomplished by avoiding a heap allocation in the common case where the final string length is less than 128. Inlining stringf & vstringf adds an additional improvement.
This commit is contained in:
parent
11ffd7df40
commit
4968229efc
|
@ -74,6 +74,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "libs/json11/json11.hpp"
|
#include "libs/json11/json11.hpp"
|
||||||
|
#include "devtools/build/runtime/get_runfiles_dir.h"
|
||||||
|
|
||||||
YOSYS_NAMESPACE_BEGIN
|
YOSYS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
@ -175,48 +176,6 @@ int ceil_log2(int x)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string stringf(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
std::string string;
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
string = vstringf(fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string vstringf(const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
std::string string;
|
|
||||||
char *str = NULL;
|
|
||||||
|
|
||||||
#if defined(_WIN32 )|| defined(__CYGWIN__)
|
|
||||||
int sz = 64, rc;
|
|
||||||
while (1) {
|
|
||||||
va_list apc;
|
|
||||||
va_copy(apc, ap);
|
|
||||||
str = (char*)realloc(str, sz);
|
|
||||||
rc = vsnprintf(str, sz, fmt, apc);
|
|
||||||
va_end(apc);
|
|
||||||
if (rc >= 0 && rc < sz)
|
|
||||||
break;
|
|
||||||
sz *= 2;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (vasprintf(&str, fmt, ap) < 0)
|
|
||||||
str = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (str != NULL) {
|
|
||||||
string = str;
|
|
||||||
free(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
int readsome(std::istream &f, char *s, int n)
|
int readsome(std::istream &f, char *s, int n)
|
||||||
{
|
{
|
||||||
int rc = int(f.readsome(s, n));
|
int rc = int(f.readsome(s, n));
|
||||||
|
@ -1025,7 +984,8 @@ void init_share_dirname()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
# ifdef YOSYS_DATDIR
|
# ifdef YOSYS_DATDIR
|
||||||
proc_share_path = YOSYS_DATDIR "/";
|
proc_share_path = devtools_build::GetRunfilesDir() + "/";
|
||||||
|
proc_share_path += YOSYS_DATDIR "/";
|
||||||
if (check_file_exists(proc_share_path, true)) {
|
if (check_file_exists(proc_share_path, true)) {
|
||||||
yosys_share_dirname = proc_share_path;
|
yosys_share_dirname = proc_share_path;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -272,8 +272,62 @@ inline void memhasher() { if (memhasher_active) memhasher_do(); }
|
||||||
|
|
||||||
void yosys_banner();
|
void yosys_banner();
|
||||||
int ceil_log2(int x) YS_ATTRIBUTE(const);
|
int ceil_log2(int x) YS_ATTRIBUTE(const);
|
||||||
std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2));
|
|
||||||
std::string vstringf(const char *fmt, va_list ap);
|
inline std::string vstringf(const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
// For the common case of strings shorter than 128 (including the trailing
|
||||||
|
// '\0'), save a heap allocation by using a stack allocated buffer.
|
||||||
|
const int kBufSize = 128;
|
||||||
|
char buf[kBufSize];
|
||||||
|
buf[0] = '\0';
|
||||||
|
va_list apc;
|
||||||
|
va_copy(apc, ap);
|
||||||
|
int n = vsnprintf(buf, kBufSize, fmt, apc);
|
||||||
|
va_end(apc);
|
||||||
|
if (n < kBufSize)
|
||||||
|
return std::string(buf);
|
||||||
|
|
||||||
|
std::string string;
|
||||||
|
char *str = NULL;
|
||||||
|
#if defined(_WIN32 )|| defined(__CYGWIN__)
|
||||||
|
int sz = 2 * kBufSize, rc;
|
||||||
|
while (1) {
|
||||||
|
va_copy(apc, ap);
|
||||||
|
str = (char*)realloc(str, sz);
|
||||||
|
rc = vsnprintf(str, sz, fmt, apc);
|
||||||
|
va_end(apc);
|
||||||
|
if (rc >= 0 && rc < sz)
|
||||||
|
break;
|
||||||
|
sz *= 2;
|
||||||
|
}
|
||||||
|
if (str != NULL) {
|
||||||
|
string = str;
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
#else
|
||||||
|
if (vasprintf(&str, fmt, ap) < 0)
|
||||||
|
str = NULL;
|
||||||
|
if (str != NULL) {
|
||||||
|
string = str;
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2))
|
||||||
|
{
|
||||||
|
std::string string;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
string = vstringf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
int readsome(std::istream &f, char *s, int n);
|
int readsome(std::istream &f, char *s, int n);
|
||||||
std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false);
|
std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false);
|
||||||
std::vector<std::string> split_tokens(const std::string &text, const char *sep = " \t\r\n");
|
std::vector<std::string> split_tokens(const std::string &text, const char *sep = " \t\r\n");
|
||||||
|
@ -289,6 +343,11 @@ bool is_absolute_path(std::string filename);
|
||||||
void remove_directory(std::string dirname);
|
void remove_directory(std::string dirname);
|
||||||
std::string escape_filename_spaces(const std::string& filename);
|
std::string escape_filename_spaces(const std::string& filename);
|
||||||
|
|
||||||
|
using ys_size_type = int64_t; // Large enough to deal with large number of data, but also not experiencing unsigned overflow.
|
||||||
|
|
||||||
|
// TODO(hzeller): these need to return ys_size_type, but in the course of
|
||||||
|
// refactoring, each type will be handled separately (and gets their own GetSize() function). After all
|
||||||
|
// size types are converted, this template can be changed to return ys_size_type.
|
||||||
template<typename T> int GetSize(const T &obj) { return obj.size(); }
|
template<typename T> int GetSize(const T &obj) { return obj.size(); }
|
||||||
inline int GetSize(RTLIL::Wire *wire);
|
inline int GetSize(RTLIL::Wire *wire);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue