nir: eliminate most ralloc/malloc for nir_variable names
Store small names in a fixed-sized string in nir_variable. GLSL IR does the same thing. When compiling my shader-db with the gallium noop driver, it improves GLSL compile times by 0.7% (much lower than anticipated). For Unigine Heaven shaders: - it eliminates 95.6% ralloc calls for nir_variable names - the total number of ralloc calls is reduced by 11% It also adds only 16B to nir_variable, while just the ralloc header for the name would occupy 40B. Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36538>
This commit is contained in:
+75
-7
@@ -32,6 +32,7 @@
|
||||
#include "util/half_float.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_printf.h"
|
||||
#include "util/u_qsort.h"
|
||||
#include "nir_builder.h"
|
||||
#include "nir_control_flow_private.h"
|
||||
@@ -270,21 +271,42 @@ nir_shader_add_variable(nir_shader *shader, nir_variable *var)
|
||||
void
|
||||
nir_variable_set_name(nir_variable *var, const char *name)
|
||||
{
|
||||
if (var->name)
|
||||
if (var->name && var->name != var->_name_storage)
|
||||
ralloc_free(var->name);
|
||||
|
||||
var->name = ralloc_strdup(var, name);
|
||||
if (!name) {
|
||||
var->name = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Use _name_storage if the name fits in it. */
|
||||
if (strlen(name) < ARRAY_SIZE(var->_name_storage)) {
|
||||
var->name = var->_name_storage;
|
||||
strcpy(var->name, name);
|
||||
} else {
|
||||
var->name = ralloc_strdup(var, name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nir_variable_set_namef(nir_variable *var, const char *fmt, ...)
|
||||
{
|
||||
if (var->name)
|
||||
if (var->name && var->name != var->_name_storage)
|
||||
ralloc_free(var->name);
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
var->name = ralloc_vasprintf(var, fmt, args);
|
||||
size_t name_size = u_printf_length(fmt, args) + 1;
|
||||
|
||||
/* Use _name_storage if the name fits in it. */
|
||||
if (name_size <= ARRAY_SIZE(var->_name_storage))
|
||||
var->name = var->_name_storage;
|
||||
else
|
||||
var->name = ralloc_size(var, name_size);
|
||||
|
||||
if (var->name)
|
||||
vsnprintf(var->name, name_size, fmt, args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@@ -293,15 +315,61 @@ nir_variable_append_namef(nir_variable *var, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
ralloc_vasprintf_append(&var->name, fmt, args);
|
||||
size_t old_len = var->name ? strlen(var->name) : 0;
|
||||
size_t append_size = u_printf_length(fmt, args) + 1;
|
||||
size_t name_size = old_len + append_size;
|
||||
|
||||
if (append_size == 1) {
|
||||
/* No change. */
|
||||
va_end(args);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Use _name_storage if the name fits in it. */
|
||||
if (name_size <= ARRAY_SIZE(var->_name_storage)) {
|
||||
if (!var->name) {
|
||||
var->name = var->_name_storage;
|
||||
} else if (var->name != var->_name_storage) {
|
||||
/* Move the name to _name_storage. */
|
||||
memcpy(var->_name_storage, var->name, old_len + 1);
|
||||
ralloc_free(var->name);
|
||||
var->name = var->_name_storage;
|
||||
}
|
||||
} else {
|
||||
/* ralloc the appended name. */
|
||||
if (var->name == var->_name_storage) {
|
||||
/* Move the name from _name_storage to ralloc'd. */
|
||||
var->name = ralloc_size(var, name_size);
|
||||
if (var->name)
|
||||
memcpy(var->name, var->_name_storage, old_len + 1);
|
||||
} else {
|
||||
var->name = reralloc_size(var, var->name, name_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Append the name. */
|
||||
if (var->name)
|
||||
vsnprintf(var->name + old_len, append_size, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
nir_variable_steal_name(nir_variable *dst, nir_variable *src)
|
||||
{
|
||||
ralloc_steal(dst, src->name);
|
||||
dst->name = src->name;
|
||||
if (!src->name) {
|
||||
dst->name = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Use _name_storage if the name fits in it. */
|
||||
if (src->name == src->_name_storage) {
|
||||
dst->name = dst->_name_storage;
|
||||
strcpy(dst->name, src->name);
|
||||
} else {
|
||||
ralloc_steal(dst, src->name);
|
||||
dst->name = src->name;
|
||||
}
|
||||
|
||||
src->name = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -865,6 +865,15 @@ typedef struct nir_variable {
|
||||
* variables with a struct or array of array of struct type.
|
||||
*/
|
||||
nir_variable_data *members;
|
||||
|
||||
/**
|
||||
* This is the backing storage for "name" if the name is short enough
|
||||
* to fit in it, so that we don't have to ralloc the name.
|
||||
*
|
||||
* It eliminates 95.6% ralloc calls for variable names when compiling
|
||||
* my GLSL shader-db.
|
||||
*/
|
||||
char _name_storage[16];
|
||||
} nir_variable;
|
||||
|
||||
static inline bool
|
||||
|
||||
Reference in New Issue
Block a user