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:
Marek Olšák
2025-08-01 20:56:22 -04:00
committed by Marge Bot
parent 96ffc24e4e
commit 3c4a64e807
2 changed files with 84 additions and 7 deletions
+75 -7
View File
@@ -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;
}
+9
View File
@@ -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