mirror of
https://github.com/verilator/verilator.git
synced 2026-09-03 03:33:58 +02:00
Optimize string formatting runtime functions
Add an overload that takes `const char*` format string. This avoids having to construct/destruct a temporary `std::string` at the call site when calling these functions with a string literal, which is fairly common. This is worth 25% code size on some assertion heavy design. Also use `std::string::clear()` instead of assigning an empty string which is more efficient.
This commit is contained in:
+100
-13
@@ -998,7 +998,7 @@ void _vl_vsformat(std::string& output, const std::string& format, int argc,
|
||||
bool widthSet = false;
|
||||
bool left = false;
|
||||
size_t width = 0;
|
||||
output = "";
|
||||
output.clear();
|
||||
output.reserve(format.length());
|
||||
for (std::string::const_iterator pos = format.cbegin(); pos != format.cend(); ++pos) {
|
||||
if (!inPct && pos[0] == '%') {
|
||||
@@ -1833,9 +1833,11 @@ void VL_FCLOSE_I(IData fdi) VL_MT_SAFE {
|
||||
Verilated::threadContextp()->impp()->fdClose(fdi);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// String formatting functions taking const std::string& as format string
|
||||
|
||||
void VL_SFORMAT_NX(int obits, CData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, argc, ap);
|
||||
@@ -1846,7 +1848,6 @@ void VL_SFORMAT_NX(int obits, CData& destr, const std::string& format, int argc,
|
||||
|
||||
void VL_SFORMAT_NX(int obits, SData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, argc, ap);
|
||||
@@ -1857,7 +1858,6 @@ void VL_SFORMAT_NX(int obits, SData& destr, const std::string& format, int argc,
|
||||
|
||||
void VL_SFORMAT_NX(int obits, IData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, argc, ap);
|
||||
@@ -1868,7 +1868,6 @@ void VL_SFORMAT_NX(int obits, IData& destr, const std::string& format, int argc,
|
||||
|
||||
void VL_SFORMAT_NX(int obits, QData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, argc, ap);
|
||||
@@ -1879,7 +1878,6 @@ void VL_SFORMAT_NX(int obits, QData& destr, const std::string& format, int argc,
|
||||
|
||||
void VL_SFORMAT_NX(int obits, EData* destp, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, argc, ap);
|
||||
@@ -1898,19 +1896,17 @@ void VL_SFORMAT_NX(std::string& output, const std::string& format, int argc, ...
|
||||
}
|
||||
|
||||
std::string VL_SFORMATF_N_NX(const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
std::string output;
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, argc, ap);
|
||||
_vl_vsformat(output, format, argc, ap);
|
||||
va_end(ap);
|
||||
|
||||
return t_output;
|
||||
return output;
|
||||
}
|
||||
|
||||
void VL_WRITEF_NX(const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, argc, ap);
|
||||
@@ -1922,8 +1918,6 @@ void VL_WRITEF_NX(const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
void VL_FWRITEF_NX(IData fpi, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
// While threadsafe, each thread can only access different file handles
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, argc, ap);
|
||||
@@ -1932,6 +1926,99 @@ void VL_FWRITEF_NX(IData fpi, const std::string& format, int argc, ...) VL_MT_SA
|
||||
Verilated::threadContextp()->impp()->fdWrite(fpi, t_output);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// String formatting functions taking const char* as format string
|
||||
|
||||
void VL_SFORMAT_NX(int obits, CData& destr, const char* formatp, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, formatp, argc, ap);
|
||||
va_end(ap);
|
||||
|
||||
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_SFORMAT_NX(int obits, SData& destr, const char* formatp, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, formatp, argc, ap);
|
||||
va_end(ap);
|
||||
|
||||
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_SFORMAT_NX(int obits, IData& destr, const char* formatp, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, formatp, argc, ap);
|
||||
va_end(ap);
|
||||
|
||||
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_SFORMAT_NX(int obits, QData& destr, const char* formatp, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, formatp, argc, ap);
|
||||
va_end(ap);
|
||||
|
||||
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_SFORMAT_NX(int obits, EData* destp, const char* formatp, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, formatp, argc, ap);
|
||||
va_end(ap);
|
||||
|
||||
_vl_string_to_vint(obits, destp, t_output.length(), t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_SFORMAT_NX(std::string& output, const char* formatp, int argc, ...) VL_MT_SAFE {
|
||||
std::string temp_output;
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(temp_output, formatp, argc, ap);
|
||||
va_end(ap);
|
||||
output = temp_output;
|
||||
}
|
||||
|
||||
std::string VL_SFORMATF_N_NX(const char* formatp, int argc, ...) VL_MT_SAFE {
|
||||
std::string output;
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(output, formatp, argc, ap);
|
||||
va_end(ap);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void VL_WRITEF_NX(const char* formatp, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, formatp, argc, ap);
|
||||
va_end(ap);
|
||||
|
||||
VL_PRINTF_MT("%s", t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_FWRITEF_NX(IData fpi, const char* formatp, int argc, ...) VL_MT_SAFE {
|
||||
// While threadsafe, each thread can only access different file handles
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
va_list ap;
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, formatp, argc, ap);
|
||||
va_end(ap);
|
||||
|
||||
Verilated::threadContextp()->impp()->fdWrite(fpi, t_output);
|
||||
}
|
||||
|
||||
IData VL_FSCANF_INX(IData fpi, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
// While threadsafe, each thread can only access different file handles
|
||||
FILE* const fp = VL_CVT_I_FP(fpi);
|
||||
|
||||
Reference in New Issue
Block a user